Skip to content

Instantly share code, notes, and snippets.

@rbnpi
Last active April 13, 2017 15:29
Show Gist options
  • Save rbnpi/9fe5edfe04fbbdb8bc51 to your computer and use it in GitHub Desktop.
Save rbnpi/9fe5edfe04fbbdb8bc51 to your computer and use it in GitHub Desktop.
Bett Show 2015 talk

Sonic Pi 2.2 at Bett 2015

This is a summary of a talk given at Bett 2015 on Sonic Pi

I started by playing excerpts from two programs, Scott Joplin Maple Leaf Rag, and a Percussion Generator, to illustrate different things Sonic Pi can do, and gave a brief description of Sonic Pi and the user interface, similar to section 1.2 of the built in tutorial, which is accessed by clicking the Help button.

I also showed how one of the example programs "Idm Breakout" could be copied and played. Then I used the following program sections to develop a code to play the round Frere Jaques

##Making sounds

Sonic Pi can play sounds generated by built in Synths, or by playing audio sample files, 89 of which are included with the program, or it can play user supplied audio sample .wav files as well.

play 72

plays a synth sound and

sample :loop_amen_full

plays a sample file

##If the sounds are nice, you might be playing music...

play 72
play 76
play 79

plays three notes so quickly after each other that they sound together as a chord. If you want to play them one after the other you need tell Sonic Pi to sleep or wait before starting another note In the following example the notes are played with 0.2 seconds between each one

play 72
sleep 0.2
play 74
sleep 0.2
play 76
sleep 0.2
play 77
sleep 0.2
play 79
sleep 0.2

##How about less typing....

It is tedious to type so much, so Sonic Pi has commands that simplify matters. To play a chord, you can put the note numbers inside a list, separated by commas

play [76,79,84]

and to play notes one after another, separated in time by 0.2 seconds you can type

play_pattern_timed [79,77,76,74,72],[0.2]

Here there are two lists separated by a comma. The first is the list of notes to be played, and the second, which only has one element 0.2 in it is the corresponding list of gaps between each note. In this case, after the first note is played, Sonic Pi sleeps for 0.2 seconds, after the second note is played, it looks for another sleep time in this list, but becuase it doesn't find one, it starts reading the list again, and uses the 0.2 for a second time, and so on. In a later example we will use different times for the various notes.

##You can represent notes symbolically instead of by numbers...

play [:c5,:e5,:g5]

and you can also use variables or named "stores" to hold the duration information

q = 0.2   # the time we will use for a quaver (note the # signifies a comment which is ignored by Sonic Pi)
c = 2 * q # a cratchet lasts twice as long
play_pattern_timed [:c5,:d5,:e5,;f5,;g5],[c,q,c,q,c] # note ALL the 5 durations are specified in this example

##Changing the nature of the sound....

You can change the synth used to generate sounds from the default (:beep) and can also change the shape of the sound generated by each note. (see section 2.3 of the built in tutorial for more details)

use_synth :tri
c = 0.4
play_pattern_timed [:c4,:d4,:e4,:c4],[c]
sleep 2
#now we play the same notes altering the length, so that the sound reduces to 0 over the release time
play_pattern_timed [:c4,:d4,:e4,:c4],[c],release: c

##Building Frere Jaques....

The previous example played the first line of Frere Jaques. We can develop this to play all of the tune. We will use the tri synth again, and also define our note durations for quaver, crotchet and minum. Another technique we can use from the Ruby language is to multiply a note list or a duration list by two, which has the effect of repeating it, adding a second copy to the end of the first one.

#select the synth
use_synth :tri

#first define note durations
q = 0.2 #quaver
c = 2 * q #crotchet, twice as long as a quaver
m = 2 * c #minim, twice as long as a crotchet

#now play the first line we heard above twice. Note: 1 duration "gap" so it is repeated for each note
play_pattern_timed [:c4,:d4,:e4,:c4]*2,[c],release: c  #release decays the note over a crotchet length
#now add line 2, played twice
play_pattern_timed [:e4,:f4,:g4]*2,[c,c,m]*2,release: c
#now add line 3 playced twice
play_pattern_timed [:g4,:a4,:g4,:g4,:e4,:c4]*2,[q,q,q,q,c,c,]*2,release: c
#finally add the last line, played twice
play_pattern_timed [:c4,:g3,:c4]*2,[c,c,m]*2,release: c

##Put the tune into a defined function...

Because we want to use the tune several times if we are to play it as a round we will define it as a named function

use_synth :pulse #use a different synth for a change

define :frere do

#first define note durations
q = 0.2 #quaver
c = 2 * q #crotchet, twice as long as a quaver
m = 2 * c #minim, twice as long as a crotchet

#now define frere
define :frere do #we copy the tune lines exactly as they are above
  play_pattern_timed [:c4,:d4,:e4,:c4]*2,[c],release: c
  play_pattern_timed [:e4,:f4,:g4]*2,[c,c,m]*2,release: c
  play_pattern_timed [:g4,:a4,:g4,:g4,:e4,:c4]*2,[q,q,q,q,c,c,]*2,release: c
  play_pattern_timed [:c4,:g3,:c4]*2,[c,c,m]*2,release: c
end

#if we stop there, we will hear nothing when we run the code
#This is because we have defined frere, but we have NOT asked Sonic Pi to play it
#we do this simply be using the function name we have defined
frere #this plays the tune

Note you can press the button marked Align at the top of the Sonic Pi screen, and it will indent the lines in the definition automatically for you. You can do this at any time, and as often as you like when writing a progarm to neaten it up.

##Building a round...

A round is when a tune is played several times, with each "part" coming in one line later than the previous one. In the case of Frere Jaques, the different lines fit quite well together giving a pleasing overall effect.

#we'll set the synth for the first tune
use_synth :pulse
#then we set up the note durations, slightly quicker this time
#note because of the way they are defined we only have to change one number
q = 0.15 #quaver (a bit quicker, i.e. shorter)
c = 2 * q #crotchet, twice as long as a quaver
m = 2 * c #minim, twice as long as a crotchet

#now define frere
define :frere do #we copy the tune lines exactly as they are above
  play_pattern_timed [:c4,:d4,:e4,:c4]*2,[c],release: c
  play_pattern_timed [:e4,:f4,:g4]*2,[c,c,m]*2,release: c
  play_pattern_timed [:g4,:a4,:g4,:g4,:e4,:c4]*2,[q,q,q,q,c,c,]*2,release: c
  play_pattern_timed [:c4,:g3,:c4]*2,[c,c,m]*2,release: c
end

#now we start setting up the round
#play the first line of the first "voice" or rendition of frere
#extension goes here later (1)
play_pattern_timed [:c4,:d4,:e4,:c4]*2,[c],release: c
#we start the tune again, (the second "voice") but put it inside a thread.
#This starts it playing and goes on immediately to the next line of code in the program
#which will play line 2 of the first "voice" at the same time.
in_thread do
  use_synth :saw  #use a different synth to make the part stand out
  frere  #play the tune using our definition
end
#meanwhile play the second line of part 1
play_pattern_timed [:e4,:f4,:g4]*2,[c,c,m]*2,release: c
#now we start the third "voice" in another thread and leave it to play there
in_thread do
  use_synth :prophet #change the synth again for this part
  frere #play the tune
end
#meanwhile start the third line of part 1
play_pattern_timed [:g4,:a4,:g4,:g4,:e4,:c4]*2,[q,q,q,q,c,c,]*2,release: c
#now we start the fourth and final "voice" in another separate thread
in_thread do
  use_synth :fm #yet another synth
  frere #play the tune
end
#meanwhile play the final line of the first part
play_pattern_timed [:c4,:g3,:c4]*2,[c,c,m]*2,release: c
#to keep things neat and tidy we sleep until the fourth voice has finished. It still has 3 lines to play
sleep 3 * 2 * 4 * c  #3 lines, each of 2 bars of 4 crotchets
#extension goes here later (2)

#extension.... Sonic Pi supports a wide range of studio effects which can be applied to your sounds. As an example you can add a wrapper to the program to give a bit of reverberation, as if it was beeing played in a large hall. Replace the comment line #Extension goes here later (1) with

with_fx :reverb, room: 0.8 do

and replace the comment line #Extension goes here later (2) with

end

Press the Align button, and notice how all of the program between the two lines we have added is indented, as it is all affected by the reverb fx we have added. Press the run button and hear the difference. The room: parameter adjusts the size of the space in which we are playing. Here it is set for quite a large space.

##What have we covered...

This short introduction has developed a simple tune, introducing you to various ideas including:

the following commands:

 play
 play_pattern_timed
 sleep
 use_synth

how to define a new function

define :functionname do
  ... #the commands within the function go here
  ...
  ...
end

how to start an independent sequence of commands in a thread

in_thread do
  ... #the commands withion the thread go here
  ...
  ...
end

using symbols for notes

 :c4  equivalent to 60
 :g4  equlvalent to 67
 :c3  equivalent to 48

using variables to hold values, and doing simple arithmentic with the contents

q = 0.2
 c = 2 * q  #c holds the value 2 * 0.2 = 0.4

The use of the align button to tidy up the code layout

One example of adding an fx effect

At this stage I demonstrated two further versions of the Frere Jaques round (FrereSliding.rb and FrereAmbiDrone.rb) and also a program LiveCodingExample.rb to illustrate Live Coding. I finished the talk by playing a program Celeste-RPI.rb which gives a rendition of The Dance of the Sugar Plum Fairly from Tchaikovsky's Nutcracker Suite.

##Where next....

1 Explore! Sonic Pi comes with a comprehensive built in Tutorial in the Help system, which takes you step by step through its many features. There are also a large number of example files included. You can copy and paste these into a workspace and play them. There are also sections in the help system describing the synths and samples which are available, and also the many fx effects which can be applied to sounds.

2 There are other resources available which can help you learn how to use Sonic Pi, and where to go for help. There are useful links included on the Info page (reached by clicking the Info button at the top of the Sonic Pi screen). Look at the about and the community tabs at the bottom of the window. The http://sonic-pi.net site contains some further examples which you can copy and paste, and also listen to, as well as download links for versions of Sonic-Pi to run under MacOS or Windows. Sam Aaron, the Author of Sonic Pi produces a weekly newsheet which you can subscrbe to at http://eepurl.com/9SLYX If you get stuck, you can ask questions on the Google SonicPi Group https://groups.google.com/forum/#!forum/sonic-pi

3 There are many ways to utilise Sonic Pi. I have tended to transcribe existing pieces of music for it, and to develop sample-based voices to make them sound as authentic as possible. I generally ahve used classical msuic for this, partly because I enjoy it, and also because there are fewer copyright problems in using it. I have written several articles on the techniques I have developed on my blog http://rbnrpi.wordpress.com and also published code as gists on the site https://gist.github.com/rbnpi I have also published sound files of Sonic Pi music on https://soundcloud.com/rbnman

###live coding However, another major use of Sonic Pi on which a lot of development work has taken place is to enable it to be used as a live instrument for performance. This is done utilising what is known as live coding. In particular a thread like command called live_loop enables you to set up some code and start it playing, and then alter the code while it is playing and run the changed version of the live_loop. This will automatically synchronise and run the new version of the code the next time the loop starts. The best way to see this is to look at two videos that Sam Aaron, the author of Sonic Pi has posted. http://vimeo.com/113811476 and http://vimeo.com/114323834 These give examples of live coding in use. Section 9 of the tutorial also gives further information on Live Coding.

(I demonstrated a simple LiveCoding program in use in the talk)

4 Above all just get stuck in. Experiment, try things out, and share how you get on via Twitter @sonic_pi or Facebook Sonic Pi page

other demo files at the talk were

The sectional talk code BETT-talk.rb (uncomment the #nc= lines in turn to play each section) http://goo.gl/cquRq4

BETT-FrereSliding.rb http://goo.gl/RD3VdS

BETT-FrereAmbiDrone.rb http://goo.gl/oyXlUS

Idm Breakbeat (from built in examples)

BETT-LiveCodingExample.rb http://goo.gl/trn6nv

BETT-ScottJoplinMapleLeafRag.rb http://goo.gl/tGoL00

BETT-PercussionGenerator2.rb http://goo.gl/ye83cy

BETT-Celeste-RPI.rb http://goo.gl/zhK0QL

BETT-Celeste-MacOS-1.rb #file split into two parts to work on Mac http://goo.gl/W87HQa

BETT-Celeste-MacOS-2.rb http://goo.gl/7ePwJ3

All of the above programs are avaliable as gists from https://gist.github.com/rbnpi

Samples folder CEL for Celeste code (This should be copied to a known location on your Raspberry Pi or other computer, and the appropriate path added to the Celeste program. As supplied, put the downloaded folder (unzipped) inside a folder named samples in the pi user home directory) download link http://r.newman.ch/rpi/CEL.zip

All the files will work on the Windows Version from Windows ver 2.3 onwards. For version 2.1.1 (current at the time of writing) you need to remove the section which checks whether a sample is loaded in the PercisionGenerator and Celeste programs, using the new sample_loaded? function. These just check if the samples are loaded, and allows some extra loading time if not. Until ver 2.3 is released, you can delete the relevant sections and just put in the appropriate sleep command.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment