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_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