Sonic Pi: Basics

  • Sonic Pi
  • Raspberry Pi
  • Ruby

I've been looking for a way to combine my programming skills with my musical background for a few years now. It wasn't until I started looking into the Raspberry Pi a few months ago that I found Sonic Pi, which is basically an IDE that lets you write code, specifically Ruby, to program sounds and create music. Very cool.

It's so cool that it comes pre-installed with the Raspbian operating system. So when I set up my Raspberry Pi, there it was. It's also available for other operating systems; I've been toying around with it on my MacBook.

I won't dig into the IDE's GUI since it's pretty self explanatory, but I do want to write about the basics of composing in Sonic Pi: writing notes, chords, and melodies, controlling the volume ("amplitude") and direction ("panning") of the sound output, and selecting basic sounds ("synths").

Playing Individual Notes

Sonic Pi makes it easy to play individual notes. You simply use the keyword play followed by a number. For example:

play 60

The number that follows the play keyword corresponds to the note that you want it to play. In this case, 60 is a C Natural. Specifically, it's probably the closest that Sonic Pi has to a Middle C.

Each individual number represents a musical half step. So if 60 is C Natural, then 61 represents C#:

play 61

D Natural is represented by 62:

play 62

And so on. You can also do microtones using decimals:

play 60.235

Different speakers and computers are capable of different things, but on my system the highest audible value is around 131. Honestly, this tone is kind of piercing and painful. On the opposite end of things, the lowest audible value is around 7, which is just a faint bassy blip. I have no idea what notes those are supposed to represent. I should also note, these were found just experimenting with the default beep synth. Different synths may have different audible ranges.

Playing Chords

Now that we know how to play individual notes, playing chords is just a matter of combining those individual notes and playing them together. For example, here is a pretty standard C Major chord:

play 60play 64play 67play 72

And here is a C Minor (Natural) chord:

play 60play 63play 67play 72

sleep and Melodies

By using the sleep keyword and a number, you can put space between notes; in this way you can produce a melody. Here is the C Major chord, broken up into a little arpeggio melody:

play 60sleep 1play 64sleep 1play 67sleep 1play 72

The number that follows the sleep keyword corresponds to a portion of the beat. If the tempo in the IDE is set to 60 beats per minute (60 bpm), then sleep 1 is a one beat or one second of space, sleep 0.5 is a half-beat or a half-second of space and 0.25 is a quarter-beat or a quarter-second of space:

play 60sleep 1play 64sleep 0.5play 67sleep 0.25play 72

We can also use sleep to put space between chords:

play 60play 64play 67play 72
sleep 2.28
play 60play 63play 67play 72

Volume (Amplitude)

You can control the volume, or amplitude of a note using the amp keyword, like so:

play 60, amp: 1

In Sonic Pi, an optional keyword like amp is referred to as an opt. You generally separate opts from the play directive (and other opts) with a comma, and they typically use a semicolon between the opt keyword and its value.

amp's default value is 1, so play 60 is the same as play 60, amp: 1.

amp: 0 represents silence:

play 60, amp: 0 ## No sound

You can go above 1 with values like amp: 2 or amp: 100, but Sonic Pi uses compression, and these greater values will likely clip and sound harsh. It's advised that you stick between 0 and 1, and use decimal values to achieve different volumes for different notes. Here is an example:

play 60sleep 0.2play 63sleep 0.2play 67, amp: 0.7
sleep 2
play 59, amp: 0.9sleep 0.09play 65, amp: 0.8play 67, amp: 0.5
sleep 2
play 58sleep 0.3play 62, amp: 0.6sleep 0.07play 65, amp: 0.6
sleep 2
play 56sleep 0.2play 62,  amp: 0.7sleep 0.1play 65, amp: 0.7

Direction (Panning)

Another opt that's available is :pan, which controls the panning of a sound, or the directional output of a sound in stereo. Basically, this opt determines if the sound comes out of the left speaker, the right speaker, dead center, or somewhere in between.

pan: -1 represents a sound that is panned fully to the left, so it only comes out of the left speaker:

play 60, pan: -1

pan: 1 represents a sound that is panned fully to the right:

play 60, pan: 1

pan: 0 represents a sound that is panned in the center, so equally between left and right. This is the default value for the pan opt:

play 60, pan: 0

play 60, pan: 0 is the same as play 60.

Since the full range for this opt is between -1 and 1, values greater than 1 or less than -1 will throw an error. However, you can use decimals to fine tune where in the panning spectrum you want the sound to come out:

play 60, pan: -1sleep 0.4play 60, pan: -0.6sleep 0.4play 60, pan: -0.3sleep 0.4play 60, pan: 0sleep 0.4play 60, pan: 0.3sleep 0.4play 60, pan: 0.6sleep 0.4play 60, pan: 1

Different Sounds (Synths)

So far we've only been using the default synth in Sonic Pi. This synth's name is beep, but we haven't specified that anywhere. The use_synth opt allows you to specify which synth you want Sonic Pi to use to play a particular note.

Select a synth with use_synth then a colon, then the name of the synth. All notes that follow that command will use that synth until another synth is selected:

use_synth :bladeplay 60play 64play 67play 72
sleep 1.5
use_synth :prophetplay 60play 63play 67play 72

You can also combine multiple synths at the same time:

use_synth :tb303play 38use_synth :dsawplay 50use_synth :prophetplay 57sleep 1use_synth :fmplay 55use_synth :tb303play 57
sleep 0.5use_synth :fmplay 54use_synth :tb303play 62

Put It All Together

So let's take all of these basics and put them all together into something fun. Here's a bit of the Clock Town Melody from Majora's Mask, transposed into Sonic Pi:

play 69sleep 0.5play 81sleep 0.2play 80sleep 0.2play 78sleep 0.2play 76sleep 0.2play 78sleep 0.6play 74sleep 0.6play 76sleep 0.5play 71sleep 0.2play 76sleep 0.2play 74sleep 0.2play 71sleep 0.2play 74sleep 0.4play 76sleep 0.2play 73

I'm going to use amp to put some decrescendos on some of the descending runs:

play 69sleep 0.5play 81sleep 0.2play 80, amp: 0.6sleep 0.2play 78, amp: 0.5sleep 0.2play 76, amp: 0.4sleep 0.2play 78sleep 0.6play 74sleep 0.6play 76sleep 0.5play 71sleep 0.2play 76, amp: 0.6sleep 0.2play 74, amp: 0.5sleep 0.2play 71, amp: 0.4sleep 0.2play 74sleep 0.4play 76sleep 0.2play 73

Now I'll add some bass in, using the chipbass synth, set to a little bit lower amplitude, just to accent the root notes of the melody:

use_synth :chipbassplay 57, amp: 0.2
use_synth :beepplay 69sleep 0.5play 81sleep 0.2play 80, amp: 0.6sleep 0.2play 78, amp: 0.5sleep 0.2play 76, amp: 0.4sleep 0.2
use_synth :chipbassplay 56, amp: 0.3
use_synth :beepplay 78sleep 0.6play 74sleep 0.6play 76
use_synth :chipbassplay 54, amp: 0.4
use_synth :beepsleep 0.5play 71sleep 0.2play 76, amp: 0.6sleep 0.2play 74, amp: 0.5sleep 0.2play 71, amp: 0.4sleep 0.2play 74
use_synth :chipbassplay 56, amp: 0.3
use_synth :beepsleep 0.4play 76sleep 0.2play 73

And just for a little bit of texture, I'll add in an ascending scale that uses the sine synth that pans from left to right as it ascends:

use_synth :chipbassplay 57, amp: 0.2
use_synth :sineplay 57, amp: 0.6, pan: -0.6
use_synth :beepplay 69sleep 0.5play 81sleep 0.2play 80, amp: 0.6sleep 0.2play 78, amp: 0.5sleep 0.2play 76, amp: 0.4sleep 0.2
use_synth :chipbassplay 56, amp: 0.3
use_synth :sineplay 59, amp: 0.6, pan: -0.2
use_synth :beepplay 78sleep 0.6play 74sleep 0.6play 76
use_synth :chipbassplay 54, amp: 0.4
use_synth :sineplay 62, amp: 0.6, pan: 0.2
use_synth :beepsleep 0.5play 71sleep 0.2play 76, amp: 0.6sleep 0.2play 74, amp: 0.5sleep 0.2play 71, amp: 0.4sleep 0.2play 74
use_synth :chipbassplay 56, amp: 0.3
use_synth :sineplay 64, amp: 0.4, pan: 0.6
use_synth :beepsleep 0.4play 76sleep 0.2play 73

And there you have it. I hope you enjoyed this little Sonic Pi intro, I definitely had a lot of fun writing it and composing these examples. In the next few weeks I'll continue my exploration of Sonic Pi, so stay tuned!