footils – Using the foo Sound Synthesis System as an Audio Martin RUMORI Klanglabor, Academy Of Media Arts Peter-Welter-Platz 2 D-50676 Cologne Germany [email protected]

Abstract shell scripts are often used for recur- foo is a versatile non-realtime sound synthesis and ring custom tasks closely related to the operat- composition system based on the Scheme program- ing system itself, such as system administration, ming language (Eckel and Gonz´alez-Arroyo, 1994; maintenance and file management. Apart from Rumori et al., 2004; Rumori, 2005). It is mainly that, there are many scripting languages for used for sound synthesis and algorithmic compo- special purposes, such as text processing (awk, sition in an interactive type-render-listen-loop (the Perl). Scripts written in one of these languages musician’s read–eval–print-loop) or in conjunction can be seamlessly integrated with with an editor like the inferior mode of emacs. Un- like with other sound synthesis languages, foo pro- scripting by means of the so called interpreter grams are directly executable like a shell by directive at the beginning of a script (as docu- use of an interpreter directive. foo therefore allows mented in execve(2)): for writing powerful sound processing utilities, so 1 called footils. #!/usr/bin/perl Keywords Those scripts appear and behave like any foo, scheme, scripting, algorithmic composition, sound utilities other UNIX program or and thus get scriptable itself. This property of being “re- 1 Introduction cursive” makes shell scripting so powerful. Scripting has played a major role in the develop- ment of computer systems since the early days. 2 Scripting and computer music Scripting often means being a user and a pro- 2.1 Standalone applications grammer at the same time by accessing func- In the field of computer music, composers of- tions of applications or operating systems in an ten deal with graphical standalone applications, automated, “coded” way rather than interac- such as Ardour or Pd, or with dynamic lan- tively. guages in an interactive fashion, such as Super- A major design principle of the UNIX oper- Collider. While these tools are very powerful ating system is to create several simple appli- in terms of harddisk recording, sound synthesis cations or tools which are suitable for exactly or composition (like Perl for text processing), one purpose and to combine them in a flexible they do not integrate in the same way with the way to implement more complex functionalities. ’s command line interface as This is possible through the well-known UNIX textual scripts (unlike Perl for text processing). concepts of pipes and file redirections. A pow- In most cases, however, this is not necessary or erful command line interpreter, the shell, allows desirable. for accessing these concepts both in interactive Pd can be launched without showing its GUI. mode as well as in so called shell scripts. It the patch to be executed can be given at the is quite easy to generalize an interactive shell command line, including initial messages to be command for using it in a script and vice versa. sent to the patch. SuperCollider’s language In fact, the UNIX shell programming language client, sclang, may be fed with code through its has started to blur the distinction between user standard input which then is interpreted. This and programmer. level of shell automation is already sufficient for 1Use of the term footils by courtesy of Frank tasks such as starting a live session or an inter- Barknecht, see http://www.footils.org active sound installation.

LAC2006 91 2.2 Soundfile utilities 2.3 Scriptable audio applications A major task when using a computer for any Apart from that, there are operations on sound- task is file maintenance. This is especially files which are much closer related to the artis- true for dealing with soundfiles. Common tasks tic work with sound itself, such as filtering or include conversion between different soundfile effects processing of any kind, mixing, arrang- types, changing the sample rate or the sam- ing or simply “composing” based on algorithms ple format, separating and merging multichan- and/or underlying sound material. While re- nel files, concatenating soundfiles, removing DC questing scripting capabilities is evident for do- offset or normalizing. As for sorting or archiving ing file related tasks mentioned above, the latter text files, this kind of tasks are often applied to procedures are mostly done inside single stan- many soundfiles at a time and therefore should dalone applications or sound synthesis systems. be scriptable. Attempts have been made to open the pro- In order to accomplish those tasks, a lot of cessing scheme of the audio data to a script in- command line utilities are available which fully terface. One approach was realized in the Com- integrate which shell scripting in the above- puter Audio Research Laboratory (CARL) Soft- mentioned sense. Examples for such utili- ware Distribution at CRCA (CME) since 1980 ties are sndinfo and denoi included in Csound (Moore and Apel, 2005). The CARL system (Boulanger, 2005), the tools bundled with lib- consists of several independent small UNIX pro- sndfile sndfile-info, sndfile-play and sndfile- grams for reading and writing soundfiles, as well convert, or sndfile-resample from libsamplerate as sound synthesis, effects processing and ana- (de Castro Lopo, 2006). Another example is the lyzing audio data. They communicate with each well known sox program, which also allows for other via ordinary UNIX pipes. This way it is some effects processing (Bagwell, 2005). possible to generate a kind of signal processing Those tools can be called from a shell script in patches as in Pd, but by means of an arbitrary order to apply them comfortably to a large num- shell scripting language: ber of files. The following script might be used to remove mains power hum from a num- $ fromsf infile.ircam | \ ber of soundfiles specified on the command line: filter bandreject.fir | \ tosf -if -os outfile.ircam

#!/bin/bash This approach is quite smart, as it allows for SOX=sox using the UNIX command line for audio pro- FREQUENCY=50 # european origin cessing in the same way as for text processing. BANDWIDTH=6 It is even possible to set up parallel processing SUFFIX="_br" pipes with the para program. since the shell while getopts ":f:b:s:" OPTION; do language is not powerful enough for expressing case $OPTION in those parallel pipes, this program has to use its f ) FREQUENCY=$OPTARG ;; own syntax, which unfortunetaly causes some b ) BANDWIDTH=$OPTARG ;; deformation to the aesthetical integrity of the s ) SUFFIX=$OPTARG ;; CARL approach. esac; done Another approach was implemented by Kai Vehmanen in his ecasound application (Vehma- shift $(($OPTIND - 1)) nen, 2005). ecasound allows for creating flexi- ble so called signal processing chains. The pa- for INFILE; do OUTFILE=‘echo $INFILE | sed -r -e \ rameters for these chains are specified via com- "s/^(.*)(\.[^\.]*)$/\1${SUFFIX}\2/g"‘ mand line options or from files containing the $SOX $INFILE $OUTFILE \ chain rules. Therefore ecasound is fully script- bandreject $FREQUENCY $BANDWIDTH; able from the commandline or from inside shell done scripts.

While using command line soundfile tools this $ ecasound -i:infile.aiff -o:outfile.aiff \ way might be quite elegant, they still can only -efr:50,6 run as they are. It is not possible to directly access and manipulate the audio data itself from Ecasound allows for building up parallel pro- inside such a script. cessing chains at the same grammatical level of

LAC2006 92 the scripting language used for simpler tasks. (score). Nevertheless, it is easily possible to ex- ecasound does not only operate on soundfiles, press a Csound-like semantics of orchestra and but may also record, process and play audio in score with foo, or the concept of behavioral ab- realtime, optionally using controller data such stractions as in Nyquist. as MIDI. By means of the foo primitives, static signal Both the CARL tools and ecasound are exam- processing patches can be generated and exe- ples for tools which allow for directly accessing cuted. Temporal relationships are expressed in the audio processing scheme. by calling them hierarchical time frames which are relative to from inside a shell script, similar to the sox ex- the surrounding one. ample above, one is able to create very sophis- Higher level concepts, such as envelopes or ticated sound processing utilities. musical processes, are entirely implemented in Scheme in the control library by Ram´on 3 Using foo for writing audio Gonz´alez-Arroyo, which is part of foo. processing scripts This openness allows for using foo for very foo’s approach for allowing scripting is different different tasks: apart from algorithmic compo- from the abovementioned ones. foo is neither sition based on highly abstracted Scheme con- a closed standalone application nor a utility es- structs as found in the control library, it is also pecially designed for scripting. foo is a sound possible to use foo on the kernel level for sim- synthesis and composition environment for non- ple tasks like converting soundfiles, extracting realtime use based on the dynamic, general pur- or merging channels, or effects processing. pose programming language Scheme. Like CLM, foo is usually used interactively by entering and evaluating Scheme expressions, 3.1 History of foo which construct signal processing patches or foo was developed by Gerhard Eckel and Ram´on render them into soundfiles. It is also common Gonz´alez-Arroyo in 1993 at ZKM, Karlsruhe, to use foo in conjunction with an editor, such as for the NeXTStep platform. The low-level the inferior-mode of emacs. Since Scheme is an foo kernel is written in Objective-C, while the interpreted language (at least in the implemen- higher level parts are written in Scheme. tation used so far), foo programs can also made Starting from 2002, foo was ported to directly executable from the shell command line the platform by the author using the prompt. GNUStep framework (Fedor et al., 2005), a free This allows for writing versatile “shell” OpenStep implementation. The project was reg- scripts which are not bound to the capabilities istered at SourceForge in 2003. In 2004, foo was of a specific application like sox, but rather can ported to Mac OS X, where it runs natively us- benefit from the full power of a generic program- ing the Cocoa (formerly OpenStep) framework. ming and sound synthesis language. Writing foo Also in 2004, foo was partitioned into libfoo, scripts (“footils”) also differs from approaches which contains the signal processing primitives, such as ecasound in that there is no distinction and elkfoo, which consists of the interface to the anymore between the calling language (shell) Elk Scheme interpreter (Laumann and Hocevar, and the audio processing language (ecasound 2005). This should make a possible future tran- chain rules). sition to a different Scheme implementation eas- 3.3 Making foo scripting comfortable ier. For easier packaging and cross-plattform- Several issues had to be solved in order to make building, foo got an autotools build system in foo programs directly executable as scripts the same year. while not affecting the interactive use of foo. In 3.2 Major concepts of foo the following, some of these issues are described. Them main purpose of foo is to provide a high 3.3.1 Understanding the interpreter quality, highly flexible sound synthesis and mu- directive sic composition system. According to the manpage of execve(2), a foo provides signal processing primitives writ- script can be made executable by adding an in- ten in Objective-C which can be accessed from terpreter directive: inside the Scheme environment. Unlike CLM (Schottstaedt, 2005) or Csound, foo does not execve() executes the program distinguish between instruments and events pointed to by filename. filename

LAC2006 93 must be either a binary executable, be suitable for scripts which do not need this or a script starting with a line of the package in order to speed up the initialization form #! interpreter [arg]. In the process. Therefore the interpreter directive for latter case, the interpreter must be such a script should read: a valid pathname for an executable which is not itself a script, which #!/usr/local/bin/foo -- --unload control will be invoked as interpreter [arg] filename. Another problem occurs at this point: execve(2) apparently does not tokenize multi- Since the original elk executable did not ac- ple initial arguments given in an interpreter di- cept a scheme file as a direct argument, a differ- rective into several arguments but passes them ent startup executable for foo has been written. as a whole as one argument to the interpreter. This was already done in the first version of foo. In order to be able to parse multiple options A foo script can be build by adding a line like given in the interpreter directive, the foo exe- cutable contains a hack which tries to tokenize #!/usr/local/bin/foo argv[1] into several arguments according to a certain heuristic, constructs a corrected argu- at its first line. ment vector and re-executes itself. 3.3.2 Load stages, packages and script 3.3.3 Command line parsing arguments foo scripts have to be able to access the part of The startup procedure of the foo sound synthe- the invoking command line following the script- sis program follows a multi-stage approach: file argument in order to understand script op- • start the interpreter executable and evalu- tions. Command line parsing therefore is a com- ate command line options directed to the mon task in foo scripts. interpreter itself (heap size, etc.) In order to make command line parsing eas- ier for script authors, a scheme library cmdline • hand over control to the scheme interpreter is included with foo. It features alternative op- by loading the toplevel scheme file, load tions such as long- and shortopts, options with foo primitives into the interpreter, evaluate or without parameters, different possibilities of scheme stage command line options, load specifying multiple parameters to options, and foo packages automatic help message generation: • if a script file was specified on the command line, build the command line left over for #!/usr/local/bin/foo -- --unload control the script and execute it, else enter the in- (require ’cmdline) teractive read-eval-print-loop (let* This load procedure indicates a problem ;; equiv-opts-list | mandatory? | \ which arises when specifying options to the foo with-params? | help-string ((option-list executable: ’((("--help" "-h") #f #f "this help screen") (("--outfile" "-o") #t #t "output file") $ foo --unload control (("--type" "-t") #f #t "file type") Usage: foo [options] [arguments] (("--sformat" "-s") #f #t "sample format") ... (("--srate" "-r") #f #t "sample rate") (("--channels" "-c") #f #t "channels"))) $ foo -- --unload control ;; show help message (help The first invocation of foo fails, because (lambda () the option --unload is not understood by the (format #t "~a: script foo~%" (car (foo:script-args))) scheme interpreter’s command line parser. In (format #t "usage:~%") order to make sure it “reaches” the scheme ini- (format #t "~a~%" tialization stage, it has to be “quoted” with -- (cmdline:help-message option-list)) to bypass the elk interpreter. (exit)))) Invoking foo with the option --unload ;; help requested? control will prevent the control library from (if (cmdline:option-given? being loaded into foo at startup. This might (foo:script-args) option-list "--help")

LAC2006 94 (help)) 3.4 footils

;; commandline valid? footils is a collection of foo scripts written so far (if (not (cmdline:cmdline-valid? by Gerhard Eckel and the author. The aim of (foo:script-args) option-list #t)) footils is to provide a set of powerful and robust (help))) scripts for the musician’s everyday use. footils currently consists of the following scripts: This script will produce the following output when invoked with no arguments: fsconvert convert soundfiles

$ ./script.foo fssrconv do a samplerate conversion on sound- (cmdline:validate) \ files mandatory option missing: --outfile ./script.foo: script foo fsextract extract channels from multichannel usage: files --help, -h this help screen --outfile, -o output file fsfold fold a soundfile over itself and normalize --type, -t file type --sformat, -s sample format fskilldc remove DC from soundfiles --srate, -r sample rate --channels, -c channels fsmono2stereo create stereo file from mono multiple : --opt --opt \ file or --opt fsquadro2stereo create stereo file from Other functions of the commandline scheme quadro file library not shown in this example include read- fsnorm normalize soundfiles ing the parameter lists of specific options or get- ting the remaining arguments of the command fsregion extract a temporal region from sound- line, e. g. file arguments. files 3.3.4 Interacting with the outer world: fsreverse reverse soundfiles in time stdin and stdout Reading from standard input and writing to fstranspose transpose soundfiles standard output from foo scripts is important fscat concatenate soundfiles if executed inside a pipe. Imagine calling a foo script like this: These scripts are currently refactored and in- tegrated with the foo distribution. $ find . -name ’*.wav’ | script.foo 4 Conclusions This will mean reading a file list from stan- dard input, which can be accomplished with Several issues of scripting in the field of com- standard scheme functions. The following code puter music have been considered. It turned out reads the files from standard input into the list that with most current software it is not possible files and the number of files into num-files: to write scripts which are seamlessly accessible from the UNIX command line and at the same (let* may benefit from the power of a fully featured ((files programming and sound synthesis language. (do ((file-list ’() It has been shown that writing scripts with (cons last-read file-list)) foo might be able to close this existing gap. (last-read)) ((begin (set! last-read (read-string)) 5 Acknowledgements (eof-object? last-read)) I would like to thank Gerhard Eckel and Ram´on (reverse file-list)))) (num-files (length files))) Gonz´alez-Arroyo for developing foo and for starting the development of scripts for the foo ...) system. Many thanks to Frank Barknecht for his kind Writing to standard output is done similarly permission to use the term footils for the foo through standard scheme functions. script collection.

LAC2006 95 References Chris Bagwell. 2005. Homepage of sox. http://sox.sourceforge.net. Richard Boulanger. 2005. Official homepage of csound. http://www.csounds.com. Erik de Castro Lopo. 2006. Homepage of lib- sndfile, libsamplerate etc. http://www.mega- nerd.com. Gerhard Eckel and Ram´on Gonz´alez-Arroyo. 1994. Musically salient control abstractions for sound sound synthesis. Proceedings of the 1994 International Computer Music Confer- ence. Adam Fedor et al. 2005. The official gnustep website. http://ww.gnustep.org. Oliver Laumann and Sam Hocevar. 2005. Homepage of Elk Scheme. http://sam.zoy.org/projects/elk/. F. Richard Moore and Ted Apel. 2005. Homepage of CARL software. http://www.crca.ucsd.edu/cmusic/. Martin Rumori, Gerhard Eckel, and Ram´on Gonz´alez-Arroyo. 2004. Once again text and parentheses – sound synthesis with foo. Pro- ceedings of the 2004 International Linux Au- dio Conference. Martin Rumori. 2005. Homepage of foo sound synthesis. http://foo.sf.net. Bill Schottstaedt. 2005. The clm home page. http://ccrma.stanford.edu/software/clm. Kai Vehmanen. 2005. Homepage of ecasound. http://www.eca.cx/ecasound/.

LAC2006 96