Using L-System to Generate Music

Written by on January 31, 2021 in LISP, Music, Programming with 0 Comments

L-system is a powerful string rewriting system. Opusmodus supports an implementation of this system (inspired by and based on this implementation).

It is possible to use the L-system to generate anything that can be described in terms of an alphabet and a set of rewriting rules. 

Let us start with a simple example:

Defining an L-system in Opusmodus

Defining an L-system in Opusmodus

As you can see, there are two steps. The first is to define a class derived from “l-system” with 2 fields, “axiom” and “depth”, initialised appropriately.

The second step is to define a set of rewriting rules using the “l-productions” method. As per the rules of this example, the symbol “a” expands to “a” followed by “b”. “b” expands to “a” followed by “c”. And “c” expands to “b”. The rewriting procedure starts with the “axiom”, in this case the string “a b”, and repeatedly expands it by applying the given rules.

Let us see what we get:

Generated Output

Generated Output

The “rewrite-lsystem” method takes our class name and then generates the output starting with the given “axiom” and repeatedly applying the rules “depth” times. 

Let us see the generated output starting from depth 0 to depth 3:

Output at Different Depths

Output at Different Depths

As the above shows, we can optionally specify the depth when invoking the “rewrite-lsystem” method .

Before proceeding with the next example, I want to simplify the task of defining the custom class and the corresponding “l-productions” method. Because this is Lisp, that is fairly straightforward:

Simplifying L-system Definition

Simplifying L-system Definition

I have defined a “macro” called “def-lsystem” that combines the two steps into one.

Let us use this method to define a grammar that generates simple “noun phrases” in English.

An L-system for Simple Noun Phrase

An L-system for Simple Noun Phrase

The output is non-deterministic in the sense that each time it runs, it is “likely” to produce a different output. Here is what I got when I ran it 5 times:

Generated Outputs

Generated Outputs

The above example also shows that we can use functions inside rules, and this is quite powerful indeed.

OK, now that you have an idea of what an “L-system” can do, how is it connected to music? Since our system can generate “sequences” from a given “formal grammar”, we can define a grammar for generating “pitches” if we so desire.

Before I define such a grammar, it is interesting to know that the “rewrite-lsystem” method optionally takes a “mapping” from one alphabet to another. Using this feature, we can turn the generated “noun phrase” into a “pitch phrase”. See the following example:

L-system Output Mapping

L-system Output Mapping

Of course, if the focus is on pitch generation, it is preferable to do it directly. Here is an attempt:

L-system for Pitch Generation

L-system for Pitch Generation

I have deliberately introduced randomness in the generated sequence, by using a function that returns a random pitch every time it is called.

Here is the output:

Generated Pitches

Generated Pitches

I hope the discussion so far has given you an idea of what one can do with L-systems in Opusmodus. In fact, there are some advanced features that I don’t have time to discuss today. I am reserving that discussion for a future article. Stay in touch!

You can download the sample code here.

Have a great weekend!

Tags: , ,

Subscribe

If you enjoyed this article, subscribe now to receive more just like it.

Subscribe via RSS Feed

Leave a Reply

Your email address will not be published.

Top