Sonic Pi: Basics
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!