It’s been too long since the last algorithmic composition post, but a series of new posts are on the way!
To kick things off we’ll revisit one of our previous Markov chain algorithmic compositions. Previously we looked at first order Markov chains in PureData. We also extended this into a second order Markov chain in Max.
Let’s have a quick recap first.
First Order Markov Chains
In a previous Algorithmic Composition post we built a first order Markov Chain analysis and generation patch. In 1st order Markov chains the next note is based on the current note and a list of probabilities for following notes. This is stored in a State Transition Matrix (STM), here’s an STM that lists the notes of Happy Birthday and the probabilities of each subsequent note.
Second Order Markov Chains
Second order Markov Chains choose the next note based on the two previous notes and the probability of subsequent notes following those two notes:
Creating 2nd Order Markov Chain Analysis and Generation in PureData.
1. First complete the steps to create a first order Markov chain in Pd. Your main patch window should look something like this:
2. In order to modify our patch to perform a second order analysis we need to make a couple of small changes to our ‘pd markovMIDIAnalysis’ and ‘pd markovPitchGenerate’ subpatches.
Second order markov chains base the next note on the previous two notes and the probabilities of other notes following those two notes in sequence. We therefore need to store the two notes as our index.
We’ll modify our analysis and composition patches to store and access these two notes together e.g. 60 60 becomes 6060, 72 69 becomes 7269 etc. Inside ‘pd markovPitchAnalysis‘ modify the ‘pd pair’ subpatch to look like this:
When we implemented a 2nd order Markov chain in Max we used the ZL stream object, unfortunately this isn’t implemented yet in PureData however the following subpatch does the same job. The contents of your ‘pd zl-stream’ subpatch should look like this:
3. We’ve now completed the analysis part of our 2nd order patch. Finally modify the ‘pd markovPitchGenerate’subpatch to look like this:
Load up a MIDI file and you’re all set to be generating 2nd order Markov Chain compositions in PureData. A further interesting thing to try is to use multiple named coll objects each with a different piece of source music in each and transition between them.
You can hear some example output from this second order Markov chain here
It’s also good to try implementing first order Markov chains for rhythm generation too.
A new series of algorithmic composition tutorials will be coming up over the Summer, so bookmark and check back soon for more algorithmic composition tutorials for Max, Pd, OpenMusic and more