1 |
Introduction |
2 |
|
3 |
This document describes a text based method of composing music, and outlines various methods for generating and controlling melody. |
4 |
|
5 |
Overview |
6 |
|
7 |
The textual composition system described here comprises three seperate levels. |
8 |
|
9 |
1. Text score language |
10 |
A simple text character based score system that is interpreted a character at a time. |
11 |
|
12 |
2. Lsystem score generator |
13 |
A rule based production grammar that generates score code |
14 |
|
15 |
3. Genetic programming |
16 |
A genetic breeder for Lsystem grammars that generate score code |
17 |
|
18 |
--------------------------------------------------------------------------- |
19 |
|
20 |
Lindenmayer Systems |
21 |
|
22 |
Lindenmayer Systems were invented in 1968 by biologist Aristid Lindenmayer, and are usually used to describe natural shapes which exhibit fractal geometry, such as plants. |
23 |
|
24 |
Lsystems (as they are often shortened to) are a type of formal grammar, which is a precice mathmatical descriptions of a language. Formal grammars can either be used as proofs that a set of strings are contained within a system, or used the other way around, as production rules to create strings. |
25 |
|
26 |
Lsystems are a form of the latter type of formal grammar, that allow us to build strings using the Lsystem as a description. Formal grammars consist of axioms, starting strings, and production rules - in Lsystems these are replacements from one token to another. |
27 |
|
28 |
Simple LSystem in action: |
29 |
|
30 |
Our Lsystem formal grammar: |
31 |
Starting string (axiom) : "A" |
32 |
Production rule 1 : Replace A with B |
33 |
Production rule 2 : Replace B with AB |
34 |
|
35 |
If we apply the rules multiple times, the string will expand, or grow as follows: |
36 |
|
37 |
Generation 0 : A |
38 |
Generation 1 : B |
39 |
Generation 2 : AB |
40 |
Generation 3 : BAB |
41 |
Generation 4 : ABBAB |
42 |
Generation 5 : BABABBAB |
43 |
Generation 6 : ABBABBABABBAB |
44 |
|
45 |
There are several aspects of the resultant strings that are interesting. Firstly, they contain quite a lot of emergent complexity, given the simple nature of the rules used to generate them. Secondly, they contain self similarity, which is why they tend to be useful for generating plant forms. This self similarity and nested behaviour is also beneficial for describing and generating musical note data. |
46 |
|
47 |
Musical representation |
48 |
|
49 |
The way an Lsystems rules are interpreted is entirely seperate to the grammar that was used to create them. In traditional Lsystems, they are used to parent and position three dimensional models to make a nice tree - but we can use them for anything. |
50 |
|
51 |
A simple musical score language |
52 |
|
53 |
o : play a note |
54 |
+ : current note pitch up one semitone |
55 |
- : current note pitch down one semitone |
56 |
|
57 |
So a score like this: |
58 |
|
59 |
o+o+o---o+o+o----o+o+o---o+o+o |
60 |
|
61 |
If you conside a sequencer playing the score one note at a time, it would be represented in a traditional piano roll sequencer something like this: |
62 |
|
63 |
o o |
64 |
o o o o |
65 |
o o o o |
66 |
o o |
67 |
|
68 |
So, we could use Lsystems rules to create this in the following way: |
69 |
|
70 |
Axiom: A---A----A---A |
71 |
Rule 1: Substitute A with: o+o+o |
72 |
|
73 |
Things start to get more interesting when we repeat the process, as in the first example. This allows use to use circular definitions in the rules to create recursive patterns. |
74 |
|
75 |
Axiom: A |
76 |
Rule 1: Substitute A with: o-B+B |
77 |
Rule 2: Substitute B with: AoA |
78 |
|
79 |
Generation 0 : A |
80 |
Generation 1 : o-B+B |
81 |
Generation 2 : o-AoA+AoA |
82 |
Generation 3 : o-o-B+Boo-B+B+o-B+Boo-B+B |
83 |
Generation 4 : o-o-AoA+AoAoo-AoA+AoA+o-AoA+AoAoo-AoA+AoA |
84 |
|
85 |
Which in our piano roll editor, would look something like this: |
86 |
|
87 |
o o ooo o |
88 |
o ooo o o o |
89 |
o o |
90 |
|
91 |
Let's run it for one more generation... |
92 |
|
93 |
Generation 5 : o-o-o-B+Boo-B+B+o-B+Boo-B+Boo-o-B+Boo-B+B+o-B+Boo-B+B+o-o-B+ |
94 |
Boo-B+B+o-B+Boo-B+Boo-o-B+Boo-B+B+o-B+Boo-B+B |
95 |
|
96 |
o o ooooo ooo |
97 |
o ooooo ooo ooo ooo |
98 |
ooo ooo |
99 |
|
100 |
(I think this is all correct, but I'm doing it by hand: todo - check :)) |
101 |
|
102 |
So you can see the great amount of complexity that arises from such simple rule systems. After a bit of practice you start to learn what different sorts of rules will sound like, but it's a very empirical and intuitive process. |
103 |
|
104 |
Note: the document refers to melody, but these rules can generate percussion patterns too, if you consider note frequencies to map to different percussion instruments. |
105 |
|
106 |
The Lsystem vs the score code |
107 |
|
108 |
A very important thing to state here is that there are two seperate systems going on here. The musical score system (how the symbols are interpreted) is _not_ the Lsystem. The Lsystem comprises the rules used to create code that is interpreted as music. The musical score is really just a side effect of the Lsystem growing it's string. In other words, the Lsystem does not know or care what the symbols mean, it just produces strings of them. |
109 |
|
110 |
A better musical representation |
111 |
|
112 |
The previous examples used a very basic form of notation, there are many musical things it can't represent, so we'll extend it a little. |
113 |
|
114 |
Firstly the prevous system only dealt with notes and pitch changes, no rests or simultaneous notes, so no chords. If we incorporate a new symbol "." as a rest, we can change the rules a bit. |
115 |
|
116 |
Now the sequencer will only rest when it reads a "." in the score, so we can trigger notes at the same time. |
117 |
|
118 |
o.o.o.o |
119 |
|
120 |
Will play four notes in sequence. This however: |
121 |
|
122 |
o+o |
123 |
|
124 |
will now play the two notes at the same time, one higher by a semitone than the other. |
125 |
Another symbol we'll add at this point is the "!" which resets the current pitch to a predefined root value (this value comes from out of this system, but for now we will take it to be middle C4) So now we can start talking about things in a more musical language: |
126 |
|
127 |
!o++++o+++o |
128 |
|
129 |
Will play a C major chord (consisting of C4,E4 and G4 where the root note is C4) |
130 |
|
131 |
!o++++o+++o...!+o++++o+++o... |
132 |
|
133 |
Will play C major chord, rest for 3 beats and then play C# major (C#,E# and G#) |
134 |
Also, we'd like to be able to pan around the stereo field - so we also add three more symbols for that: |
135 |
|
136 |
'/' : pan right |
137 |
'\' : pan left |
138 |
'|' : center pan |
139 |
|
140 |
The pan position works in the same way as the pitch, in that this: |
141 |
|
142 |
/o./o./o./o./o./o./o./o. |
143 |
|
144 |
Will play a series of note all panned slightly right of each other. When it reaches full right pan, the note will flip to full left pan, so the note will appear to continuously move from left to right. |
145 |
|
146 |
Genetic Programming: an Lsystem breeder |
147 |
|
148 |
Genetic programming is a method of automatic programming, where you grow a program by it's suitablility to fix a certain problem. Firstly a population of candidate programs are generated (usually randomly) and scored based on how well they solve the problem. The best ones are picked and used to generate a new population of candidates. The process continues until a suitable program results. |
149 |
|
150 |
The genetic programming discussed here is a somewhat specialised version of this. Firstly the guidance of which program is more suitable is driven by the player, so there is no automatic selection. Also in traditional GP there are usually hundreds of programs in a population - here, to simplify the choice for a human player, there are only 4. |
151 |
|
152 |
The genetic programming breeder can also pick up an lsystem originally written by the player and evolve it further, where it may agan be further modified by the player. |
153 |
|
154 |
First we write a simple scorecode lsystem that creates a nice melody: |
155 |
|
156 |
!1 |
157 |
2---2---2---2---2 |
158 |
o.+o.+o.2.2 |
159 |
|
160 |
Which after 2 generations expands to: |
161 |
|
162 |
!o.+o.+o.o.+o.+o.2.2.o.+o.+o.2.2---o. |
163 |
+o.+o.o.+o.+o.2.2.o.+o.+o.2.2---o.+o. |
164 |
+o.o.+o.+o.2.2.o.+o.+o.2.2---o.+o.+o. |
165 |
o.+o.+o.2.2.o.+o.+o.2.2---o.+o.+o.o.+ |
166 |
o.+o.2.2.o.+o.+o.2.2 |
167 |
|
168 |
The Lsystem breeder can now be used to generate mutated versions of this parent program. |
169 |
There are now 3 mutated versions of this melody to audition, namely: |
170 |
|
171 |
!o.+o-+4.o.+o-+4.2.\.\---o.+o-+4.o.+o |
172 |
-+4.2.\.\---o.+o-+4.o.+o-+4.2.\.\!|-o |
173 |
.+o-+4.o.+o-+4.2.\.\-.-o.+o-+4.o.+o-+ |
174 |
4.2.\.\ |
175 |
|
176 |
!\.+o.+o.\.+o.+o.2.2.\.+o.+o.2.2---<- |
177 |
--\.+o.+o.\.+o.+o.2.2.\.+o.+o.2.2---\ |
178 |
.+o.+o.\.+o.+o.2.2.\.+o.+o.2.2+--\.+o |
179 |
.+o.\.+o.+o.2.2.\.+o.+o.2.2 |
180 |
|
181 |
!o.+oo.+o1+o.4.2---o.+o1+o.4.2--.o.+o |
182 |
1+o.4.2---o.+o1+o.4.2---o.+o1+o.4.2+o |
183 |
.4.o.+o1+o.4.2---o.+oo.+o1+o.4.2---o. |
184 |
+o1+o.4.2--.o.+o1+o.4.2---o.+o1+o.4.2 |
185 |
---o.+o1+o.4.2+o.4.o.+o1+o.4.2--.o.+o |
186 |
o.+o1+o.4.2---o.+o1+o.4.2--.o.+o1+o.4 |
187 |
.2---o.+o1+o.4.2---o.+o1+o.4.2+o.4.o. |
188 |
+o1+o.4.2---o.+oo.+o1+o.4.2---o.+o1+o |
189 |
.4.2--.o.+o1+o.4.2---o.+o1+o.4.2---o. |
190 |
+o1+o.4.2+o.4.o.+o1+o.4.2---o.+oo.+o1 |
191 |
+o.4.2---o.+o1+o.4.2--.o.+o1+o.4.2--- |
192 |
o.+o1+o.4.2---o.+o1+o.4.2+o.4.o.+o1+o |
193 |
.4.2 |
194 |
|
195 |
Whether these are good or bad is entirely up to you, patterns can be auditioned or selected to make a new generation. The idea is to throw caution to the wind and play it live, like an |
196 |
instrument. |
197 |
|
198 |
When you one that's cool (perhaps the big long one above) you can edit the code responsible. |
199 |
|
200 |
!1 |
201 |
2---2--.2---2---2 |
202 |
o.+o1+o.4.2 |
203 |
|
204 |
All this mutation has really done to make the result much longer, is insert a |
205 |
1 in the second rule, meaning there is much more recursion going on each generation - making a much longer score. |