Creating L-Systems in Supercollider

L-systems also known as Lindenmayer Systems is a rule based parallel rewriting system.  Every L-system has an axiom (starting point) and series of rules.  The rules get replaced into one another to grow the L-system or in other words works with the ideas of formal grammars.  L-systems were first introduced by Aristid Lindenmayer to describe growth models in plants.  Since then they have evolved further into fractal like approaches, Turtle Graphics, arts and music.

I first discovered musical aspects of L-systems when I was getting my masters degree and ended up writing my thesis about ways of interpreting the resultant string of characters as well as using the image as guides for music composition.  When I was researching this, I found it very difficult to produce a complex L-system whose output string I could use directly in a synthesis environment.  Max/MSP has certain capabilities but also  can only hold a maximum number of values in a table or collection and they all have to be indexed which is not efficient if the string is 4000 characters long.  Supercollider though has the abilities to generate the string as well as refer back to it for controlling parameters or musical rules.

The following code shows how I put together an L-system string calculator. For this code to work the wslib Quark has to be installed. To do this type Quarks.gui and select the wslib.  I have also used this L-system sting calculator in 2 sound installations titled Reflective Tunnel and Reflective Catacombs.  Reflective Tunnel was set in the tunnels at Wesleyan University in Connecticut and used the harmonics of a cello split to different rules in the L-system.  Then the L-system was played back in the tunnel with pseudo-random envelopes on all the frequencies to create layers of sound that phased and reflected off the concrete walls. In Reflective Catacombs the space was sonically mapped to obtain the resonant frequency and assigned to rules in an L-system and pseudo-random envelopes to play back in the space.  Both installations created shifting atmospheres and interesting beating patterns.
// boot server if needed
Server.default = s = Server.internal.boot

// system to substitute rules
~substitute = { |string, dict|
var str= “”; { | c |
var val = dict[c.asSymbol] ? c;
str = str ++ val;

// fill a dictionary with entries
~myDictionary =;
~myDictionary[\a] = “B – CG”;
~myDictionary[\b] = “A*F-D”;
~myDictionary[\c] = “E/G + F”;
~myDictionary[\d] = “G – BC”;
~myDictionary[\e] = “G/E – BC”;
~myDictionary[\f] = “A -BC/E”;
~myDictionary[\g] = “A -DF/G”;

a = “a” //axiom

//change a to whatever the starting rule is. The number before collect is the number of iterations

~history =5.collect { a = ~substitute.value(a, ~myDictionary).postln };


Once this code is run the stream gets assigned to ~history that can be assigned to a variable and put into a routine  or printed as a long list.

k = ~history

t = Routine({ { | c| c ;

if(c.asString == “F”, {“FM”, [\carrierfreq, [34, 100, 673, 589, 10, 2, 7, 45, 234, 45, 4357, 1239, 3240].choose.postln])});


This routine reads one character in the L-system every 0.35 seconds and looks to see if it is an F.  If it is it selects a frequency at equal probability from the list and assigns it to the carrier frequency of the FM synth definition.


For interest in my L-system interpretations and mappings to compositions my thesis can be found at



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s