Today we're looking using Markov Chains in OpenMusic to generate rhythmic patterns for algorithmic compositions.
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
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.
- 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:
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:
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):
- 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:
We'll then choose some random pitch classes from our scale and combine this with our zero order Markov chain:
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 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.