Hacking Perl in Nightclubs
by Alex Mclean
|
Pages: 1, 2
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:
http://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:
http://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.
http://cpan.org/authors/id/Y/YA/YAXU/perl-music-article/examples/tm-0.1.pl
It requires a spread communication daemon (http://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.

