A couple of posts back I highlighted how in one way you are better at maths than a computer (You are Better at Maths Than a Computer). And now it appears my computer hasn’t taken this well and has now decided to humiliate me at something I like to do, playing the drum kit.
Sonic Pi
Today I spent a day pratting around with the absolutely amazing Sonic Pi (Sonic Pi). Sonic Pi is a code-based music creation and performance software. It allows you to write code that plays music within its own framework. It is such a fun tool both for learning to create music and learning to code, and I like both this was right up my street.
Creating a Drum Machine
Sonic Pi has a window where you write code in block statements (similar to the Ruby programming language), it has in build methods for playing sounds, measuring time etc.. and comes with a library of samples and synths that can be used. and it is free!
How Does this Work
Firstly, you download and install sonic pi, it comes with a great tutorial for explaining the basics. but to summarise it at a very high level – you have a window for writing code and a way of playing / recording the sound produced from this code. For example the following code (at 60bpm) will play a kick drum every 2 seconds.
which would sound like this.
Creating a Drum Machine
In order to create a drum machine, we first need to think about how the drums work in relation to music. I actually play the drumkit so I had a bit of a head start here, and obviously this topic is a lot wider than I am about to explain. So let’s assume some basics with our drum machine;
- We will play with 4 beats in a bar (4/4 time signature)
- I will support values that fall in the 16th note grid.
Do not worry if those concepts make no sense to you, I am just limiting what the drum machine will be capable of to rhythms and signatures that we are most used to (pop, rock music etc..)
Let’s take these limitations and make a grid – we have up to 16 notes in our bar of music and 4 beats. We also want to have the most basic elements that make up a drum kit – a kick drum, a snare drum and a hi-hat;
we could then plot the drums we wish to play at the point we wish to play them. For example, the following grid
could be represented in music notation as
We will try to code this initially.
Coding the Machine
So how are we going to code this? Firstly, we want something to loop over our settings and play this continuously then we will need some collections for each of the three instruments to tell them at what point to play their samples.
These values are populated into the arrays as follows;
what we need to do now is to loop the length of the array (16 positions) and if the value is 1 in any of the positions play the relevant drum, this is amazingly easy to handle in sonic pi.
the code documented played as audio would sound like the following.
At this point – with this little code we have a basic drum machine!
we can add more instruments in by adding new arrays – for example we might want to add the left foot of the drummer in (controlling the high-hats).
Examples
Below are some examples of using this code – the underlying code is exactly the same, just changing the values in the arrays telling them when to play and changing the tempo/samples used to make them more appropriate for that style of music.
Bosa Nova
Drum and Bass
You may notice the Number 2 is contained in some of these patterns – this represents a secondary snare sound (in this case a quieter one) and allows more instruments of their designated type to be handled in the array – the code below is an example of this;
Punk
Soukous (Congolese drum groove)
House/EDM Music
Funk
Extending the Drum Machine – Drum Fills
OK quite impressive, but these are just repeated beats? is the computer actually better at me at this point? I mean sure it makes less mistakes but it is less creative. It can’t play any improvisation… or can it?
Often drummers will play a repeating section of music (a groove) for a fixed number of bars usually 4 or 8 then they will add in a Fill a different bar of music before they start playing the next section of the song. Obviously, we could just use the same arrays and make the drum machine play something different – but that isn’t improvising, for that we need an element of randomness;
Linear Fills
Linear fills are whereby a drummer will play a series of notes where no two notes are played together at the same time, using this approach we wouldn’t need multiple arrays to contain the drums we wanted to play – only one as no two sounds would be played together at once.
The Linear Fill Function
we could write a function that populate an array from a list of sounds randomly. and then iterate and play those sounds, because the sounds are randomly picked we wouldn’t know at runtime what the fill would sound like, but we would know it would be perfectly in time. To that extent the computer would be an improvising musician! Consider the function below;
we call the function calling a random seed between 0 and 100. The linear fill is then played and the code returns to the top of the loop with a splash value of 1 (meaning the first drum beat after the fill that ends is a cymbal splash).
Let’s set up a sweet groove.
You might notice a value of 2 in the last hi hat beat, much like we saw earlier for the snare this is a different sound and represents the opening of the hi hat.
now let’s listen to a couple of iterations of this at 95bpm. Note how the fill is not the same, it is randomly selected.
Not bad for a few lines of code!
Extending the Drum Machine – Additional Limbs
OK…. OK. So now the computer can drum perfectly in time and improvise, I get I might be out of a job here, but I still think I could just about compete with it. The final nail in the coffin for me vs the computer is that I have four limbs, where as the computer doesn’t… lets go back to our drum groove arrays and add a third hand array;
This array contains various bongo and snap type sounds. No one person behind a drum kit could play all these sounds like for like – at various points 3 drums are being hit at the same time – an impossibility with just one drummer.
you can see the array positions we have entered above but below is a more readable grid.
Adding Synths
So basically yeah… the computer is miles better at drums than me. But it’s not limited to drums (that just happens to be what I know best). we could easily add a function to play some synth notes.
this function uses a modulo calculation (the remainder from a divide) to play synth notes ever mth note within the grid. We have specified that the notes will come from the E Major add11 chord but be randomly selected between piano keys 60-72. if we add this on top of the previous track we would have the following;
Live Coding
One amazing feature about this software is the using the live loop keyword you can update the code as the loop is playing allowing you to make changes to the tracks (changing synths beats etc… without stopping the music). Infact some programmers/musicians have done live DJ sets armed with just this application. The creator of sonic Pi Sam Aaron has sets on youtube (Sam Aaron live coding an ambient electro set w/ Sonic Pi – YouTube). Here is an example of this functionality with me adding different drum layers over time – in real time. It sounds complicated, but because of how I coded this I am simply changing the values in the arrays to play different beats at different times.
Conclusion
Despite the fact it is now apparent my computer is a better drummer than me this is one of the most fun afternoons of mucking about with code I have had in years, if anyone has an interest in both music and coding I recommend they install this and play about, it’s is remarkably easy to pick up and play sounds – to make a masterpiece obviously is still going to take some time, but you can very much learn by doing. What is scary is I feel this was quite a comprehensive post about Sonic Pi – in reality I simply scratched the surface of the functionality on offer, and it’s incredible it is open source and free to use. I suspect I will lose many more afternoons playing around on this!
The Sonic Pi Code demonstrated in this post is available in GitHub: SonicPi (github.com)