We've looked at using OpenMusic for algorithmic composition in a number of posts before, we've also looked at using the OpenMusic OMalea library and random walks in OpenMusic. Today we're going to use OpenMusic and OMalea to work with Markov Chains.
Markov Chains are a very useful tool for the algorithmic composer, we've looked at Markov Chains in keykit here. If you're not familiar with how Markov Chains work it's definitely worth reading this algorithmic composition post.
In brief, Markov Chains chose the next note using a probability. For example if the current note is E, there might be a 70% chance of the next note being a A and a 30% chance of it being an C#. These probabilities are stored in something called a transition table or transition matrix.
This is the approach we'll take in today's post. We'll load up a MIDI file, create a transition matrix from this using the ana-mark function, and then generate new melodies based upon this.
1. First of all we need to load up a MIDI file. Create a new class MIDIfile, either by choosing from the menu or CMD clicking (CTRL click on PC) and typing midifile.
2. Evaluate the midifile class by hitting the 'v' key or CMD clicking on it's output (CTRL click on PC). This will allow you to load up a MIDI file, once it's loaded make sure the midifile class is selected and press b to lock it. This will ensure that you don't have to load the MIDIfile every time you evaluate the patch.
3. We next have to extract the pitch data from the MIDI file. We can also use markov chains to generate rhythm, dynamics and other musical information, but for now we'll stick with pitch. Add a mf-info function, this allows to extract each note from the MIDI file.
((64 1000 500 52 1) (73 1500 385 58 1) (74 1875 125 43 1) (62 2000 500 32 1))
5. We need to access just the first element of each set of parentheses: the pitch. There are a number of ways we can do this, but the simplest is to use the mat-trans function followed by the first function. Add these in one a time and evaluate them to see what they do. You patch should now look like this:
6. Now when we evaluate our patch we get a list of pitches. This can be fed into the ana-mark function (remember you need the omalea library enabled to be able to use this function - this can be turned on in preferences if it's not already).
((list-of-pitches ((first-pitch-probabilities) (second-pitch-probabilities... ... (last-pitch-probabilities)))
Something like this:
((1 2 3) ((0.0 1.0 0.0) (0.333 0.0 0.667) (0.0 1.0 0.0)))
7. We need to be able to separate our list of pitches, the first element in the list [ (1 2 3) in the above example ] from the list of probabilities [the second element in the list]. For this we can use the Lisp functions first and second. You can type first and second directly into a new box to create them, or create them from the drop down menu. So far our patch looks like this:
Markov chains and algorithmic composition.
You can also try using the Markov chains to generate elements of your CSound scores as looked at in the post on algorithmic composition, OpenMusic and CSound - using the om2csound library.
Check back soon for more algorithmic composition techniques and tutorials.