Compiling a Cscore Program

A Cscore program can be invoked either as a standalone program or as part of Csound in between sorting the score and performing the score with the orchestra:

cscore [scorefilein] [> scorefileout]

or

csound [-C] [otherflags] [orchname] [scorename]

Before trying to compile your own Cscore program, you will most likely want to obtain a copy of the Csound source code. Either download the latest source distribution for your platform or check out a copy of the csound5 module from Sourceforge CVS. There are several files in the sources that will help you. Within the examples/cscore/ directory are a number of examples of Cscore control programs, including all of the examples contained in this manual. And in the frontends/cscore/ directory are the two files cscoremain.c and cscore.c. cscoremain.c contains a simple main function that performs all of the initialization that a standalone Cscore program needs to do before it calls your control function. This main stub initializes Csound, reads the commandline arguments, opens the input and output score files, and then calls a function cscore(). As described above, it is expected that you will write the cscore() function and provide it in another file. The file frontends/cscore/cscore.c shows the simplest example of a cscore() function that reads in a score of any length and writes it to the output unchanged.

So, to create a standalone program, write a control program as shown in the previous section. Let's assume that you saved this program in a file named mycscore.c. Next, you need to compile and link this program with the Csound library and cscoremain.c in order to create an exectuable by following the set of directions below that apply to your operating system. It will be helpful to already have some familiarity with the C compiler on your computer since the information below cannot be complete for all possible systems.

Linux and Unix

The following commands assume that you have copied your file mycscore.c into the same directory as cscoremain.c, that you have opened a terminal to that same directory, and that you have previously installed a binary distribution of Csound that placed a library libcsound.a or libcsound.so into /usr/local/lib and the header files for the Csound API into /usr/local/include/csound.

To compile and link:

gcc mycscore.c cscoremain.c -o cscore -lcsound -L/usr/local/lib -I/usr/local/include/csound

To run (sending the results to standard output):

./cscore test.sco

It is possible that on some Unix systems, the C compiler will be named cc or something else other than gcc.

Windows

Csound is usually compiled on Windows using the MinGW environment that makes GCC -- the same compiler used on Linux -- available using a Unix-like command shell (MSYS). Since pre-compiled libraries for Csound on Windows are built in this way, you may need to use MinGW as well to link to them. If you have built Csound using another compiler, then you should be able to build Cscore with that compiler as well.

Compiling standalone Cscore programs using MinGW should be similar to the procedure for Linux above with library and header paths changed appropriately for where Csound is installed on the Windows system. (Please feel free to contribute more detailed instructions here as the editor has been unable to test Cscore on a Windows machine).

OS X

The following commands assume that you have copied your file mycscore.c into the same directory as cscoremain.c and that you have opened a terminal to that same directory. In addition, the Apple-supplied developer tools (including the GCC compiler) should be installed on your system and you should have previously installed a binary distribution of Csound that placed the CsoundLib framework into /Library/Frameworks.

Use this command compile and link. (You may get a warning about "multiple definitions of symbol _cscore").

gcc cscore.c cscoremain.c -o cscore -framework CsoundLib -I/Library/Frameworks/CsoundLib.framework/Headers

To run (sending the results to standard output):

./cscore test.sco

MacOS 9

You will need CodeWarrior or some other development environment installed on your computer (MPW may work). Download the source code distribution for OS 9 (it will have a name like Csound5.05_OS9_src.smi.bin).

If using CodeWarrior, find and open the project file "Cscore5.cw8.mcp" in the folder "Csound5.04-OS9-source:macintosh:Csound5Library:". This project file is configured to use the source files cscore.c and cscoremain_MacOS9.c from the csound5 source tree and the Csound5Lib shared library produced by compiling Csound with the "Csound5.cw8.mcp" project file. You should substitute your own Cscore program file for cscore.c and either compile Csound5Lib first or substitute a copy of the library in the project from the binary distribution of Csound for OS 9. The file cscoremain_MacOS9.c contains specialized code for configuring CodeWarrior's SIOUX console library and allows commandline arguments to be entered before the program is run.

Once you have the proper files included in the project window, click the "Make" button and CodeWarrior should produce an application named Cscore. When you run this application, it first displays a window allowing you to type in the arguments to the main function. You only need to type in the filename or pathname to the input score -- do not type in "cscore". The input file should be in the same folder as the application or else you will need to type a full or relative pathname to the file. Output will be displayed in the console window. You can use the Save command from the File menu before quitting if you wish. Alternatively, in the commandline dialog, you can choose to redirect the output to a file by clicking on the File button on the right side of the dialog. (Note that the console window can only display about 32,000 characters, so writing to a file is necessary for long scores).

Making Cscore usable from within Csound

To operate from Csound, first follow the instructions for compiling Csound (see Building Csound) according to the operating system that you are using. Once you have successfully built an unmodified Csound system, then substitute your own cscore() function for the one in the file Top/cscore_internal.c, and rebuild Csound.

The resulting executable is your own special Csound, usable as above. The -C flag will invoke your Cscore program after the input score is sorted into score.srt. The details of what happens when you run Csound with the -C flag are given in the next section.

Csound 5 also provides an additional way to run your own Cscore program from within Csound. Using the API, a host application can set a Cscore callback function, which is a function that Csound will call instead of using the built-in cscore() function. One advantage of this approach is that it is not necessary to recompile the entirety of Csound. Another benefit is that the host application can select at runtime from more than one Cscore function to designate as the callback. The disadvantage is that you need to write a host application.

A simple approach to using a Cscore callback via the API would be to modify the standard Csound main program -- which is a simple Csound host -- contained in the file frontends/csound/csound_main.c. Adding a call to csoundSetCscoreCallback() after the call to csoundCreate() but before the call to csoundCompile() should do the job. Recompiling this file and linking to an existing Csound library will make a commandline version of Csound that works similarly to the one described above. Don't forget to use the -C flag.

Notes about score formats and run-time behavior

As stated previously, the input files to Cscore may be in original or time-warped and pre-sorted form; this modality will be preserved (section by section) in reading, processing, and writing scores. Standalone processing will most often use unwarped sources and create unwarped new files. When running from within Csound, the input score will arrive already warped and sorted, and can thus be sent directly (normally section by section) to the orchestra. One advantage of this method of using Cscore is that all of the syntactical conveniences of the full Csound score language may be used -- macros, arithmetic expressions, carry, ramp, etc. -- since the score will go through the "Carry, Tempo, Sort" phases of score processing before being passed to the user-supplied Cscore program.

When running within Csound, a list of events can be conveyed to a Csound orchestra using cscoreListPlay(). There may be any number of cscoreListPlay() calls in a Cscore program. Each list so conveyed can be either time-warped or not, but each list must be in strict p2-chronological order (either from presorting or using cscoreListSort()). If there is no cscoreListPlay() in a Cscore module run from within Csound, all events written out (via cscorePutEvent(), cscorePutString(), or cscoreListPut()) are written to a new score in the current directory with the name cscore.out. Csound then invokes the score sorter again before sending this new score to the orchestra for performance. The final, sorted, output score is written to a file named cscore.srt.

A standalone Cscore program will normally use the put commands to write into its output file. If a standalone Cscore program calls cscoreListPlay(), the events thus intended for performance will be sent to the output in the same way as if cscoreListPut() had been called instead.

A note list sent by cscoreListPlay() for performance should be temporally distinct from subsequent note lists. No note-end should extend past the next list's start time, since cscoreListPlay() will complete each list before starting the next (i.e. like a Section marker that doesn't reset local time to zero). This is important when using cscoreListGetNext() or cscoreListGetUntil() to fetch and process score segments prior to performance, because these functions may only read part of an unsorted section.