Building a Breakbeat Drummer with Sonic Pi

- Posted in Music by

Not being able to play the drums and also not having much experience programming them, I need a high-level way of creating rhythms. So let's use Sonic Pi to make the machine take care of the hard part.

The Basic Idea

Here is what we are going to do: Let's randomly chop up the first bar of the Amen Break and assemble it into new patterns.

Moomin Holding Knife meme "Let's chop up that breakbeat"

We are going to use 8 slices - one for each cymbal hit.

The first bar of the Amen Break chopped into 8 slices

First Chops

So here is the code to create the 8 slices outlined above.

slices = 8  # number of slices
slice = 0  # try slices 0 to 7
start = slice  * 1.0/slices
sample :loop_amen, start: start, finish: start + 1.0/slices

Trying this you will get a nice kick for slice 0 and 1 - and a double kick for slice 5. The nice snare hits are - as expected - slice 2 and 6.

Randomized Chops

As a next step let's assemble a whole bar from 8 randomly selected slices. With use_sample_bpm one beat is defined as the length of one of our slices. So we just can do sleep 1 to wait for the next beat.

slices = 8
use_sample_bpm :loop_amen, finish: 1.0/slices
slices.times do
  start = (rrand_i 0, slices - 1)  * 1.0/slices
  sample :loop_amen, start: start, finish: start + 1.0/slices
  sleep 1
end

Looks like our basic idea is working.

Looping it

Whatever the random generator comes up with - we need to hear it again to make it feel like actual music. Repetition legitimizes. To make the bar repeat, we wrap it into a live loop and reset the random seed at the beginning of each bar. Thus the random generator will come up with the same numbers each time.

slices = 8
use_sample_bpm :loop_amen, finish: 1.0/slices
live_loop :drummer do
  use_random_seed 0
  slices.times do
    start = (rrand_i 0, slices - 1)  * 1.0/slices
    sample :loop_amen, start: start, finish: start + 1.0/slices
    sleep 1
  end
end

Composing with Seeds

This is a steady beat you can already play along with. But let's go one step further and compose beats by picking random seeds. Each bar gets's a number representing what is played. Here a simple 8-bar loop based on seed 21 that throws in a break on bar 4 and 8.

| 21 | 21 | 21 |  1 |
| 21 | 21 | 21 |  2 |

And here the code using knit() for shorthand:

rate = 0.7
slices = 8.0
song = knit(
  21, 3, 1, 1,
  21, 3, 2, 1,
)
use_sample_bpm :loop_amen, rate: rate, finish: 1.0/slices
live_loop :drummer do
  use_random_seed song.tick
  slices.times do
    start = (rrand_i 0, slices - 1)  * 1.0/slices
    sample :loop_amen, rate: rate, start: start, finish: start + 1.0/slices
    sleep 1
  end
end

As you will have noticed, we also added a way to set the tempo of the drummer.

Picking the good bars

Trying out random numbers is fun, but I am especially interested in bars starting with a kick. These are slice 0 and 1. Let's list the first few of these:

slices = 8
(0..100).each do |seed|
  use_random_seed seed
  start = (rrand_i 0, slices - 1)
  if start == 0.0 || start == 1.0
    puts seed
  end
end

So apparently I should try the seeds 3, 4, 8, 15, 21 …

More Things to Try

To wrap things up, here are a few ideas, what to explore when playing with this code:

  • Try 2, 4 and 16 slices.
  • Try a different :loop_*, not just the Amen Break.
  • Come up with a generative way to pick random seeds.
  • Write scripts to search for seeds producing bars with specific properties you are interested in.
  • Add rests.
  • Maybe even try crossfading chunks.

Moomin closing his knife

Meta

This blog has been very quiet, but at 38C3 I stumbled into a Sonic Pi workshop. This is where I pieced together the idea above and was reminded how much fun this is. More stuff has been in the pipeline for ages and will hopefully see the light of day soon.

Let’s play together — Syncing a Pocket Operator with Sonic Pi

- Posted in Music by

Live coding music with Sonic Pi and toying around with hardware mini synths such as Pocket Operators are both fun - but a very different kind of fun. But there should be a way to bring both together, right?

If you are reading this, chances are that you own more than one Pocket Operator. In this case you will be aware, that you can daisy chain these using a clock signal generated by the first PO in the chain. So wouldn't it be handy to generate such a clock signal using Sonic Pi?


The Click

Using a click to synchronize synthesizer units is basically done since the dawn of time - way before digital interconnection with MIDI. Even though this tutorial is exclusively talking about Pocket Operators, this will also work with a wide variety of other hardware providing a clock in.

Each PO has six sync modes, that provide a different configuration of the two input and output channels. For testing let’s use SY5 , that accepts mono/sync as input and also provides both as outputs. The clock input and output is always on the left stereo channel.

The Sync mode can be selected by repeatedly pressing chord + bpm. To access SY2-SY5 a cable needs to be plugged into the input jack on the left side.

flowchart LR
  CS:::hidden-- clock -->L
  AS:::hidden-- mono -->R
  subgraph Pocket Operator
    L:::left~~~L2[L]:::left
    R:::right~~~R2[R]:::right
  end
  L2-- clock -->L3:::hidden
  R2-- mono -->R3:::hidden

classDef hidden display: none;
classDef left fill:#fff,stroke:#000,color:#000;
classDef right fill:#ff0000,stroke:#000,color:#fff;

So how does this clock signal look like? The first thing we can do is plugging in a pair of headphones an listen to this sound not meant for human ears.

There it is: A pulse on each eighth note. This is interesting considering the fact that the PO provides sixteenth note resolution. When turning up the swing parameter of the sequencer you can even hear the clock starting to shuffle a bit.

Set the swing by pressing bpm and turning the A knob.

The PO with a stereo splitter attached to the output. The white channel is connected to another cable.

The clock ticks sounds like some very short pulse with steep flanks. So let’s record the signal to learn more about the shape of a click. Any recording program will do. To separate the two stereo channels coming out of the mini headphone jack, you can use a stereo splitter cable that provides two mono headphone jacks. The left channel is the white one.

So there are the peeks we are looking for:

The flanks are as steep as it gets and the wave does not go below 0. So we are looking at a very primitive, unipolar digital protocol.

Making our own clock

The PO with a stereo splitter attached to the output. The white channel is connected to another cable.

So it’s time to fire up Sonic Pi to get our hands dirty. We are going to need some sharp click noise on each eighth note. A first, naïve try could look like this:

live_loop :clock do
 sample :drum_snare_hard, amp: 3
 sleep 0.5
end

Sonic Pi counts in quarter notes. So playing a loud snare sound each half quarter note should do what we want — if the snare sample is able to trigger a clock tick. Let's connect the Computer and the PO to find out.

flowchart LR
    subgraph Computer
      L00[L]:::hidden~~~L0[L]:::left
      R00[R]:::hidden~~~R0[R]:::right
    end

    L0-- clock -->L

    subgraph Pocket Operator
      L:::left~~~L2[L]:::left
      R:::right~~~R2[R]:::right
    end

    classDef hidden display: none;
    classDef left fill:#fff,stroke:#000,color:#000;
    classDef right fill:#ff0000,stroke:#000,color:#fff;

So how does it perform? Our little snare clock is indeed able to make the Pocket Operator play the next two sixteenth notes of its pattern, but it doesn’t do this reliably. Cranking up the volume of the computer seems to help getting fewer dropped ticks, but we still don’t get a full measure without an issue.

So we now have to do some serious engineering™️ and try out a bunch of other built-in samples. Since we are using a live_loop, cycling through samples is pretty convenient. As it turns out,:bd_808 , the 808 kick, triggers perfectly. Somewhat surprising, but once more the 808 proves to be the superior drum machine.

So here is the updated code to generate a synthesize clock signal:

use_bpm 80
live_loop :clock do
 sample :bd_808, amp: 3
 sleep 0.5
end

If it doesn’t work in your setup, make sure, that the output volume of your audio interface is high enough, but not clipping. Actually listening to the clock signal can help to figure out what might be wrong.

Playing together

The "Now kiss!" meme with Sonic Pi and the PO getting closer.

To wrap things up, let’s finally add a simple drum pattern generated by Sonic Pi. The PO will beep and burp perfectly in sync with this beat.

use_bpm 80

# Eighth note clock pulse on left channel
live_loop :clock do
 sample :bd_808, amp: 3, pan: -1
 sleep 0.5
end

# Some drum pattern on right channel
drums = [
 :drum_bass_hard, nil,
 :drum_snare_hard, nil,
 :drum_bass_hard, :drum_bass_hard,
 :drum_snare_hard, nil,
].ring
live_loop :drums do
 sync :clock
 sample drums.tick, pan: 1
end

As you will notice, the :clock loop is fully panned to the left side and the :drums loop to the right. And since the drum loop is synced to the clock loop, we do not need to sleep.

To join the two audio sources, some kind of mixer needs to be added to the setup.

flowchart LR
    subgraph Computer
      L00[L]:::hidden~~~L0[L]:::left
      R00[R]:::hidden~~~R0[R]:::right
    end

    subgraph Pocket Operator
      L:::left~~~L2[L]:::left
      R:::right~~~R2[R]:::right
    end

    subgraph Mixer
      1~~~L4[L]:::left
      2~~~R4[R]:::right
    end

    L0-- clock -->L
    R2-- mono -->1
    R0-- mono -->2

    classDef hidden display: none;
    classDef left fill:#fff,stroke:#000,color:#000;
    classDef right fill:#ff0000,stroke:#000,color:#fff;

Aaaand it’s done. That wasn’t that hard. We are now able to run Sonic Pi and one or more Pocket Operators in sync. Time to jam — until we take this to the next level next time.

This is a revised version of an article posted on Medium in 2021.