Hacking Perl in Nightclubs
I've found the experiences of dancing and programming to have a great deal in common. With both I am immersed in an abstract world of animated structures, building up and breaking down many times before finally reaching a conclusion. Indeed, when the operation of even the dullest data-munging computer program is visualized, for example in a debugger, it does seem to be dancing around its loops and conditions -- moving in patterns through time.
In other words, a musical score is a kind of source code, and a musical performance is a kind of running program. When you play from a musical score or run a program you are bringing instructions to life.
So a piece of composed music is like a Perl script, but let's not forget improvised music. The rules behind improvised music -- for example improvised jazz -- develop during a performance, perhaps with little or no predefined plan. Where is the comparison with code here? Well, how many times have you sat down to write some Perl without first deciding exactly how you were going to structure it? Perl is great for improvising. The question is, can you write improvised Perl scripts on stage? This article hopes to answer this question.
Consumer Software v. Live Programming
If music and software have so much in common, how do they commonly meet? Well, modern-day music is often composed not at a piano but at a computer. Here the limits of composition are defined by the creators of software, with musicians eagerly waiting for the next upgrade of their favorite music application. However, at the fringes of electronic music, you find musicians who are also programmers, writing their own software to generate their music. This is a diverse world, spanning and mixing all the genres you could think of, from classical cantata form to speed garage to dance hall. Very few of these musicians have chosen Perl to write their musical code, but this article hopes to encourage more Perl hackers to turn their tools to music.
A little about myself -- I'm a musician who for the last few years has used Perl as my only musical instrument. I've had some successes, with hundreds of people dancing to my Perl, jumping about to my subroutines, whooping as I started up a new script. To this end, I built a whole library of little compositional Perl scripts that I ran together to make music. However, when running my Perl scripts during a performance I grew to feel as if I wasn't really performing -- I was running software I'd written earlier, so to some extent the performance was pre-prepared. I could tweak parameters and so on, but the underlying structure was dictated by my software. So what's the alternative?
Over the last couple of months, I've moved toward writing software live, in front of an audience. If a programmer is onstage, then they should program! This may seem a little extreme, but I'm not the only one making music this way. This approach grew through a collaboration with Adrian Ward called "slub," and also from a fast-growing organization called TOPLAP, the Temporary Organisation for the Promotion of Live Algorithm Programming. Check toplap.org/ for more information.
I'll introduce my live-programming environment -- "feedback.pl" --later. First, I'll talk a little about writing code that generates music.
Generative Music in Practice
When I use the phrase Perl Music, I mean music that is generated live by Perl code. Instead of writing a melodic sequence by hand, a Perl Musician writes a Perl script that algorithmically generates a melody. When making music in this way, the composer is taking a step back from the music, working with the structure behind a composition rather than with the composition itself. This approach is often termed "Generative music."
Perl hackers know that programming is a creative endeavour. So instead of starting with someone else's software, why not start with nothing apart from some vague musical idea? Then sit down and start to express that idea as code.
Now, while musical Perl code doesn't have to be complicated, it doesn't have to make sense either, you don't have to plan on making anything that is at all readable the next day. Saying that, to take full advantage of any inspiration you have found, code needs to be written very quickly, so keen programming skills and good knowledge of Perl is of great advantage.
In any case, the most important thing is that your code makes a musical pattern that you judge to be good. Sometimes elegant mathematical forms sound good, other times unexpected bugs and chaotic nonsense produce the most interesting results.
Let's sidetrack to talk a little about how you might build an environment to make live Perl music, starting with a brief tour around some useful CPAN modules.
CPAN Music Modules
Sadly Perl isn't quite fast enough to be useful for synthesizing sounds directly. Instead we have to use Perl to trigger sounds by talking to other bits of software or hardware.
There are a fair few music related Perl modules to be found on CPAN,
perhaps the best known being the MIDI-Perl package by Sean Burke.
MIDI-Perl concerns itself only with the reading and writing of MIDI
files, which are a kind of musical score - this article is concerned
with making live music, not writing scores. However, if you do want
to create or manipulate MIDI files, the MIDI::Simple
module in the
MIDI-Perl package is a great place to start.
As well as a file format for storing musical scores, MIDI also
provides a real time protocol for triggering sounds on synthesizers
and samplers in real time. If you have a MIDI compatible synthesizer
or sampler then there are CPAN modules to help you take advantage of
them; MIDI::Music
for UNIX and Win32API::MIDI
for Windows.
Software synthesizers are now commonplace and reliable, thanks to the increasing speed of computers and improving latency times of operating systems including the Linux kernel. Most music software is still controllable by MIDI, but for a faster and more modern alternative, have a look at Open Sound Control (OSC).
OSC is an open network protocol for music, and is well supported by the best free software music applications including pure-data, SuperCollider and CSound. It's most commonly carried over UDP, so you can use your existing TCP/IP network and Internet connection for OSC.
For sending and receiving OSC messages with Perl, install the
Audio::OSC
package from CPAN. Here's an example of its use:
my $osc =
Audio::OSC::Client->new(Host => 'localhost', Port => 57120);
$osc->send(['#bundle', time() + 0.25, ['/play', 'i', "60"]]);
This example sends a message to port 57120 telling it to play number
60 in a quarter of a second's time. The OSC protocol doesn't define
the meaning of such commands, it's up to you to make sure that the
receiving application understands what the sending application is
asking of it. Later I'll show the use of Audio::OSC
to talk to an
application called SuperCollider.
Ecasound is an excellent piece of software useful for live routing and
recording of audio. It supports LADSPA plug-ins, allowing you full
programmatic control over a wide range of effects such as noise
filters, reverb, chorus and so on. For full real time control over
ecasound, install the Audio::Ecasound
module.
While not likely to have a place in a professional studio, Audio::Beep
is a fun way of making primitive, monophonic music. I'll use this in
an example later.
Finally, perhaps the most essential CPAN module for live music is
Time::HiRes
. Unless your music is very intense, at some point you'll
want your script to pause before triggering the next sound. Normally
Perl only lets you sleep for whole seconds at a time, but Time::HiRes
offers a great deal more accuracy. Time is such an important issue in
music, that I've dedicated the whole of the next section to it.
Time
Time is central to music, and presents a few technical hurdles to jump. If you have more than one music-generating Perl script running at the same time, you'll want to keep them in sync somehow, and if you're playing with someone else, you'll need to keep in sync with them as well. You not only need to make sure all the different scripts are playing at the same speed, but also in phase - that is, everything needs to be able to work out when the start of the bar is. Further, at some point you'll want to change the speed of the music, especially if your crowd are looking a bit restless. And if you want to start up a new script while another is running, how do get it to start at the right moment?
Here's how I do it, in brief. I have a central time server called 'tm.pl', that stores the current bangs per minute (bpm), the number of bangs that have occurred since the script started, the number of bangs since the last bpm tempo change and the time of that change. It keeps this information up to date by referring to the system clock. By fetching these four simple bits of information it's possible for another Perl script to work out what it should be doing and when.
A 'bang' is like a musical beat, or the regular tick of a clock. Each Perl script keeps its own 'heart beat', an event that regularly calls a method called 'bang'. I put all my music generating code inside that 'bang' method. If it receives a bpm change from the server it schedules the change of speed at exactly the right moment.
Well, I say that but of course computers are volatile things, and so in practice events never happen at exactly the right moment. But as long as the math is right, any slight error is corrected, and so the scripts stay in synchrony.
Introducing feedback.pl
Now as I tried to explain earlier, I like to write code live while practicing and performing. I should really explain what this means.
I wrote my own little text editor for live coding. The editor is only intended for writing Perl code, but doesn't have a save function. In that case, you might wonder how I execute the code.
Well if you're using feedback.pl, the code you're writing is running
all the time, in the background. In fact feedback.pl has two
"threads" - one thread is the text editor and another runs the code
that is being edited. The running code in the second thread re-parses
itself whenever you press ctrl-x, leaving all variables intact.
mod_perl programmers will be familiar with this concept -- the
Apache::StatINC
and Apache::Reload
modules do something very similar.
It gets weirder -- the running code can edit its own source code. This
is really useful for user feedback. I quite often write code that
puts comments in its source that tells me what the running code is up
to. So, the human interface to the running code is its source code.
You edit the code to modify the process; the process edits the code in
response. That's why it's called feedback.pl
.
If you want to see what I mean, download feedback.pl
from:
cpan.org/authors/id/Y/YA/YAXU/perl-music-article/examples/feedback-0.1.pl
You'll need a few modules installed from CPAN to get it to work.
Audio::Beep
, Audio::OSC
and Time::HiRes
. Sadly Audio::Beep
only works
under Linux and Microsoft Windows at the moment, users of other
operating systems will have to fiddle about to get these examples to
work.
Once everything is ready, run feedback.pl
and type this little script in:
# 231
sub bang {
my $self = shift;
$self->code->[0] = '# ' . $self->{bangs};
$self->modified;
}
Press ctrl-x and it will start to run. $self->{bangs}
contains the
number of bangs since the script was started, and this is written to
the first line of the code (make sure that line doesn't have anything
important in it). Calling $self->modified
tells the editor that the
code has changed, causing it to refresh the screen with the changes.
OK, lets make some sounds.
#
sub bang {
my $self = shift;
my $note = 100;
$note += 50 if $self->{bangs} % 4 == 0;
$note -= 30 if $self->{bangs} % 3 == 0;
$note += 60 if $self->{bangs} % 7 == 0;
beep($note, 40);
$self->code->[0] = '# note: ' . $note;
$self->modified;
}
Hopefully this should play a bassline through your speaker. beep()
is a routine imported from Audio::Beep
; you just pass it a frequency
in Hz and a duration in milliseconds.
The bassline is surprisingly complex for such a short program. It could almost be the theme tune to an 8-bit computer game. The complexity comes from the use of polyrhythms, in this case three different modulus combined together.
Polyrhythms are wonderful to play with but largely absent from commercial dance music. You can see one reason for this absence by looking at consumer music software -- while such pieces of software are obsessed with loops, they don't make it very easy for you to mix loops with different time signatures together. Writing our own code brings us freedom from such constraints, and you can really hear that freedom in polyrhythms.
Now these simple beeps are fun, but quite limited, obviously. You can only play one beep at a time, and have no control over the timbral qualities of the sound. Lets have a quick look at getting better sounds out of our computers by controlling SuperCollider from Perl.
Beyond the Beep -- SuperCollider
SuperCollider is a powerful language for audio synthesis, is free
Software, and runs under both Linux and Mac OS X. It consists of two
Parts: scserver
, a real-time sound synthesis server, and sclang
, an
Object-Oriented interpreted language based on smalltalk (sclang). Due
to SuperCollider's client-server architecture, it's possible for other
languages to replace sclang and control scserver directly, although
scheme is the only other language with the libraries for this so far.
However, with Perl it's easy to control sclang scripts with the
aforementioned Audio::OSC
module.
As a rich programming language, SuperCollider takes a bit of learning; however, if you want to try making some sounds with Perl and SuperCollider script. Here it is:
cpan.org/authors/id/Y/YA/YAXU/perl-music-article/examples/simple.sc
Once you have SuperCollider running, you can start up the script like so:
sclang ./simple.sc -
Note that SuperCollider users call their programs "patches" rather than "scripts". Patching (or paching) is a historical term that originally referred to the programming of analog synthesizers, but as far as SuperCollider is concerned, it's mostly synonymous with scripting.
The simple.sc script listens for OSC messages, which you can send from feedback.pl using the built in methods 'play' and 'trigger' like this:
sub bang {
my $self = shift;
# play a "middle c" note every fourth bang
$self->play({num => 60})
if $self->{bangs} % 4 == 0;
}
You can also trigger a sample in this way:
sub bang {
my $self = shift;
# play a drum sample for 100 milliseconds, panned slightly to the left,
# every sixth bang
$self->trigger({sample => '/home/alex/samples/drum.wav'
ts => 100,
pan => 0.4
}
)
if $self->{bangs} % 6 == 0;
}
Check the source code of feedback.pl to see how the OSC message is sent, and to seek out extra parameters to effect the sound further.
Multiple Scripts
To have multiple scripts running at the same time, you can use my "tm.pl" script.
cpan.org/authors/id/Y/YA/YAXU/perl-music-article/examples/tm-0.1.pl
It requires a spread communication daemon (spread.org/) to be
running and the Spread::Session
Perl module to be installed. Start
the tm.pl script, set the environment variable SPREAD to 1, and then
multiple invocations of feedback.pl will stay in synch. You can
change the bpm (bangs per minute, similar to beats per minute) at any
time, for example $self->set_bpm(800) will set the bpm to 800, which
is suitable for fast gabba techno.
Further Experiments
I haven't gone into detail about how to generate the music itself - that's really up to you and your imagination. However, here are a few pointers toward some interesting areas of research.
Markov chains are a way of probabilistically analyzing a
one-dimensional structure and then generating new structures based on
the original. It's used often for producing amusingly garbled text,
but can also be used for making amusingly garbled music. Check
Richard Clamp's Algorithm::MarkovChain
module on CPAN for more details.
Regular expressions are of course excellent for manipulating chunks of text, but why not instead use them to manipulate sequences of notes while they are playing? Being able to hear as well as see the effect of a regex is rather pleasing.
Lastly, my best advice when looking for inspiration is to listen to your favorite pieces of music. Listen to the structure behind a piece and think about how you might write an algorithm to create that structure. Once you start writing the code you'll start to get more ideas based upon it, so that the eventual music sounds nothing like what you found inspiration from.
Conclusion
This might all sound like a rather strange and tortured way of making music, but actually the opposite is true. It's not strange, there is structure behind every piece of music, and it's quite normal for composers to think of the composition of this structure in terms of a defined process. The classic example is of Mozart using dice to generate tunes. It's not tortured either. Thanks to Perl, music generating code can be extremely fast to work with.
The aims of all this are many and varied. One is to make people dance to Perl code, another is to be able to jam freely with others, not only laptop musicians but also drummers, singers and other 'real' musicians. Indeed, although programming does allow a certain unique perspective on things, the overall aim is to be able to reach some kind of level playing field with other musicians. I believe to reach this point, we have to learn how to use the whole computer as a musical instrument, rather than limiting ourselves to consumer software packages. So give it a go with Perl.
Footnote
At the time of writing and due to active development, Audio::OSC
is
not currently passing tests under Linux and quite possibly other
architectures. It'll be fixed soon but until then users can find a patch that allows
it to work under Intel-based Linux. To be truthful, all of this
software is heavily experimental, feel free to contact me if you'd like some help.
- Download
- Documentation
- Perl Bloggers
- Foundation News
Sponsored by
- Subscribe to this website's feed
Monthly Archives
- February 2014 (1)
- January 2014 (1)
- October 2013 (1)
- January 2013 (1)
- December 2012 (1)
- November 2012 (1)
- October 2012 (2)
- August 2012 (2)
- June 2012 (11)
- May 2012 (18)
- April 2012 (17)
- February 2012 (1)
- December 2011 (1)
- September 2011 (1)
- August 2011 (2)
- June 2011 (1)
- May 2011 (3)
- April 2011 (1)
- March 2011 (1)
- February 2011 (1)
- January 2011 (1)
- November 2010 (1)
- October 2010 (2)
- September 2010 (1)
- August 2010 (3)
- July 2010 (2)
- April 2010 (2)
- March 2010 (4)
- May 2008 (1)
- April 2008 (2)
- March 2008 (1)
- February 2008 (1)
- January 2008 (1)
- December 2007 (2)
- September 2007 (1)
- August 2007 (1)
- July 2007 (1)
- June 2007 (1)
- May 2007 (1)
- April 2007 (1)
- March 2007 (1)
- February 2007 (1)
- January 2007 (1)
- December 2006 (1)
- November 2006 (2)
- October 2006 (1)
- September 2006 (1)
- August 2006 (1)
- July 2006 (1)
- June 2006 (1)
- May 2006 (1)
- April 2006 (1)
- March 2006 (1)
- February 2006 (4)
- January 2006 (4)
- December 2005 (4)
- November 2005 (3)
- October 2005 (2)
- September 2005 (2)
- August 2005 (9)
- July 2005 (8)
- June 2005 (9)
- May 2005 (8)
- April 2005 (7)
- March 2005 (6)
- February 2005 (7)
- January 2005 (6)
- December 2004 (8)
- November 2004 (8)
- October 2004 (5)
- September 2004 (9)
- August 2004 (6)
- July 2004 (8)
- June 2004 (6)
- May 2004 (7)
- April 2004 (8)
- March 2004 (8)
- February 2004 (9)
- January 2004 (7)
- December 2003 (4)
- November 2003 (7)
- October 2003 (8)
- September 2003 (6)
- August 2003 (7)
- July 2003 (9)
- June 2003 (9)
- May 2003 (8)
- April 2003 (8)
- March 2003 (10)
- February 2003 (8)
- January 2003 (8)
- December 2002 (5)
- November 2002 (9)
- October 2002 (7)
- September 2002 (11)
- August 2002 (8)
- July 2002 (8)
- June 2002 (4)
- May 2002 (6)
- April 2002 (6)
- March 2002 (7)
- February 2002 (5)
- January 2002 (8)
- December 2001 (7)
- November 2001 (5)
- October 2001 (9)
- September 2001 (7)
- August 2001 (13)
- July 2001 (8)
- June 2001 (13)
- May 2001 (11)
- April 2001 (9)
- March 2001 (8)
- February 2001 (8)
- January 2001 (8)
- December 2000 (6)
- November 2000 (10)
- October 2000 (10)
- September 2000 (2)
- August 2000 (2)
- July 2000 (5)
- June 2000 (7)
- May 2000 (7)
- April 2000 (3)
- March 2000 (2)
- February 2000 (2)
- January 2000 (2)
- December 1999 (6)
- November 1999 (6)
- October 1999 (5)
- September 1999 (4)
- August 1999 (3)
- July 1999 (2)
- June 1999 (3)
- April 1999 (1)
- March 1999 (1)
- January 1999 (1)
- December 1998 (1)
- November 1998 (1)
- July 1998 (2)
- June 1998 (1)
- March 1998 (1)