AlgoScore - Music By The Numbers

Earlier this year I discovered Jonatan Liljedahl's AlgoScore, a Csound-based program for sound and music composition. Alas, at that time I was unable to run AlgoScore on the machines here at Studio Dave. My builds of Csound use double-precision numerics, and AlgoScore was not compatible with that build option. However, Jonatan recently took another look at the problem, resolved it (with a little help from Victor Lazzarini and other friends on the Csound Developers mail-list), and I can now compile and run AlgoScore with double-precision Csound.

Figure 1: AlgoScore

Csound is an amazing environment for sound and music production and processing, with hundreds of functions and routines for bending, folding, and spindling your sonic masterworks in almost any way imaginable. Yet for all its considerable power, learning to use Csound can be especially troublesome to the novice. Csound is a programming language with a text-based native interface, a fact that often results in much dismay to prospective users who have been attracted by the tempting descriptions of Csound's lavish resources. For many new users this text-based interface is the environment's most frustrating aspect.

Programmers have devised a variety of utilities and applications to alleviate the difficulties of working with Csound. Most of that software replaces the text interface with a GUI. The GUI may be uncomplicated for simple launchers and single-purpose utilities, or it may be quite complex for more full-featured environments. The designs for most of these programs include minimal text entry and maximal use of the GUI's graphic tools. AlgoScore's design recognizes and addresses the need for textual and visual tools appropriate to the task.

What It Is, What It Isn't

On the AlgoScore Web site Jonatan Liljedahl introduces his program as

... a graphical environment for algorithmic composition, where music is constructed directly in an interactive graphical score.

According to the Wiktionary an algorithm is

A precise step-by-step plan for a computational procedure that begins with an input value and yields an output value in a finite number of steps.

Algorithmic music composition is the process of applying such computational procedures to generate values for the materials of music (pitches, dynamics, rhythm, instrumentation, form, et cetera). The space for this article forbids further discussion of algorithmic music, but a Google search for "algorithmic composition" yields plenty of material for study. I highly recommend algorithmic.net as a starting point.

AlgoScore is not a "graphical composition" environment, i.e., the sound is not created by the graphics per se. AlgoScore supplies graphic objects, but their ultimate content and shapes result from Csound and/or Nasal code (a Nasal interpreter is included with the package). Thus, unlike other programs that simplify Csound, AlgoScore requires some knowledge of computer programming. Fortunately Csound and Nasal are relatively simple languages to learn, and even a little familiarity will take you a long way into the possibilities of AlgoScore.

AlgoScore's main display presents a time-line along which various objects will be ordered. These objects include audio and MIDI buses, data generators, envelope structures, and many other useful types. Objects can be hooked directly into the time-line, or their output may be routed to modulate other objects before reaching an output bus, and each object has a unique set of parameters that can be freely edited. As already noted, your edits will result in a new shape for the object. Figures 2 and 3 present the "before & after" images to clarify this process.

Figure 2: Object modulation - Before connection

Figure 3: Object modulation - After connection

A composition is built by repeatedly testing the effects of your code upon your objects and the effects of the objects upon the time-line and each other. This workflow is similar to other non-realtime composition environments such as HighC and OpenMusic. You set out your initial objects, connect them as desired, tweak and twiddle parameter values to your heart's content, listen to the results, and repeat that process until the work is completed to your satisfaction. At that time you can choose to leave it for later edition, or you can export it to a WAV or MIDI file.

To be clear, AlgoScore is not a MIDI sequencer or audio editor. Its event displays can not be edited directly, but your compositions can be exported as WAV or MIDI files for post-processing in your favorite programs. AlgoScore does not provide access to every feature in Csound, but the program is extensible and can be customized by user-defined objects.

Getting It, Installing It

AlgoScore for Linux is available only as a source code tarball, which means you'll have to build and install the software yourself (OSX users can download a pre-built package). AlgoScore itself has some specific dependencies, such as recent versions of Csound and JACK, and its build process requires a recent version of the Cmake utility. Building the program isn't difficult, as long as you've met its requirements. See the AlgoScore Web site for download links and further details regarding installation.

Incidentally, I ran into a few problems while compiling AlgoScore. I built the program according to the included instructions, but the binary segfaulted on opening. After some exchanges with Jonatan Liljedahl it was determined that CFLAGS must include an optimization flag for either -O2 or -O3. I entered

    export CFLAGS="-O2"

at the bash prompt, recompiled AlgoScore, and the program opened without complaint.

I was able to build and install AlgoScore on 32-bit and 64-bit systems, but 64 Studio's JACK is too old for AlgoScore's use of JackMIDI. Alas, due to a compiler bug I was unable to build JACK's current SVN sources. AlgoScore on my 64-bit box will run fine as an audio-only system, but I look forward to using its MIDI capabilities as soon as possible.

Figure 4: From AlgoScore to QSynth

Csound is AlgoScore's audio rendering engine for composition playback and export. For best results, use the latest version of Csound, though most versions in the 5.xx series should work without problems. The situation is different regarding JACK. Most versions of JACK will work for AlgoScore's audio side, but the program's MIDI side utilizes the relatively new JackMIDI protocol available only in versions of JACK greater than 0.102.0. Figure 4 shows the JackMIDI connections panel in QJackCtl, along with the audio and ALSA sequencer connections for the same session. If your QJackCtl does not display a JackMIDI panel you may need to upgrade QJackCtl. Older versions of JACK can be problematic too, even if they support JackMIDI. Early implementations are not identical to the recent versions, so you may need to upgrade JACK.

The program defaults should be agreeable on most systems, but configuration is simple enough with the File/Preferences dialog. Many features can be customized in this dialog, including the GUI theme and your choice of external text editor.

Using AlgoScore

AlgoScore's interface conventions are somewhat unusual. Pop-up menus are available by placing the mouse pointer on an object and then pressing a relevant command key on the computer keyboard. For example, if the pointer lies on an envelope object I can press "p" to open the object Properties dialog. After editing parameters in that dialog I click on the Apply button, and voila, the object's shape is updated with the new values. Similarly, if I place the mouse pointer on a data generator and press the "e" key a text editor will open, complete with the data generator's included code. Again, the Apply button will update the generator's results. For example, if a MIDI event generator is connected to an evgraph (event graph) object it will repopulate the graph with a new set of events created by the generator. Very cool.

Other conventions include object drag, copy, and delete. Right-clicking on a shape will open its connections dialog, right-clicking on a blank area of the main display canvas will summon the Object creator dialog. Double-click a selection in that dialog to add an object to the canvas. A connection is made by selecting the Out option in the originating object's connections dialog (see above). When you release the right mouse button a virtual wire will appear that can be connected to a bus or another object. When the wire is fixed to its destination, another dialog will appear for the connection's function, i.e., whether the object is modulating the frequency of another object, providing an event stream directly to the output bus, or performing some other valid action.

Making Sound

Getting sound out of AlgoScore is simple enough. In the example shown in Figure 5 a data generator has been attached to a MIDI output bus. The generator concocts MIDI note events and sends them along the MIDI bus out to whatever destinations you've attached to AlgoScore's JackMIDI connection. Audio output is created in similar fashion with an audio output bus, and both audio and MIDI buses can co-exist within the same composition. JackMIDI provides a time-stamped MIDI event stream that guarantees tight coordination of events on the MIDI and audio buses.

Figure 5: The datagen object at work

AlgoScore can be used as an external control device via its signal_bus object. According to the manual this bus sends raw float values through a JACK signal port which can then be connected to another program in the JACK system. The midi_bus can be used in similar fashion to provide a neat graphic environment for the production of MIDI event streams that could then be routed to remotely control a program such as AVSynthesis. By default the MIDI bus accepts note-on/off, pitch-bend, and volume (CC #7) events, along with a message type for raw MIDI bytes.

Figure 6 shows off a simple example of AlgoScore at work. A data generator produces a set of events that is routed to a MIDI bus, AlgoScore's connection to JackMIDI (or source for MIDI file output). The generator's events are also sent to an evgraph object, the event display graph. Beneath the graph I've placed a linseg object, an envelope with a simple rising and falling curve. This envelope is connected to the MIDI bus where it modulates the data generators notes with a stream of MIDI volume controller messages.

Figure 6: Modulated MIDI

Let's look closer at the Nasal code within that data generator :

    out.resolution = 0;         # required
    out.interpolate = 0;        # required
    out.data = setsize([], 85); # number of events generated

    math.seed(690);             # for the randomizing functions

    forindex(i; out.data) {         # start event production loop
      t = math.irand2(0, length);   # randomize start time
      n = math.irand2(60, 90);      # randomize note number
      v = 20 + math.linrand() * 100; # randomize velocity
      d = math.linrand() + 2.0;     # randomize duration
      out.data[i] = [t, [n, v, d]]; # create the event
    }                               # end production

The comments clarify that this code is a little machine that creates a stream of 85 MIDI note events with varying start times, durations, note numbers, and velocities. When the datagen object is attached to a MIDI bus and AlgoScore is in playback mode the notes are sent along the bus to your selected JackMIDI target, typically a softsynth or an external sound module.

As mentioned, the linseg object at the bottom of the display represents a rising and falling stream of MIDI continuous controller messages. When that object is first invoked its default properties values need changed. Figure 7 shows the Properties dialog for the linseg object, edited for length, height, fill, and envelope breakpoints. The object's function is here defined to control the volume of the event stream on the MIDI bus, but it could as well have defined a pitch bend curve. Objects can be joined freely to buses, graphs, and other objects, with some restrictions. AlgoScore's console window will report any invalid connections or erroneous data

Figure 7: Properties editor for the linseg object

When all object values are set and all data generators have made their initial runs I click the Play button in the transport/status bar to send a realtime MIDI event stream to AlgoScore's JackMIDI output port. Alternately, I can select File/Export Bus to save the score's output as a standard MIDI file.

I've encountered only two notable performance problems. The first problem was troublesome but easily fixed. If a MIDI note event's duration extends beyond the length of an evgraph object it may result in a stuck note. To solve the problem, disconnect the external synthesizer, lengthen the graph to accommodate the event duration, then reconnect your synth. You may need to close and re-open your target sound device to eliminate the stuck note. The second problem occurred when AlgoScore's JACK connection zombified, another problem easily fixed, thanks to the Score/Reconnect JACK menu item.

Documentation

In this user's opinion the best way to learn how to use AlgoScore is by playing with the examples, tweaking parameters to see and hear "what happens if". For more help, the AlgoScore Web site includes the full package documentation in HTML and PDF formats, along with links to visual and recorded examples of music made with AlgoScore. A mail list and an IRC line round out the comm channels, where AlgoScore's author responds to any and all questions regarding his program.

Outro

I'm partial to deferred-time algorithmic composition systems. I like to think about what I'm doing and I like to plan what I'm going to do, but at the same time I want to be surprised and inspired by the results from the system. For my purposes AlgoScore provides the best of both approaches. Turn-around time is fast, thanks to the well-designed user interface, and playback is immediate and uncomplicated. At this point the only wish I have for AlgoScore would be support for OSC. Jean Pierre-Lemoine has recently added OSC support for AVSynthesis (more Csound-based software), and I'd love to design OSC message generators in AlgoScore that could be routed to control audio and visual parameters in AVSynthesis. Ah, the sweet dreams of musical machines.

Load Disqus comments