on
sπ01: Making Techno Beats
This is the first post in a Series about Sonic Pi. It is intended for readers who have at least a little programming knowledge, but doesn’t assume any knowledge about music. It is not a tutorial in the usual sense, but more of en exploration of different aspects of electronic music and how they can be implemented in Sonic Pi. For infos about what Sonic Pi is and how to set it up on your computer see the 0-th post.
The live_loop
Most programming languages have pretty much the same control flow elements: if
, for
, while
, etc.
These are also present in Sonic Pi, but it also introduces something new: the live_loop
.
This is a control flow feature specifically for live coding.
It goes like this
live_loop :loop_name do
# your code
end
Features of live_loop
s
- Your code runs in an endless loop. When you redefine the loop by evaluating the code again, the new version will be used in the next iteration. This way you can change the content of the loop on the fly without interrupting the flow of the music.
- Each
live_loop
runs in its own thread. The code after thelive_loop
definition will run immediately after updating the thread, which usually takes no significant time at all. This way you can have as many live loops as you wish running in parallel. - Live loops send
cue
s for syncing with otherlive_loop
s at the beginning of each iteration. This way you can have precise timing without having to be too precise with the numbers. - Each
live_loop
has its own context.tick
s for example are per loop. This way you don’t have to fear overwriting state in other loops.
Techno Beats
Techno is pretty easy to implement, because there are some basic patterns, to which we can fall back to if we’re not feeling creative. The classic techno beat for example is in a 4/4 measure, where base drum or kick plays on every beat (“four on the floor”). This is simple enough in Sonic Pi:
use_bpm 150
live_loop :drums do
sample :bd_haus
sleep 1
end
This will play the sample bd_haus
that comes with Sonic Pi and wait one beat on every loop.
The first line use_bpm 150
sets the beats per minute to 150 which makes everything a little faster.
The default would be 60 bpm, so one beat per second.
Next we add cymbals in the off beat:
live_loop :drums do
sample :bd_haus
sleep 0.5
sample :drum_cymbal_closed
sleep 0.5
end
Already sounds like something.
But it would be better to have an open cymbal.
Unfortunately the drum_cymbal_open
is a bit too much.
You can try to just replace the sample as it is, but the cymbal will overshadow everything.
We have to cut it to a manageable length and amplitude.
sample :drum_cymbal_open, sustain: 0, release: 0.2, amp: 0.3
Compare the sound of it to the closed cymbal, maybe a few time on its own, outside the loop, and then inside the loop. Things often sound different in context.
What happened here is that we changed the ‘envelop’ of the sample, the pattern with which the sound changes in volume over time. The default envelop for a sample is just a constant volume for its full duration. This makes sense because most samples already have a balanced sound. The period of constant volume is called sustain. There can also be a period before that, in which the volume increases linearly from zero to some value, in a time span called attack, and one after, where it decreases to zero again, called release. One can best observe the effect by playing a note with very long attack/release phases.
play :c4, attack: 3, sustain: 0, release: 3, amp: 0.3
Try playing around with the values.
For example what happens if you set the release to 0
?
The next step is to add a snare on every second beat. This could be done by just copying the four lines and adding a snare directly after the base drum, but since we are using a full fledged programming language, we can take a shortcut.
live_loop :drums do
sample :bd_haus
if tick%2 == 1
sample :drum_snare_hard, amp: 0.5
end
sleep 0.5
sample :drum_cymbal_open, sustain: 0.0, release: 0.2, amp: 0.3
sleep 0.5
end
Custom samples
The samples that come with Sonic Pi are a good start, but they aren’t perfect. You may want to bring in some extras, maybe create your own collection. One that I use quite often is a clap snare that can replace the snare in the drum loop above. There are lots of samples online, maybe look for one under a Creative Commons licence.
This can easily be done by placing your samples in a directory and using sample "path/to/dir", :sample_name
,
where sample_name
is just the filename without extension.
Here is what that looks like in the wild. I also added an extra twist by playing the base drum one more time every eight beats and a closed cymbal that plays with the base drum.
use_bpm 150
live_loop :drums do
sample :bd_haus
sample :drum_cymbal_closed, amp: 0.5
if tick%2 == 1
sample "~/lib/samples", :drum_clap
end
sleep 0.5
if look%8 == 7
sample :bd_haus
end
sample :drum_cymbal_open, sustain: 0, release: 0.15, amp: 0.2
sleep 0.5
end
Listen:
Feel free to play around with this. Maybe you want the extra base drum only every 16 beats. The release on the open cymbal could be a bit shorter.
Synths
In addition to the drums techno music usually has a lot of synthesizers in it. Here are two patterns that can be heard quite often.
We can use the use_synth
command to switch to a specific synth
and this change will be persistent for all play
commands within the live_loop
.
For a list of synths and what they represent, have a look at the documentation.
I often use use_synth_defaults
so that I don’t have to repeat options for every play
.
It also understands the options we used for the cymbal sample: amp
, attack
, sustain
, release
and many more.
As a musical background we can play octaves of the same tone in a loop, varying every 8 iterations or so.
Here is an example were we define a function octave
with the define keyword,
that takes a note n
as a parameter and plays first the note itself, then the one 12 halftones (one octave) above.
live_loop :octaves do
use_synth :tb303
use_synth_defaults amp: 0.5, sustain: 0.1, release: 0.05
define :octave do |n|
play n
sleep 0.25
play n+12
sleep 0.25
end
8.times do
octave :e2
end
8.times do
octave :g2
end
end
In techno there is usually a catchy melody in the foreground.
If we don’t feel like composing one right now,
we can let the computer do the job for us.
In Sonic Pi it is common to use randomness to generate something less monotonous than what we have heard so far.
It is really easy to get a nice sound by randomly choosing notes from a pentatonic scale using the choose
method.
live_loop :lead_synth do
use_synth :dsaw
use_synth_defaults release: 0.3, sustain: 0.2, amp: 0.6
use_random_seed 42
notes = (scale :e2, :minor_pentatonic, num_octaves: 2)
16.times do
play notes.choose
sleep 0.5
end
end