Sonic Pi: Samples
We continue with our journey into the world of Sonic Pi today, this time looking into samples. A sample is just a prerecorded audio clip. Sonic Pi comes with lots of samples available by default. You can trigger a sample using the sample
keyword followed by the name of the sample you want to play, preceded by a colon.
sample :elec_blip
Samples work just like notes in most regards. For example, you can space them out with sleep
and layer them by triggering the samples at the same time. Or you can combine them with regular synth notes:
sample :elec_blipsleep 1.2
play 67sleep 1.2
use_synth :bass_foundation
play 64sample :glitch_perc1sleep 1.2
play 49
The audio output of samples can also be changed using amp and pan.
sample :elec_blip, pan: -1sleep 1
use_synth :bass_foundationplay 62, attack: 0.4, release: 0.8sample :elec_blip, pan: -0.3sleep 1
use_synth :bass_highendplay 50, amp: 0.6, attack: 1, release: 0.2sample :elec_blip, pan: 0.3sleep 1
sample :elec_blip, pan: 1
Rate (Stretch, Squash, and Reverse)
You can change the length and pitch at which a sample is played using the rate
opt:
sample :ambi_glass_rub, rate: 1
The default value for the rate
opt is 1
, so sample :ambi_glass_rub
is the same as sample :ambi_glass_rub, rate: 1
.
We can stretch a sample by using a rate
value less than 1
:
sample :ambi_glass_rub, rate: 0.5
rate: 0.5
doubles the length of time that the sample takes to play as well as plays it an octave lower.
Alternatively, we can squash a sample by using a rate
value greater than 1
:
sample :ambi_glass_rub, rate: 2
rate: 2
cuts the length of time that the sample takes to play in half as well as plays it an octave higher.
Finally, we can reverse a sample by using a negative value for the rate
:
sample :ambi_glass_rub, rate: -1
Here's a fun drum sample played backward and forward at various rate
s:
sample :loop_amen, rate: -0.5sleep 3.5sample :loop_amen, rate: 0.5sleep 3.5sample :loop_amen, rate: -1sleep 1.67sample :loop_amen, rate: 1sleep 1.67sample :loop_amen, rate: -1.5sleep 1.15sample :loop_amen, rate: 1.5
Envelopes
Unsurprisingly, we can also apply the ADSR envelope opts to adjust the attack, decay, sustain, and release of our sample playback, but it works a little differently than regularly played notes.
Where you can fully extend a note using the ADSR envelope, you can only reduce the amplitude and length of a played sample. Using lengthy attack
, decay
, sustain
, or release
will not make the sample playback longer. In fact, you can never extend a sample's length using an envelope. The sample will stop playing either when the envelope has completed its four phases or the sample has finished playing, whichever comes first.
This can be a little bit confusing to figure out, so let's break it down. Here's a nice, long sample to play with:
sample :loop_3d_printer
We can fade in over 1 beat using the attack
opt:
sample :loop_3d_printer, attack: 1
We can also set the amplitude that the attack phase attacks toward using the attack_level
opt:
sample :loop_3d_printer, attack: 1, attack_level: 0.4
We can also adjust the decay
and decay_level
:
sample :loop_3d_printer, attack: 1, attack_level: 0.4, decay: 1, decay_level: 0.8
Sustain works differently though. Where for a regular synth note playback, sustain
's default value is 0
, for a sample, sustain
's default is the calculated time it takes to play the rest of the sample. More on this in a second.
Release is also a little different in a sample than in a synth; where a synth's release
default value is 1
, for a sample the release
default value is 0
. You can hear this when you compare this:
sample :loop_3d_printer
...with this:
sample :loop_3d_printer, release: 1
So what was this about the sustain taking on a calculated duration for samples? Let's dive in there.
First, let's think about the length of the :loop_3d_printer
sample we've been playing with. You can see that with:
print sample_duration :loop_3d_printer# expected result: 7.959183673469388
We can see that :loop_3d_printer
is basically 8 beats long, which is 8 seconds at 60 bpm. If we add release: 1
, it fades out the sample for the last second of playback. If no other opts are present, this means the other 6.959183673469388 are the duration of the sustain.
sample :loop_3d_printer, release: 1
And further, if we use attack: 1
to fade in for one second at the beginning of the sample playback, the sustain
is further reduced to 5.959183673469388.
sample :loop_3d_printer, attack: 1, release: 1
However, we can also adjust the sustain
manually by giving it a value. If that value is less than the automatically calculated sustain
value, it will cut the playback time down.
sample :loop_3d_printer, attack: 1, sustain: 3, release: 1
But we can also drop the sustain
to 0
, allowing us to get some very short, punchy samples:
sample :loop_3d_printer, attack: 1, sustain: 0, release: 1
You can use this trick effectively with drum samples. Compare this :drum_snare_hard
sample with its defaults:
sample :drum_snare_hard
...to this one with sustain: 0
and release: 0.2
:
sample :drum_snare_hard, sustain: 0, release: 0.2
This second one is much tighter and cleaner sounding!
Partial Samples
We can also use specific portions of a sample. We can specify a starting position with the start
opt and an ending position with the finish
opt. In this way we don't have to start at the beginning of the sound or finish at the end of the sound.
sample :loop_3d_printer, start: 0.3, finish: 0.4
Naturally this can be combined with rate, envelope, and other opts and techniques to give you a huge range of options for building beats and music.
External Samples
You can also use any WAV, AIFF, OGG, OGA, or FLAC files on your computer as samples by passing in a file path. If, for example, you had a file named Kasha.wav
on your MacBook's desktop that you wanted to sample, you could do with the following:
sample "/Users/joey/Desktop/Kasha.wav"
All of the same opts will work for this sample!
sample "/Users/joey/Desktop/Kasha.wav", start: 0.6, finish: 0.7