Today we're looking using Markov Chains in OpenMusic to generate rhythmic patterns for algorithmic compositions.
Our previous OpenMusic tutorial used these functions from OpenMusic's OMalea library:
- ana-mark to analyse a MIDI file to create a transition table of pitches and
- markov1 to generate a new algorithmic composition based on the transition table.
Algorithmic Composition: Rhythm
Each note has two rhythmic properties: the note onset and the note duration. If we're representing our rhythms as absolute time in milliseconds (ms) it's important when analysing an existing MIDI file to do some pre-analysis work on it. For the purposes of building our Markov transition table, all note onsets and durations should be carefully quantized and all tempo changes removed. It's also useful to use a single tempo of 60 BPM.
Using a tempo of 60 BPM means that the durations are consistent, easily divisible and easy to read
Whole note = 4000
1/2 note = 2000
1/4 note = 1000
1/8 note = 500
1/16 note =250
etc
This does not mean that you can only produce music at 60BPM as it is very easy to change the tempo later for example, halving the onset time and duration of each note would double the tempo. Using a consistent tempo means that you can create your transition table from multiple pieces of music.
If you don't quantize the music before analysis, we may have many different similar values for note durations. All of these durations might sound like 1/8th notes 506 498 502 490 513, however as they are different values they won't be treated as equivalent in our Markov analysis.
Before analysis:
- Load your MIDI file(s) into a sequencer and carefully rhythms, ensure that you quantize note onset, note on and note off.
- Remove tempo changes and set the tempo to 60BPM.
The note list from a MIDI file in OpenMusic is output in the following order:
1. Pitch
2. Onset
3. Duration
4. Velocity
5. Channel
Previously we used the Lisp first function to analyse only the pitches of our MIDI file and to generate an algorithmic composition like this:
Rather than taking the first value (pitch) we can take the third (duration) to analyse and algorithmically compose a rhythm from the Markov chain of the input durations:
We can perform a Markov analysis on both the pitches and durations and the algorithmically generate some new musical examples based on these analyses:
OpenMusic OMTP Library
The examples above use the OMalea library to analyse and generate algorithmic compositions based on Markov Chains. Paul Nauert's OMTP library also includes some Markov functions, these are specifically designed as rhythm tools. In preferences ensure the OMTP library is enabled:
In this first example, we work use the m-rhythm function from the OpenMusic timepack library (OMTP):
To start with we'll generate a simple algorithmic composition using a zero order Markov chain. Zero order Markov chains base their next choice only on a set of probabilities and do not consider what the previous event was.
The inputs to the m-rhythm function are as follows:
- A list of possible rhythms
- The probability of each rhythm occuring
- A target length in bars
- An initial condition for the Markov Chain.
To make the output a little more interesting we'll add an n-cercle class to our patch:
The n-cercle class is usually used as a representation of pitch classes, here we've a diminished scale into the n-cercle - double click the n-cercle to enter the editor.
We'll then choose some random pitch classes from our scale and combine this with our zero order Markov chain:
The p->mc function is from Nauert's other OpenMusic library OMPF.
To create a first order Markov chain using m-rhythm we create a nest list: a list of lists. Each sublist represents one rhythm and the probability of the other rhythms in the list following it:
In a similar way we can create a second order Markov chain by having a deeper nested list:
It's possible to create any order Markov chain using m-rhythm by using nested lists.
In forthcoming algorithmic composer tutorials we'll explore in more depth OpenMusic and the OMTP and OMPF libraries, as well as exploring similar algorithmic composition ideas in MaxMSP, PureData, Common Music and other algorithmic composition software.
Subscribe to the RSS feed and check back soon for more algorithmic composition tutorials.
1 comment:
How do you make the first patch in this post a 2nd order markov chain?
Post a comment