Introduction

The Csound music programming system (Vercoe 2004) is currently the most complete of the text-based audio processing systems in terms of its unit generator collection. Csound hails from a long tradition in Computer Music. Together with cmusic (Moore 1990), it was one of the first modern C-language-based portable sound compilers (Pope 1993), when it was released in 1986. Due to its source-code availability, first from an MIT ftp server and then from the DREAM site at Bath, it was adopted by composers and developers world-wide. These brave peopled developed into a formidable tool for sound synthesis, processing and computer music composition. Its latest version, Csound 5 (ffitch, 2005) has close to one thousand opcodes, ranging from the basic table lookup oscillator to spectral signal demixing unit generators.

Many important changes have been introduced in Csound5, which involved a complete redesign of the software. This resulted not only in a better software, from an engineering perspective, but in the support for many new possible ways of using and interacting with Csound.

An important development has been the availability of a complete C API (the so-called ‘Host API', which was, in fact, already partially present in earlier versions). The API can be used to instantiate and control csound from a calling process, opening a whole new set of possibilities for using Csound.


I. The Csound 5 API

The Csound 5 Host API allows the embedding of the audio processing system under other ‘host' software. Effectively, Csound is now a library, libcsound, that can provide audio services, such as synthesis and processing, for any application. This allows for complete control over the functioning of the audio engine, including transport control, loading of plugins, inter-application sofware bus, multithreading, etc.. A ‘classic' csound command-line program can now be written based only on a few API calls:

#include <csound.h> 
int main(int argc, char **argv) { 
int result;
CSOUND *cs; /* the csound instance */


/* initialise the library */
csoundInitialize(&argc, &argv, 0); 
/* create the csound instance */
cs = csoundCreate(NULL); 
/* compile csound code */
result = csoundCompile(cs, argc, argv); 
/* this is the processing loop */
if(result) while(csoundPerformKsmps(cs)==0); 
/* destroy the instance */
csoundDestroy(cs); 
return 0;
} 

The Csound API can be used in many applications; the development of frontends is the most obvious of these. A good example of its application is found on the csoundapi~ Class, which provides a multi-instantiable interface to Csound 5 for Pure Data. The Csound API is the basis for TclCsound (Lazzarini 2005), a Tcl/Tk extension, discussed in the next section.


II. TclCsound

The classic interface to csound gives you access to the program via a command-line such as

csound -odac hommage.csd 

This is a simple yet effective way of making sound. However, it does not give you neither flexibility nor interacion. With the advent of the API, a lot more is possible. At this stage, TclCsound was introduced to provide a simple scripting interface to Csound. Tcl is a simple language that is easy to extend and provide nice facilities such as easy file access and TCP networking. With its Tk component, it can also handle a graphic and event interface. TclCsound provides three ‘points of contact' with Tcl:

1. a csound-aware tcl interpreter (cstclsh)

2. a csound-aware windowing shell (cswish)

3. a csound commands module for Tcl/Tk (tclcsound dynamic lib)

The Tcl interpreter: cstclsh

With cstclsh, it is possible to have interactive control over a csound performance. The command starts an interactive shell, which holds an instance of Csound. A number of commands can then be used to control it. For instance, the following command can compile csound code and load it in memory ready for performance:

csCompile -odac hommage.csd -m0 

Once this is done, performance can be started in two ways: using csPlay or csPerform . The command

csPlay 

will start the Csound performance in a separate thread and return to the cstclsh prompt. A number of commands can then be used to control Csound. For instance,

csPause 

will pause performance; and

csRewind 

will rewind to the beginning of the note-list. The csNote, csTable and csEvent commands can be used to add Csound score events to the performance, on-the-fly. The csPerform command, as opposed to csPlay , will not launch a separate thread, but will run Csound in the same thread, returning only when the performance is finished. A variety of other commands exist, providing full control of Csound.

Cswish: the windowing shell

With Cswish, Tk widgets and commands can be used to provide graphical interface and event handling. As with cstclsh, running the cswish command also opens an interactive shell. For instance, the following commands can be used to create a transport control panel for Csound:

frame .fr
button .fr.play -text play -command csPlay
button .fr.pause -text pause -command csPause
button .fr.rew -text rew -command csRewind
pack .fr .fr.play .fr.pause .fr.rew 

Similarly, it is possible to bind keys to commands so that the computer keyboard can be used to play Csound.

Particularly useful are the control channel commands that TclCsound provides. For instance, named IO channels can be registered with TclCsound and these can be used with the invalue, outvalue opcodes. In addition, the Csound API also provides a complete software bus for audio, control and string channels. It is possible in TclCsound to access control and string bus channels (the audio bus is not implemented, as Tcl is not able to handle such data). With these TclCsound commands, Tk widgets can be easily connected to synthesis parameters.

A Csound server

In Tcl, setting up TCP network connections is very simple. With a few lines of code a csound server can be built. This can accept connections from the local machine or from remote clients. Not only Tcl/Tk clients can send commands to it, but TCP connections can be made from other sofware, such as, for instance, Pure Data (PD). A Tcl script that can be run under the standard tclsh interpreter is shown below. It uses the Tclcsound module, a dynamic library that adds the Csound API commands to Tcl.

# load tclcsound.so
#(OSX: tclcsound.dylib, Windows: tclcsound.dll)
load tclcsound.so Tclcsound
set forever 0


# This arranges for commands to be evaluated
proc ChanEval { chan client } {
if { [catch { set rtn [eval [gets $chan]]} err] } {
puts "Error: $err"
} else {
puts $client $rtn
flush $client
}
} 
# this arranges for connections to be made 
proc NewChan { chan host port } {
puts "Csound server: connected to $host on port $port ($chan)"
fileevent $chan readable [list ChanEval $chan $host]
} 
# this sets up a server to listen for
# connections 
set server [socket -server NewChan 40001]
set sinfo [fconfigure $server -sockname]
puts "Csound server: ready for connections on port [lindex $sinfo 2]"
vwait forever 

With the server running, it is then possible to set up clients to control the Csound server. Such clients can be run from standard Tcl/Tk interpreters, as they do not evaluate the Csound commands themselves. Here is an example of client connections to a Csound server, using Tcl:

# connect to server
set sock [socket localhost 40001]


# compile Csound code
puts $sock "csCompile -odac hommage.csd"
flush $sock 
# start performance
puts $sock "csPlay"
flush $sock 
# stop performance
puts $sock "csStop"
flush $sock 

As mentioned before, it is possible to set up clients using other software systems, such as PD. Such clients need only to connect to the server (using a netsend object) and send messages to it. The first item of each message is taken to be a command. Further items can optionally be added to it as arguments to that command.

A Scripting Environment

With TclCsound, it is possible to transform the popular text editor e-macs into a Csound scripting/performing environment. When in Tcl mode, the editor allows for Tcl expressions to be evaluated by selection and use of a simple escape sequence (Ctrl-C Ctrl-X). This facility allows the integrated editing and performance of Csound and Tcl/Tk code.

In Tcl it is possible to write score and orchestra files that can be saved, compiled and run by the same script, under the e-macs environment. The following example shows a Tcl script that builds a csound instrument and then proceeds to run a csound performance. It creates 10 slightly detuned parallel oscillators, generating sounds similar to those found in Risset's Inharmonique .

load tclcsound.so Tclcsound 
# set up some intermediary files 
set orcfile "tcl.orc"
set scofile "tcl.sco"
set orc [open $orcfile w]
set sco [open $scofile w] 
# This Tcl procedure builds an instrument
proc MakeIns { no code } {
global orc sco
puts $orc "instr $no"
puts $orc $code
puts $orc "endin"
} 
# Here is the instrument code
append ins "asum init 0 \n"
append ins "ifreq = p5 \n"
append ins "iamp = p4 \n" 
for { set i 0 } { $i < 10 } { incr i } {
append ins "a$i oscili iamp,
ifreq+ifreq*[expr $i * 0.002], 1\n"
} 
for { set i 0 } {$i < 10 } { incr i } {
if { $i } {
append ins " + a$i"
} else {
append ins "asum = a$i "
}
} 
append ins "\nk1 linen 1, 0.01, p3, 0.1 \n"
append ins "out asum*k1" 
# build the instrument and a dummy score 
MakeIns 1 $ins
puts $sco "f0 10"
close $orc
close $sco 
# compile
csCompile $orcfile $scofile -odac -d -m0 
# set a wavetable
csTable 1 0 16384 10 1 .5 .25 .2 .17 .15 .12 .1 
# send in a sequence of events and perform it
for {set i 0} { $i < 60 } { incr i } {
csNote 1 [expr $i * 0.1] .5 \
[expr ($i * 10) + 500] [expr 100 + $i * 10]
}
csPerform 
# it is possible to run it interactively as
# well
csNote 1 0 10 1000 200
csPlay 

The use of such facilities as provided by e-macs can emulate an environment not unlike the one found under the so-called ‘modern synthesis systems', such as SuperCollider (SC). In fact, it is possible to run Csound in a client-server set-up, which is one of the features of SC3. A major advantage is that Csound provides about three or four times the number of unit generators found in that language (as well as providing a lower-level approach to signal processing, in fact these are but a few advantages of Csound).

TclCsound as a language wrapper

It is possible to use TclCsound at a slightly lower level, as many of the C API functions have been wrapped as Tcl commands. For instance it is possible to create a ‘classic' Csound command-line frontend completely written in Tcl. The following script demonstrates this:

#!/usr/local/bin/cstclsh 
set result 1
csCompileList $argv
while { $result != 0 } {
set result csPerformKsmps
} 

This script is effectively equivalent to the C program shown in section 2. If saved to, say, a file called csound.tcl, and made executable, it is possible to run it as in

csound.tcl –odac hommage.csd 


References

John ffitch. On the design of Csound 5. Proceedings of the 2005 Linux Audio Conference, ZKM, Karlsruhe, Germany.

Victor Lazzarini. The TclCsound frontend and language Wrapper. Sounds Electric 2005 . NUI, Maynooth, Ireland.

F Richard Moore. 1990. Elements of Computer Music, Englewood Cliffs, NJ: Prentice-Hall, 1990.

Stephen T Pope. 1993. Machine Tongues XV: Three Packages for Software Sound Synthesis. Computer Music Journal 17 (2).

Barry Vercoe et Al. 2005. The Csound Reference Manual http://www.csounds.com/manual/html/index.html