CyberSpy

Rantings from a guy with way too much free time

Generating Music with Formal Grammars

2017-10-19 Musings

What’s your Grammar Know about Music?

Well, not your Grandma, but grammar, a field of computer science that formalizes language theory. For those unfamiliar with the topic, it’s a bit similar to the grammar lessons that tortured you in grade school, except with a twist of math!

Why do we care about grammars when we are contemplating generating music algorithmically? It turns out using a special type of generative grammar known as an L-system is a great way to programmatically create our compositions. In the last post, one of the academic papers discussed this technique. Here, I’ll summarize some of that discussion and develop examples which we can use for our compositions.

Introduction to L-Systems

L-Systems are types of formal grammars known as a parallel rewriting system. We define an alphabet, and production rules on that alphabet which transforms our alphabet according to these rules. The rules are typically recursive and result in transforming strings from shorter sequences to longer ones through the replacements. Many of these systems resemble biological cell growth models in plants and were motivated from such by Aristid Lindenmayer who was a botanist.

Because of the recursive nature of L-Systems, they tend to have self-similar, or fractal-like, properties. Complexity arises as we iterate the number of replacement cycles. Each cycle creates a further dimensioned transformation that adds complexity to our sequence.

Let’s look a a simple example to get a feel for how we define an alphabet and a replacement ruleset:

  • variable: $A, B$
  • axiom: $A$
  • rules: $(A \to AB), (B \to A)$

Our alphabet consists of ${A, B}$. We define $A$ as an axiom. And we define two replacement rules, $(A \to AB), (B \to A)$.

So if we start out with our axiom, $A$, let’s see what we’d generate after $n=5$ iterations.

  • $n=0:$ $A$
  • $n=1:$ $AB$
  • $n=2:$ $ABA$
  • $n=3:$ $ABAAB$
  • $n=4:$ $ABAABABA$
  • $n=5:$ $ABAABABAABAAB$

A few observations. What do you notices about the growth property of this L-System? Turns out it’s a Fibonacci sequence. Recall in my post on the golden ratio that this sequence often arises in biological and other growth systems.

Secondly, what does any of this have to do with making music? Well, how we choose to interpret our generated strings and map our alphabet to musical structures ultimately results in composition.

Let’s see if we can make this more tangible. Here’s a great paper by Stelios Manousakis that describes using many different types of L-systems at length for music generation. Stelios exhaustivly enumerates many variations on both L-System grammars as well as interpretation models on those grammars. I will only be superficial here so as to show the workflow. I’ll leave it up to you (the invisible reader) to experiment with more sophisticated grammars and interpretational overlays.

So for first crack at an interpretation, let’s create the following mappings:

Melodic Mapping:

  • $A$ $a-c-e-g$
  • $B$ $g-e-c-d$

where $a$ through $g$ are the notes in the major scale.

Rhthmic Mapping:

  • $A$ $q,t-t-t,e-e-e-e,q$
  • $B$ $t-t-t,e-e-e-e,t-t-t,q$

where $q$ is a quarter note, $t-t-t$ is a triplet, and $e-e-e-e$ are four eighth notes.

To implememt our mapping, we could first convert our L-System String into a rhythm, and then map a melody into the generated rhythmic string.

Given the sequence $ABAABABAABAAB$, let’s construct an implementation.

#!/bin/bash

PATTERN1="q t t t e e e e q "
PATTERN2="t t t e e e e t t t q "
echo "$1" | sed -e "s/A/$PATTERN1/g" -e "s/B/$PATTERN2/g"

If we run our script, on our generated string, $ABAABABAABAAB$ we’d generate a rhythmic pattern like:

sh ./rep.sh ABAABABAABAAB  | fold -60
q t t t e e e e q t t t e e e e t t t q q t t t e e e e q q
t t t e e e e q t t t e e e e t t t q q t t t e e e e q t t
t e e e e t t t q q t t t e e e e q q t t t e e e e q t t t
e e e e t t t q q t t t e e e e q q t t t e e e e q t t t e
e e e t t t q

Now that we have a rhythm, we can substitute our rhythmic placeholders with notes from our sequence.

All of this was notional. The patterns that we would use for both rhythmic and melodic substitutions presupposes an implementation for such representations.

Let’s pause now that we know the general ideas and take a look at a specific musical implementation that renders both melodic and rhythmic sequences that we can render to an audio device. Specifically, in my next post, we’ll look at expremigen.

comments powered by Disqus