I’m teaching some more 101 level programmer classes and this time we’re looking at Sonic Pi as an introduction to text-based languages after playing with the building blocks of Scratch. I chose Sonic Pi because of it’s immediacy of interaction and fast feedback going from typing code to seeing (or hearing) a result.
The first and simplest program you can write is a one liner to play a single note. Like this
Changing the numeric value changes the pitch of the note, lower values are lower in pitch, higher values are higher in pitch.
You can play two notes separated by small pause like this:
play 60 sleep 0.5 play 62
Notes are processed top to bottom in order. Sleep puts a pause in the program of that many seconds before playing the next note. If the sleep wasn’t there, both notes would play together. Increasing and decreasing the sleep value changes length of the piece.
One thing to mention before we go too far, as this is a text based language, spelling, case (upper and lower and mixed) and punctuation really matter. Things which are spelled differently really are different things to the computer, even if you didn’t intend them to be different.
Music is often about repetition so it’s good to be able to repeat phrases and there are a number of different ways that Sonic Pi supports this. An easy one is repeating something a number of times:
5.times do play 60 sleep 1 end
Maybe not terribly exciting but we can move on from there to do scales:
# play a chromatic scale note = 60 12.times do play note note = note + 1 sleep 0.5 end
C Chromatic scale
10.times do play chord(:E3, :major).choose sleep 1 end
root = 55
play root # C3 sleep 0.5 play root + 1 sleep 0.5 play root + 2 sleep 0.5 play root + 3 sleep 0.5 play root + 4 sleep 0.5 play root + 5 sleep 0.5 play root + 6 sleep 0.5 play root + 7 sleep 0.5 play root + 8 sleep 0.5 play root + 9 sleep 0.5 play root + 10 sleep 0.5 play root + 11 sleep 0.5 play root + 12 # C4 sleep 0.5
root = 50 note = root
12.times do play note sleep 0.5 note = note + 1 end
Welcome to Sonic Pi v2.9
live_loop :bass do [:d2, :a2, :b2, :g2].each do |n| 8.times do # with_fx :rlpf do play n, release: 0.2 # end sleep 0.25 end end end
live_loop :kick do # sync :bass sample :drum_bass_hard with_fx :slicer do sample :drum_bass_hard end sleep 0.5 end
chord(:e3, :major7).each do |n| play n sleep 0.5 end live_loop :test do
sample :bd_haus, rate: 1 sleep 0.5
loop do play choose(chord(:e3)) sleep 2 end
loop do with_fx :flanger do sample :ambi_haunted_hum, rate: (rrand 1.0, 2.5) sleep (rrand 0, 2) sample :perc_bell, rate: (rrand 1.0, 2.5) sleep rrand(0, 2) end end
live_loop :foo do use_synth :prophet play :e2, release: 8, cutoff: rrand(70, 130) sleep 8 end
live_loop :bar do #use_synth :dark_ambience #play :c5 #sample :bass_voxy_hit_c #sample :guit_e_fifths #sample :bd_haus play (ring :d, :r, :r, :a, :f5, :r, :a, :r).tick sleep 0.25 end