Algorithmic Music Composition With Linux, Part 1
Dave leads a guided tour of three Linux software packages designed for making music by the numbers.
Over the next few weeks my articles will focus on software systems designed with special consideration for music composition by the use of algorithms. Wiktionary defines an algorithm as "... 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". By that definition algorithmic music composition is the process of using such procedures to generate values for the pitches, dynamics, rhythm, instrumentation, and other formal aspects of the composition.
The packages I'll describe are systems that bind together a set of tools that typically include a language component, some form of graphic I/O, and a compiler for a broad variety of output targets. These systems impose no particular rules regarding the composer's use of either the system itself or its generated data. Whole compositions may be produced through algorithmic means, or a system may be used to generate a series of variations on a single phrase within an otherwise strictly deterministic piece. The software obeys the plan of the algorithm(s) employed, produces the results of its calculations, and hands those results to the composer. The composer obeys the demands of the creative impulse and remains free to dispense of the generated material as he or she prefers.
In this article I'll review Professor Heinrich Taube's Grace. Following articles will profile Michael Gogins' CsoundAC and Christopher Ariza's athenaCL. Each system has its unique characteristics, and each one is a valuable addition to the algorithmic composer's software armory.
Common Music/Grace is a software system designed to assist composers working in music styles that employ chance, random, fractal, and other stochastic methods of generating values for their musical materials. Common Music is a music programming language that includes a variety of functions and routines particularly important to algorithmic composition. Grace is the Graphic Realtime Algorithmic Composition Environment, a JUCE-based GUI for Common Music that includes code editors for the Sal and Scheme language dialects, a set of predefined instruments, an interactive plotter with playback and various display options, a variety of output targets, and access to the host system's audio and MIDI I/O services. Common Music is transparently integrated into the Grace system so throughout the remainder of this article I will refer simply to Grace, with the same case as shown in the GUI splash screen.
Incidentally, Dr. Taube began the Common Music project in 1989 at Stanford University's Center for Computer Research in Music and Acoustics, better known as CCRMA (pronounced just like karma). In 1996 Common Music won 1st prize at the Concours International de Logiciels Musicaux in Brussels, and the system continues its evolution today at the University of Illinois at Champagne/Urbana.
Installation & Configuration
If you run Fedora or Ubuntu the easiest way to get Grace for your system is to download the precompiled binary. If you need or want to build it yourself the process isn't terribly difficult, but you will need to install an uncommon dependency or two. See the Common Music Web site for complete instructions for building the system.
There is no need to install the binary for system-wide use. To run it just enter the directory where you opened the package file and launch the binary there, i.e. :
cd $HOME/Grace ./Grace
You'll soon see the Grace console as shown in Figure 1. Now you'll need to configure its audio and MIDI settings from the dialogs under the Audio menu (Figure 2). The Linux version of Grace supports ALSA and JACK audio. Personally, I prefer JACK, but the system works well with either engine. However, if you decide to use JACK you may need to increase its buffer period size. I usually run my M-Audio Delta 66 with a small period (128) for low latency performance. Alas, with that setting the Grace audio file player suffered audible discontinuities during playback - xruns in JACK-speak - so I adjusted the period size to 1024 and eliminated the xruns.
The MIDI configuration dialog lets you select the preferred MIDI input and output ports, but unfortunately the configuration is somewhat confused. Regardless of which ports I selected in the configuration dialog only the Juce Midi I/O ports (Figure 3) sent and received data. As long as those ports are correctly configured everything works fine, but the confusion can be annoying.
Once the audio and MIDI ports are configured you're ready to compose with Grace.
I'm going to jump straight into programming Grace at the code level, so bear with me if I leave some things unexplained for now. Sal is a programming language, but it doesn't require a degree in computer science to master its essentials. Editing existing code and building my own library of useful code fragments proved to be my best way into the language. I won't claim mastery of the entire language - there are many aspects I haven't yet required in my work - but I have found it easy to learn the parts I needed/wanted to know. Of course your way into Sal will be made even smoother if you have some experience with another programming language.
We'll begin our explorations by using one of the system's code editors to create some MIDI data and send it to the MIDI output port. Open a new editor from the File menu. Our examples are written in the Sal2 language, so open the editor's Options menu and set the syntax to Sal2. You can choose to set it as the default syntax, or you can set it to Lisp, the original Sal, or plain text if you like.
Grace began life as Common Music, a clearly Lisp-derived language designed for music composition. Common Music is still supported in the GraceCL version of the system, and the Scheme implementation retains enough parentheses to satisfy most hard-core Lispers, but I believe that new users are more likely to enjoy the relative ease of programming in Sal. Like the original Common Music language, Sal includes tools for phrase generation and manipulation, pattern ordering/reordering, spectral composition, cellular automata, and many other interesting processes. It also has the appeal of an uncluttered syntax.
Consider this Sal code fragment culled from the midiout.sal tutorial :
loop repeat 8 for t from 0 by .125 send("mp:midi", t, key: between(40, 90)) end
Nice. No parentheses or other syntactical botheration.
Copy that fragment and paste it into your open editor (Figure 4). The code is run by selecting the code block in the editor - or simply placing the cursor after the end marker - and pressing the Ctrl + Enter key combination. Alternately, you can select the Execute item from the editor's Eval menu. Given a properly configured connection you should be able to route the newly created MIDI messages from the editor to whatever MIDI device(s) - software or hardware - that you have available to your system. For the examples here I recommend a synthesizer or sampler with a General MIDI sound set.
Some of the code's functions might be obvious even to non-programmers. A loop repeats itself 8 times and performs the instructions within the loop, a for statement and a send command. The for statement defines a variable t by starting its value at 0 and increasing it by .125 in each iteration of the loop. The send command sends a MIDI message in the following format :
send (midi_port:midi_note_event start_time MIDI_keynumber)
In the code block the message start time is defined by the variable t. On each repetition of the loop the message start time will increase by .125 seconds. The MIDI note number is defined by a function called between, which selects a random integer between 40 and 90 (MIDI notes are numbered frm 0 to 127). An explicit MIDI note-off message is not required, Common Music will automatically end the message at the end of its duration, i.e. after the message has lasted for .125 seconds.
Thus, our code fragment creates a different randomly selected MIDI note event eight times at evenly-spaced intervals and sends each event to the MIDI port chosen for the task (see the Audio/MIDI Out menu item). Where it goes from there is up to the user, though in this instance I suggest routing the MIDI output to a synthesizer or sampler.
Let's make some simple changes to the code at three access points. We'll change the number of repetitions of the loop, we'll redefine the duration of t, and we'll expand the range of numbers for the between function.
loop repeat 16 for t from 0 by .250 send("mp:midi", t, key: between(32,96)) end
At this point the savvy MIDI musician might wonder about other information that commonly attends to a MIDI note event. Have no fear, the other information - velocity, controller data, pitch bend - is all there in default values unless specified otherwise. For example, if the key: slot had not been filled its default value of 60 would have been used.
For a final touch we'll add a random MIDI Program Change number to select a new instrument per run. We'd like to save the output to a MIDI file, so we'll also add a mechanism to do so :
file "midi-loop-01.mid" () loop repeat 12 for t from 0 by .125 send("mp:prog", val: random(16)) send("mp:midi", t, key: between(32,96)) end end
Now when the code is executed it will perform its actions in realtime as before and create a MIDI file of the performance. By the way, in the example the file will be written to the current directory, but you can specify any path you prefer.
I leave it to the reader to experiment further. Consult the Common Music reference documentation in the Grace Help menu to see what other randomization routines can replace those used in our example code. Load other examples and tutorials from the Help menu, experiment with the code, then experiment some more.
Composing With The Plotter
The Plotter (Figure 5) is a normalized 2D graph that functions something like a piano-roll sequencer display, minus the tracking cursor. You add a point on the graph by holding the Ctrl key while clicking with the mouse (any mouse button will do), and you can delete a point by selecting it and then pressing the Delete key. Double-click on a point to open a precision editor, double-click anywhere else within the graph to open an editor for the current layer.
You can play your graph through the Play Plot dialog in the Audio menu. This dialog determines the playback length, note duration and amplitude values, MIDI channel, and other playback functions. You can also save the plot's output as a MIDI file via this panel.
The data display can be set for points alone, connected points (an envelope display), unpointed lines, vertical and horizontal boxes, and other representations. The Plotter's data can be converted to Sal, Lisp, or XML via the Export dialog under the Plot menu. The data can be formatted as an envelope list or a points record and sent to your current code editor, to a new one, or to the clipboard. You can load a MIDI file into the Plotter - in which case the display is no longer normalized (Figure 6) - and that data can be edited and exported at will. This feature opens some fascinating possibilities for transformative processes over large data sets, but alas, space forbids further exploration of the Plotter. We must move on to describe the Grace targets.
In the next part of this series we'll continue our exploration into algorithmic music made with the Grace system.
Similis sum folio de quo ludunt venti.
|Designing Electronics with Linux||May 22, 2013|
|Dynamic DNS—an Object Lesson in Problem Solving||May 21, 2013|
|Using Salt Stack and Vagrant for Drupal Development||May 20, 2013|
|Making Linux and Android Get Along (It's Not as Hard as It Sounds)||May 16, 2013|
|Drupal Is a Framework: Why Everyone Needs to Understand This||May 15, 2013|
|Home, My Backup Data Center||May 13, 2013|
- New Products
- Linux Systems Administrator
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Designing Electronics with Linux
- Dynamic DNS—an Object Lesson in Problem Solving
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Using Salt Stack and Vagrant for Drupal Development
- Reply to comment | Linux Journal
6 hours 47 min ago
- Nice article, thanks for the
17 hours 27 min ago
- I once had a better way I
23 hours 13 min ago
- Not only you I too assumed
23 hours 30 min ago
- another very interesting
1 day 1 hour ago
- Reply to comment | Linux Journal
1 day 3 hours ago
- Reply to comment | Linux Journal
1 day 10 hours ago
- Reply to comment | Linux Journal
1 day 10 hours ago
- Favorite (and easily brute-forced) pw's
1 day 12 hours ago
- Have you tried Boxen? It's a
1 day 18 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi
It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?