Algorithmic Music Composition With Linux, Part 2
In this part of the series we complete our tour of the Grace algorithmic composition environment.
The TargetsGrace can format its output for the following targets and file types :
- Audio - Realtime and file (WAV, AIFF, etc)
- MIDI - Realtime and file (MID)
- OSC - Realtime
- Csound - Realtime and score file
- FOMUS - File (LilyPond and others)
We've already considered Grace as a generator for MIDI files and realtime performance. Now let's see how it works with Csound.
The Csound ConnectionIf you don't already know about Csound here's a description from the cSounds.com site :
Csound is a sound design, music synthesis, and signal processing system, providing facilities for composition and performance
For present purposes we're interested in using Csound as a synthesizer. We'll use Grace as a generator for a Csound-formatted score, then we'll render that score to an audio file by using instruments played by the Csound synth.
The Audio menu include a submenu of Csound-related function, including Grace's Csound Settings dialog (Figure 7). The default options should be okay for new users, while experienced Csounders will appreciate the choice to redefine those options at will. Incidentally, the resulting soundfile will be placed in the current working directory or in the directory specified by SFDIR, a Csound environment variable.
process randscore() repeat 196 send("cs:i", pick(1,2,3,4), between(0,300), pick(.5,1,1.5,2,2.5,3,3.5,4), between(1000,7000), between(100,1400), pick(1,2,3,4)) wait between(.5,2.5) end sprout (randscore(), "simple.sco")
Figure 8 displays the results of running that code. Each randomization sets a particular value for each slot - called a p-field - in the Csound score statement. The first three p-fields are reserved for instrument number, start-time, and duration. Those field assignments cannot be changed, but fields from p4 onwards can define anything else required by the opcodes used by the instrument. In the example, the last three randomizations assign values to amplitude, frequency, and function-table number, after which a wait command instructs the repeat process to wait between .5 and 2.5 seconds.
Creating huge scores is a trivial matter with this sort of code. I've used Common Music many times to create large-scale scores that would have been impossible to realize without its help. Grace has made the process even easier.
FOMUS And GraceDavid Psenicka's FOMUS is just too cool. This program takes your Grace output and converts it to a format compatible with the Finale, Sibelius, Common Music Notation, and LilyPond music notation packages. Happily, the awesome LilyPond is one of those packages, giving Linux users the opportunity to see the outcome of their algorithmic procedures turned into standard music notation. FOMUS - the name stands for "FOrmat MUSic" - is not a notation editor, but its output can be edited in the targeted programs.
The following example shows off FOMUS at work in Grace. Bear in mind that due to the nature of the algorithm the score will be different for each run of the code.
;;; define a process called fomex process fomex () ;;; a for loop that defines the voice number, i.e. upper or lower staff for v from 1 to 2 ;;; loop for the value of off in steps of 1/2, ;;; i.e. eighth notes (quavers) loop for off from 0 to 10 by 1/2 ;;; create a fomus note message with delta time of off send( "fms:note", time: off, ;;; if off is less than 10 set the note duration ;;; to an eighth note ;;; else make it a quarter note (crotchet) dur: #?(off < 10, 1/2 , 1), ;;; if the voice number is 2 set the pitch ;;; between MIDI note numbers 35 to 60 ;;; else give it a pitch between MIDI note numbers 60 to 85 pitch: #?(v = 2, between(35, 60), between(60, 85)), ;;; use the odds function to determine where to apply ;;; the LilyPond directive to create phrase curves (..) voice: v, marks: odds(.333, {"(.."})) ;;; end the loop end ;;; end the process definition end
Now we run our fomex process with the sprout scheduler to create a LilyPond file :
;;; start the run begin ;;; define some score attributes with parts = {{:id "apart" :name "Piano" :inst "piano"}} ;;; run the fomex process to create a LilyPond-ready file ;;; with the score attributes defined above sprout( fomex(), "fomex.ly", parts: parts) ;;; end the run end
These examples are slightly edited versions from the fomus.sal code in the Examples. I've added the comments to clarify its activity in terms hopefully comprehensible to fellow musicians, and Figure 9 should enlighten anyone wondering exactly what the code does. If you have a typical installation of LilyPond and PDF viewer(s) Grace will automagically set up the FOMUS -> LilyPond -> viewer chain. Sweet, and very helpful in the production cycle.
OSCillationsThe Open Sound Control (OSC) data transfer protocol is also supported by Grace. I've described OSC in a previous article, so I'll refer readers to that article for the missing background. It is sufficient here to note that Grace works exactly as the OSC-aware programs described in my article.
The latest versions of Ardour include support for controlling that DAW with OSC messages (Figure 10). This feature is very exciting to those of us who like to play around with algorithmic mixing. Let's look at a simple example of code designed to control some aspect of Ardour via OSC messages.
Ardour does not enable its OSC connection by default, so first we need to access its Options/Misc Options menu and activate the Use OSC item. However, before we can send any messages from Grace we need to know in what format Ardour expects to see them. Ardour has many controls, all of which are or will be accessible through MIDI and/or OSC. Fortunately fellow Ardourista Gwen Coffy has prepared a list of OSC message types for Ardour and their formats. We'll begin with a simple example that toggles the playback and stop states :
;;; Open the OSC connection between Grace (sends on port 7779) ;;; and Ardour (receives on port 3819). send("osc:open", 7779, 3819) ;;; Starts playback in Ardour. send("osc:message", "/ardour/transport_play") ;;; Stops playback. send("osc:message", "/ardour/transport_stop")
Now let's concoct some code in which Grace randomly selects from a list of OSC messages to send to Ardour :
process ardourcon() repeat 8 send("osc:message", pick("/ardour/goto_start", "/ardour/rewind", "/ardour/transport_play", "/ardour/transport_stop", "/ardour/ffwd")) wait 8 end sprout(ardourcon())
Each time the code is executed it will make a new selection from the pick list. Since the repetition will not exclude previous selections it's possible that the run will repeat the previous selection, but have no fear, it's still working as expected.
The example is merely a trivial demonstration of capability. At this point it should be obvious that we can employ loops and other control structures and add other random selection functions for more Ardour actions. I leave it to the reader to explore those possibilities, and I invite fellow OSCars to comment upon their own experiments with the Grace/OSC/Ardour trio.
The Schottstaedt ConnectionGrace makes good use of code from fellow Commoner Bill Schottstaedt's Common Lisp Music (Common Lisp Music) and his SndLib library. The Instrument Browser (Figure 11) in the Audio menu offers more than sixty pre-built instruments designed and tested in Common Lisp Music. Many instruments include example files you can audition to hear if the selected instrument is right for your music. The instruments include typical musical sounds such as piano, bells, and synthesized voice, along with some more unusual sounds such as simulators for the sounds of insects, animals, and ocean waves.
Grace employs SndLib to support the ALSA audio and MIDI services and the JACK sound server. Alas, I was unable to use JACK at low latency settings without xruns and audio distortion. I solved the xruns/distortion issue by raising JACK's period size to 1024, but of course I had to trade off my low latency audio. Oh well, not a big deal for my purposes. Next I specified MIDI Through for Common Music's MIDI data target, but nothing happened when I connected the Through port to QSynth. Eventually I realized that despite my device selection in Grace I had to connect the Juce Midi Output port to QSynth, as seen in Figure 3.
By the way, FOMUS includes Bill's Common Music Notation among its target packages. And if that weren't enough, Grace's implementation of the Scheme Lisp dialect is called S7 and comes from - you guessed it - Bill Schottstaedt.
DocumentationThe documentation for Grace can be accessed through the Help menu where links are provided to the reference manuals for Common Music, Sal, Scheme, and Common Lisp Music. Links are also supplied that will take you immediately to the start pages of the Web site for Common Music and other relevant software. The Help menu includes excellent examples and tutorials for the Sal and Scheme dialects, all of which are highly recommended to new and experienced users. You can run these files without knowing anything about their host languages. However, the files are carefully annotated, an informative amenity for all users.
Dr. Taube has authored a book about algorithmic music composition with Common Music, called Notes From The Metalevel. Published in 2004 the book is understandably out of date in some regards, but its exposition of Common Music is still valuable. I recommend it to anyone seriously interested in the art of music composition with algorithms.
If you can't find what you need in the Help menu or in Rick's book you can join the cm-dist mail list. The list shares its traffic with Common Lisp Music users, and the level of relevancy is very high, i.e. there's lots of signal and not much noise. Rick responds quickly and amiably to users with problems with Common Music, and Bill Schottstaedt is available for help with his software.
OutroI hope you've enjoyed reading this introduction to Grace. I also hope that some of you have been inspired enough to check out the system on your own. I've followed Rick Taube's work for many years, and I must say that Grace is his finest articulation of that work to date. By leveraging the powers of Csound, Common Lisp Music, FOMUS, SndLib, OSC, MIDI, Emacs, and his own Common Music he has created a most powerful environment for the exploration of algorithms as a means for making music.
In my next article I'll present another environment for algorithmic music composition, CsoundAC by composer and Csound developer Michael Gogins.