Skip to content

Instantly share code, notes, and snippets.

@rbnpi
Created March 9, 2015 18:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rbnpi/10a7787159bfb3c8a5fb to your computer and use it in GitHub Desktop.
Save rbnpi/10a7787159bfb3c8a5fb to your computer and use it in GitHub Desktop.
Sonic Pi large project to play 26 different Rounds using 5 sample based voices. The program is customisable. See areticle at https://rbnrpi.wordpress.com and the comment below
#Program demonstrating the streamlined method of setting up a sample based voice
#from a single sample with a medley of rounds and voices
#written by Robin Newman, March 2015
#Works best with a Pi2 and Sonic Pi 2.5dev or later, but can be adjusted for other configurations
#See article on https://rbnrpi.wordpress.com/
#most of the rounds from http://www-personal.umich.edu/~msmiller/rounds.html
#the rest from Wikipedia en.wikipedia.org/wiki/Round_(music)
# if using version 2.5dev or later remove or comment out function pitch_ratio
#The program is arranged to deal with 3 or 4 part rounds. The three or four parts
#are played twice, the second time up an octave.
#The program utilises just 5 single note audio samples for 5 different instruments
#The function pl enables note to be played using each of these instruments
#Transposition, allocation of instruments and tempo can be adjusted for each round
#Most of the four part rounds are transposed down, to allow for the pitch range of the trumpet voice
#used for the fourth part.
#One round, 'Sumer Is Icumen In' has a drone bass part added. This is played
#by the bassoon voice which is only used for this round.
#The remaining three voices are shuffled at random between each of the first three
#parts of each round.
#Each round has its notes stored in a notes array, and the corresponding
#note durations in a related array
#These are processed by the function plarray
#Note durations are expressed in terms of variables defining each note value
#These are set up by the function setupround, which first sets the tempo,
#redefining the note duration variables, and then the arrays holding each round
#CONFIGURATION CHOICES=============================================================
#location of samples
use_sample_pack_as '/home/pi/samples/Rounds',:rounds #adjust location as necessary
#program needs sample name and normal pitch of that sample
selectionmode=true #set to true for random selection of 5 choices or false to play all 26 rounds
use_random_seed(11111) #change seed number to get a different selection of choices if using selection mode
num=26 #number of rounds to choose from (set to one LESS than then number of rounds if using a Pi B or B+
#to exclude the round 'SUMER IS ACUMIN IN" which will not play on these models
#num MUST be adjusted if you change the number of rounds in the data section
#on a Pi model B or B+ comment out fx_reverb and associated end towards end of program
#END OF CONFIGURATION CHOICES======================================================
use_debug false
#first deal with selecting and setting up the samples
inst0=:rounds__bassoon_g3
samplepitch0=:g3
inst1=:rounds__flute_ds5
samplepitch1=:ds5
inst2=:rounds__clarinet_gs4
samplepitch2=:gs4
inst3=:rounds__harp_a4
samplepitch3=:a4
inst4=:rounds__trumpet_cs5
samplepitch4=:cs5
#preload all the samples
load_flag=0
if sample_loaded? inst0 then #check if sample already loaded
flag=1
end
load_samples [inst0,inst1,inst2,inst3,inst4]
if load_flag==0 then #samples not loaded so allow time
sleep 3
end
#put the sample names and pitches into an array i
i=[[inst0,samplepitch0],[inst1,samplepitch1],[inst2,samplepitch2],[inst3,samplepitch3]]
i.concat [[inst4,samplepitch4]]
#build list of instrument choices for each round.
instlist=[]
num.times do #first three voices allocated at random
instlist.concat [[i[2],i[1],i[3]].shuffle+[i[4],i[0]]]
end
#define variables that need to be used globally
s=dsq=sq=sqd=q=qt=qd=qdd=c=cd=cdd=m=md=mdd=b=bd=0 #note duration variables
roundlist=[] #round names
notes=[] #notes list for a round (an array of arrays)
dur=[] #note durations for a round (an array of arrays)
notesbass=[] #etra part notes for round 3
durbass=[] #extra part durations for round 3
gapslist=[] #gap between parts coming in
tempolist=[] #tempo of a round
partslist=[] #number of part entries in round
shiftlist=[] #transpose shift to play round
#prior to the release of version 2.5 you need the next function
#if you get an error message saying it exists then delete it or comment it out
comment do
define :pitch_ratio do |n|
return 2**(n.to_f/12)
end
end
#this function plays the sample at the relevant pitch for the note desired
#the note duration is used to set up the envelope parameters
define :pl do |inst,samplepitch,nv,dv|
shift=note(nv)-note(samplepitch)
sample inst,rate: (pitch_ratio shift),sustain: 0.8*dv,release: 0.2*dv
end
#this function plays an array of notes and associated array of durations
#also uses sample name (inst), sample normal pitch, and shift (transpose) parameters
define :plarray do |inst,samplepitch,narray,darray,shift=0|
narray.zip(darray) do |nv,dv|
if nv != :r
pl(inst,samplepitch,note(nv)+shift,dv)
end
sleep dv
end
end
#set_bpm sets bpm required adjusting note duration variables accordingly
define :set_bpm do |n|
s=1.0/8*60/n.to_f
dsq = 1 * s #demisemiquaver
sq = 2 * s #semiquaver
sqd = 3 * s #semi quaver dotted
q = 4 * s
qt = 2.0/3*q
qd = 6 * s
qdd = 7 * s
c = 8 * s
cd = 12 * s
cdd = 14 * s
m = 16 * s
md = 24 * s
mdd = 28 * s
b = 32 * s
bd = 48 * s
end
#this section sets the bpm then defines the note and duration arrays
#for all the differnt rounds
define :setuprounds do |bpmvalue|
set_bpm(bpmvalue) #define notes and durations in terms of currrent bpm value
#DATA SECTION DETAILING THE ROUNDS==============================
v=0 #index counter for rounds
roundlist[v]='Three Blind Mice'
notes[v]=[:fs4,:e4,:d4,:r,:a4,:g4,:r,:g4,:fs4,:r,:a4,:d5,:d5,:cs5,:b4,:cs5,:d5,:a4,:a4,:a4,:d5,:d5,:d5,:cs5,:b4,:cs5]
notes[v].concat [:d5,:a4,:a4,:a4,:d5,:d5,:cs5,:b4,:cs5,:d5,:a4,:a4,:a4,:g4,:fs4,:e4,:d4,:r]
dur[v]=[cd,cd,cd+q,c,cd,q,q,q,c,c,c,c,q,q,q,q,c,q,c,q,q,q,q,q,q,q]
dur[v].concat [c,q,c,q,c,q,q,q,q,q,q,q,c,q,cd,cd,cd,cd]
tempolist[v]=180
gapslist[v]=4*cd
partslist[v]=4
shiftlist[v]=-5
v +=1
roundlist[v]='Row the Boat'
notes[v]=[:c4,:c4,:c4,:d4,:e4,:e4,:d4,:e4,:f4,:g4,:c5,:c5,:c5]
notes[v].concat [:g4,:g4,:g4,:e4,:e4,:e4,:c4,:c4,:c4,:g4,:f4,:e4,:d4,:c4]
dur[v]=[cd,cd,c,q,cd,c,q,c,q,cd*2,q,q,q,q,q,q,q,q,q,q,q,q,c,q,c,q,cd*2]
tempolist[v]=180
gapslist[v]=4*cd
partslist[v]=4
shiftlist[v]=0
v +=1
roundlist[v]='Frere Jaques'
notes[v]=[:c4,:d4,:e4,:c4]*2+[:e4,:f4,:g4]*2+[:g4,:a4,:g4,:f4,:e4,:c4]*2+[:c4,:g3,:c4]*2
dur[v]=[c,c,c,c,c,c,c,c,c,c,m,c,c,m,q,q,q,q,c,c,q,q,q,q,c,c,c,c,m,c,c,m]
tempolist[v]=160
gapslist[v]=8*c
partslist[v]=4
shiftlist[v]=0
v +=1
roundlist[v]='Wind, gentle evergreen'
notes[v]=[:d5,:e5,:d5,:c5,:b4,:c5,:d5,:e4,:g4,:c5,:b4,:c5,:b4,:a4,:d5,:d5,:cs5,:c5,:c5,:b4,:g4,:b4,:a4,:g4,:fs4,:g4,:g4]
notes[v].concat [:b4,:c5,:b4,:g4,:a4,:fs4,:g4,:a4,:b4,:c5,:b4,:a4,:g4,:g4,:fs4,:a4,:gs4,:b4,:e4,:a4,:a4,:a4,:fs4,:g4,:d5,:c5,:b4,:a4,:g4,:g4]
notes[v].concat [:g4,:g4,:d4,:g4,:g4,:c4,:e4,:fs4,:g4,:d4,:b3,:a3,:fs4,:g4,:b3,:c4,:c4,:d4,:d4,:g4]
dur[v]=[qd,sq,c,c,cd,q,c,qd,sq,c,qd,sq,c,c,c,c,c,c,c,c,q,q,qd,sq,cd,q,md]
dur[v].concat [qd,sq,q,q,q,q,cd,q,c,qd,sq,c,c,c,q,q,q,q,c,c,c,qd,sq,c,c,qd,sq,cd,q,md]
dur[v].concat [c,c,c,m,c,qd,sq,c,c,m,c,m,c,m,c,qd,sq,cd,q,md]
tempolist[v]=160
gapslist[v]=8*md
partslist[v]=3
shiftlist[v]=0
v +=1
roundlist[v]='Upon Christ Church Bells in Oxford'
notes[v]=[:c5,:c5,:c5,:c5,:c5,:c5,:c5,:e5,:d5,:c5,:b4,:a4,:g4,:g4,:g4,:g4,:e4,:g4,:c4,:g4,:c5,:f4,:g4,:g5,:f5,:e5,:a5,:d5,:e5,:f5,:e5,:d5,:c5]
notes[v].concat [:e5,:e5,:e5,:e5,:e5,:e5,:e5,:g5,:f5,:e5,:f5,:d5,:c5,:d5,:g4,:d5,:d5,:e5,:d5,:e5,:d5,:e5,:d5,:d5,:c5,:b4,:c5,:a4,:d5,:b4,:c5,:d5,:e5]
notes[v].concat [:g5,:g5,:g5,:g5,:g5,:g5,:g5,:g5,:g5,:g5,:g5,:g4,:a4,:a4,:b4,:c5,:b4,:r,:a4,:b4,:c5,:b4,:c5,:b4,:c5,:d5,:b4,:a4,:g4,:a4,:f4,:g4,:g4,:c4]
dur[v]=[cd,q,c,c,c,c,c,c,c,c,c,c,cd,q,c,c,c,c,c,c,c,c,c,q,q,c,c,q,q,c,cd,q,m]
dur[v].concat [cd,q,c,c,c,c,c,c,c,q,q,c,c,c,c,c,c,c,c,c,c,c,c,c,q,q,c,c,c,c,cd,q,m]
dur[v].concat [q,q,q,q,c,q,q,c,q,q,c,c,cd,q,c,c,m,c,q,q,c,c,c,c,c,c,c,q,q,c,c,cd,q,b]
tempolist[v]=160
gapslist[v]=8*b
partslist[v]=4
shiftlist[v]=-7
v +=1
roundlist[v]='To The Greenwood'
notes[v] = [:c5,:b4,:b4,:a4,:a4,:g4,:g4,:f4,:f4,:e4,:c4,:f4,:g4,:c4]
notes[v].concat [:c4,:d4,:e4,:f4,:g4,:e4,:f4,:d4,:e4,:c4,:a4,:b4,:c5,:d5,:g4,:c5,:c5,:b4,:c5]
notes[v].concat [:e5,:e5,:d5,:e5,:c5,:c5,:b4,:c5,:a4,:a4,:g4,:e5,:d5,:c5,:c5]
dur[v]=[m,c,c,c,c,c,c,c,c,c,c,c,c,m,q,q,q,q,c,c,c,c,c,c,q,q,q,q,c,c,c,c,m,cd,q,c,c,cd,q,c,c,c,c,c,c,cd,q,m]
tempolist[v]=160
gapslist[v]=4*b
partslist[v]=3
shiftlist[v]=0
v +=1
roundlist[v]='Viva La Musica!'
notes[v]=[:d5,:c5,:b4,:a4,:g4,:fs4,:g4,:fs4,:b4,:c5,:d5,:c5,:b4,:a4,:g4,:a4,:g4,:g4,:c4,:d4,:e4,:d4]
dur[v]=[cd,q,c,q,q,c,c,m,cd,q,c,q,q,c,c,m,c,m,c,c,c,m]
tempolist[v]=160
gapslist[v]=2*b
partslist[v]=3
shiftlist[v]=0
v +=1
roundlist[v]='Shalaom Chavarim'
notes[v]=[:b3,:e4,:e4,:fs4,:g4,:e4,:g4,:g4,:a4,:b4,:b4,:e5,:d5,:b4,:b4,:e5,:b4,:a4,:g4,:a4,:b4,:g4,:fs4,:e4,:b3,:e4,:fs4,:g4,:e4]
dur[v]=[c,c,q,q,c,c,c,q,q,c,c,md,c,md,c,c,q,q,c,c,c,q,q,c,c,md,q,q,md]
tempolist[v]=160
gapslist[v]=4*c
partslist[v]=3
shiftlist[v]=0
v +=1
roundlist[v]='Oh My Love Lovst Thou Me II'
notes[v]=[:g4,:a4,:bb4,:bb4,:c5,:d5,:g5,:d5,:g5,:g5,:f5,:g5,:d5,:c5,:bb4,:a4,:g4]
dur[v]=[m,m,b,m,m,md,c,c,c,c,c,m,cd,q,m,m,b]
tempolist[v]=180
gapslist[v]=2*b
partslist[v]=4
shiftlist[v]=-5
v +=1
roundlist[v]='Celebrons sans cesse'
notes[v]=[:c5,:bb4,:a4,:bb4,:g4,:f4,:f4,:c4,:d4,:bb3,:c4,:c5,:bb4,:a4,:g4,:f4,:f4,:e4,:f4,:f5,:e5,:d5,:c5,:a4]
dur[v]=[md,c,m,m,b,m,b,m,m,m,m,md,c,b,md,c,b,m,m,b,m,b,b,b]
tempolist[v]=220
gapslist[v]=4*b
partslist[v]=4
shiftlist[v]=-5
v +=1
roundlist[v]='Gaudeamus Hodie'
notes[v]=[:c4,:c4,:e4,:g4,:f4,:g4,:f4,:e4,:d4,:c4,:c4,:e4,:g4,:f4,:e4,:d4,:c4,:c4,:e4,:g4,:c5,:b4,:a4,:g4,:f4,:e4,:d4,:c4]
notes[v].concat [:c4,:d4,:e4,:f4,:g4,:a4,:g4,:e4,:f4,:d4,:c4]
notes[v].concat [:g4,:g4,:a4,:c5,:g4,:g4,:a4,:f4,:g4,:c5,:e5,:d5,:c5,:d5,:g4,:c5,:b4,:c5]
dur[v]=[c,c,c,c,c,c,q,q,c,c,c,c,c,c,c,m,c,c,c,c,c,c,q,q,c,m,m,b]
dur[v].concat [b,b,b,b,b,b,c,c,c,c,b,m,m,c,md,m,m,c,md,m,m,c,c,c,c,c,m,c,b]
tempolist[v]=200
gapslist[v]=8*b
partslist[v]=3
shiftlist[v]=0
v +=1
roundlist[v]='Come Let us All A-Maying Go'
notes[v]=[:g5,:fs5,:e5,:d5,:e5,:d5,:c5,:b4,:g4,:a4,:g4,:g5,:fs5,:d5,:g5,:fs5,:d5,:g5,:fs5,:e5,:g5,:fs5,:g5]
notes[v].concat [:e5,:d5,:c5,:b4,:a4,:b4,:c5,:b4,:a4,:g4,:d5,:c5,:b4,:b4,:c5,:d5,:b4,:g4,:d5,:b4,:g4,:c5,:a4,:r,:b4,:g4]
notes[v].concat [:g4,:g4,:g4,:g4,:g4,:g4,:g4,:g4,:d4,:g4,:fs4,:e4,:d4,:g4,:fs4,:e4,:d4,:c4,:d4,:g4]
dur[v]=[c,c,c,cd,q,q,q,cd,q,c,m,c,c,c,c,c,c,q,q,cd,q,c,md]
dur[v].concat [c,c,c,q,q,q,q,q,q,c,c,c,m,q,q,q,cd,c,q,cd,c,q,cd,c,m,c]
dur[v].concat [m,c,m,c,m,c,m,c,c,q,q,c,c,q,q,q,q,m,c,md]
tempolist[v]=180
gapslist[v]=4*bd
partslist[v]=3
shiftlist[v]=-4
v +=1
roundlist[v]='Come Follow Me Merrily'
notes[v]=[:d5,:b4,:c5,:d5,:e5,:e5,:d5,:d5,:c5,:b4,:a4,:b4,:c5,:c5,:b4,:a4,:g4,:a4,:b4,:g4]
notes[v].concat [:g4,:d4,:a4,:d4,:g4,:g4,:d4,:g4,:c4,:g4,:d4,:d4,:g4,:r,:b4]
notes[v].concat [:d5,:e5,:fs5,:e5,:fs5,:g5,:g5,:g5,:fs5,:d5,:e5,:fs5,:g5,:fs5,:e5,:fs5,:g5,:r]
dur[v]=[c,cd,q,c,c,c,c,c,c,c,m,c,c,c,c,cd,q,c,md+m,c,m,c,m,c,m,c,m,c,m,c,m,c,md,m,c]
dur[v].concat [cd,q,c,m,c,c,c,c,m,c,cd,q,c,cd,q,c,md+m,c]
tempolist[v]=180
gapslist[v]=4*bd
partslist[v]=3
shiftlist[v]=-4
v +=1
roundlist[v]='Now We Are Met'
notes[v]=[:c4,:e4,:f4,:g4,:a4,:b4,:c5,:a4,:g4,:f4,:e4,:e4,:d4,:c4,:f4,:g4,:c4]
notes[v].concat [:r,:c5,:c5,:c5,:b4,:r,:c5,:c5,:c5,:b4,:r,:g4,:g4,:g4,:a4,:b4,:c5,:b4,:c5]
notes[v].concat [:r,:b4,:c5,:d5,:e5,:r,:a4,:b4,:c5,:d5,:c5,:c5,:f5,:e5,:d5,:d5,:c5]
dur[v]=[c,q,q,c,q,q,c,c,m,c,q,q,c,c,c,c,m,q,q,q,q,c,cd,q,q,q,c,cd,q,q,q,q,q,m,c,m]
dur[v].concat [m+q,q,q,q,c,cd,q,q,q,c,q,q,c,c,c,c,m]
tempolist[v]=180
gapslist[v]=4*b
partslist[v]=3
shiftlist[v]=0
v +=1
roundlist[v]='Merrily, Merrily'
notes[v]=[:eb4,:eb4,:eb4,:eb4,:eb4,:eb4,:g4,:f4,:eb4,:r,:g4,:g4,:g4,:g4,:g4,:g4,:bb4,:ab4,:g4,:r]
notes[v].concat [:eb5,:eb5,:eb5,:eb5,:bb4,:eb5,:d5,:eb5,:c5,:bb4,:c5,:bb4,:eb5,:g4,:bb4,:bb4,:r]
dur[v]=[q,q,q,q,q,q,c,q,c,q,q,q,q,q,q,q,c,q,c,q,c,sq,sq,q,c,c,q,c,q,c,q,c,q,c,q,c,q]
tempolist[v]=140
gapslist[v]=2*md
partslist[v]=4
shiftlist[v]=-4
v +=1
roundlist[v]='The Huntsmen'
notes[v]=[:c4,:e4,:e4,:e4,:f4,:f4,:f4,:e4,:e4,:e4,:e4,:d4,:d4,:d4,:d4,:c4,:d4,:e4,:c4,:g4]
notes[v].concat [:g4,:g4,:g4,:g4,:g4,:g4,:g4,:g4,:a4,:a4,:a4,:b4,:b4,:b4,:c5,:c5,:r]
notes[v].concat [:c5,:r,:d5,:r,:e5,:c5,:e4,:e4,:f4,:f4,:f4,:g4,:g4,:g4,:c4,:r]
dur[v]=[q,q,q,q,q,q,q,c,q,c,q,q,q,q,q,q,q,cd,c,q,q,q,q,q,q,q,cd+c,q,q,q,q,q,q,q,cd,c,q]
dur[v].concat [c,q,c,q,q,m,sq,sq,c,s,sq,c,sq,sq,cd+c,q]
tempolist[v]=150
gapslist[v]=4*md
partslist[v]=3
shiftlist[v]=0
v +=1
roundlist[v]='Hey We to the Other World'
notes[v]=[:a4,:c5,:bb4,:a4,:g4,:f4,:e4,:c4,:a4,:c5,:f4,:c5,:d5,:c5,:bb4,:a4,:g4]
notes[v].concat [:c5,:c5,:a4,:f4,:f4,:bb4,:c5,:d5,:e5,:d5,:e5,:f5,:a4,:g4,:c5,:c5]
dur[v]=[m,m,q,q,q,q,c,c,c,c,cd,q,q,q,q,q,m,cd,q,c,q,q,q,q,c,c,q,q,md,c,cd,q,m]
tempolist[v]=180
gapslist[v]=2*b
partslist[v]=3
shiftlist[v]=-2
v +=1
roundlist[v]='Dona Nobis Pacem'
notes[v]=[:g4,:d4,:b4,:a4,:d4,:c5,:b4,:a4,:g4,:g4,:fs4,:e5,:d5,:c5,:b4,:a4,:d5,:c5,:b4,:b4,:a4,:g4,:fs4,:g4]
notes[v].concat [:d5,:d5,:d5,:c5,:b4,:b4,:a4,:e5,:e5,:d5,:d5,:d5,:c5,:b4,:a4,:g4]
notes[v].concat [:g4,:fs4,:g4,:a4,:b4,:c5,:d5,:d4,:c5,:c5,:b4,:b4,:fs4,:a4,:d5,:d4,:g4]
dur[v]=[q,q,m,q,q,m,c,c,c,c,m,c,q,q,q,q,cd,q,c,q,q,c,c,md]
dur[v].concat [md,md,c,c,c,c,m,c,m,c,m,q,q,c,c,md,md,md,cd,q,q,q,c,m,c,m,c,m,q,q,c,c,md]
tempolist[v]=140
gapslist[v]=8*md
partslist[v]=3
shiftlist[v]=-2
v +=1
roundlist[v]='Fox and Geese'
notes[v]=[:f4,:a4,:bb4,:c5,:d5,:e5,:f5,:g5,:e5,:f5,:c5,:c5,:bb4,:a4,:g4,:g4,:f4,:c4,:c4,:c4,:f4,:a4,:f4,:g4,:a4,:b4,:a4]
notes[v].concat [:g4,:a4,:g4,:a4,:c5,:c5,:f5,:c5,:f5,:d5,:e5,:c5,:c5]
dur[v]=[c,cd,q,c,cd,q,c,m,c,m,c,cd,q,c,c,c,c,c,c,c,m,c,cd,q,c,m,c,cd,q,c,m,q,q,c,m,c,m,m,c,md]
tempolist[v]=180
gapslist[v]=4*md
partslist[v]=4
shiftlist[v]=-5
v +=1
roundlist[v]='Hey, Ho, Nobody Home'
notes[v]=[:d4,:c4,:d4,:d4,:d4,:a3,:a3,:d4,:d4,:e4,:e4,:f4,:f4,:f4,:f4,:e4,:a4,:g4,:a4,:g4,:a4,:g4,:a4,:g4,:f4,:e4]
dur[v]=[m,m,c,q,q,c,c,c,c,c,c,q,q,q,q,m,cd,q,cd,q,cd,q,q,q,q,q]
tempolist[v]=180
gapslist[v]=b*2
partslist[v]=4
shiftlist[v]=3
v +=1
roundlist[v]='White Sand and Grey'
notes[v]=[:a4,:b4,:a4,:gs4,:a4,:cs5,:d5,:cs5,:b4,:cs5,:a4,:fs4,:d4,:e4,:a3]
dur[v]=[b,m,m,b,b,b,m,m,b,b,b,m,m,b,b]
tempolist[v]=210
gapslist[v]=4*b
partslist[v]=3
shiftlist[v]=-4
v +=1
roundlist[v]='Hava Nashira, Shir "Alleluia"'
notes[v]=[:g3,:d4,:e4,:d4,:g3,:c4,:b3,:a3,:g3,:a3,:g3,:g4,:fs4,:g4,:a4,:b4,:g4,:g4,:a4,:b4,:c5,:b4]
notes[v].concat [:b4,:a4,:g4,:fs4,:g4,:e4,:d4,:g4,:g4,:fs4,:e4,:fs4,:g4]
dur[v]=[m,c,c,m,m,m,c,q,q,m,m,m,c,c,m,m,m,c,q,q,m,m,m,c,c,m,m,m,c,c,q,q,q,q,m]
tempolist[v]=160
gapslist[v]=4*b
partslist[v]=3
shiftlist[v]=2
v +=1
roundlist[v]='Oaken Leaves'
notes[v]=[:f4,:c4,:f4,:f4,:f4,:f4,:e4,:f4,:g4,:f4,:g4,:g4,:fs4,:g4,:d4,:g4]
notes[v].concat [:a4,:a4,:c5,:a4,:g4,:a4,:bb4,:a4,:g4,:a4,:bb4,:a4,:g4,:fs4,:g4]
notes[v].concat [:f4,:c5,:a4,:bb4,:c5,:c5,:c5,:d5,:eb5,:d5,:c5,:c5,:bb4,:c5,:d5,:c5,:bb4,:a4,:b4]
dur[v]=[md,c,m,c,c,cd,q,c,c,b,m,m,m,m,b,b,m,m,b,cd,q,c,c,b,c,c,m,m,m,b,b,m,m,cd,q,m,c,c,c,c,c,c,m,c,c,m,m,m,b,b]
tempolist[v]=180
gapslist[v]=8*b
partslist[v]=3
shiftlist[v]=0
v +=1
roundlist[v]='The Spring is Come'
notes[v]=[:bb4,:ab4,:g4,:ab4,:bb4,:eb5,:ab4,:g4,:ab4,:bb4,:eb5,:bb4,:ab4,:g4,:f4,:eb4,:r,:eb4,:r,:eb4,:r,:eb4,:bb3,:bb3,:eb4]
notes[v].concat [:g4,:f4,:eb4,:f4,:g4,:g4,:f4,:eb4,:f4,:g4,:ab4,:g4,:f4,:eb4,:d4,:eb4]
dur[v]=[c,q,c,q,c,c,q,c,q,c,c,c,c,c,c,md,c,m,m,m,m,m,c,c,md,c,q,c,q,c,c,q,c,q,c,c,c,c,c,c,md]
tempolist[v]=160
gapslist[v]=4*b
partslist[v]=3
shiftlist[v]=0
v +=1
roundlist[v]='The Hillside'
notes[v]=[:c5,:b4,:b4,:a4,:a4,:g4,:g4,:f4,:f4,:e4,:c4,:f4,:g4,:c4,:c4,:d4,:e4,:f4,:g4,:e4,:f4,:d4,:e4,:c4,:f4,:g4,:a4,:b4,:c5,:c5,:c5,:b4,:c5]
notes[v].concat [:e5,:e5,:d5,:e5,:c5,:d5,:b4,:c5,:a4,:b4,:c5,:d5,:e5,:e5,:f5,:d5,:d5,:e5]
dur[v]=[m,c,c,c,c,c,c,c,c,c,c,c,c,m,q,q,q,q,c,c,c,c,c,c,q,q,q,q,c,c,c,c,m]
dur[v].concat [cd,q,c,c,cd,q,c,c,q,q,q,q,c,q,q,c,c,m]
tempolist[v]=180
gapslist[v]=8*m
partslist[v]=3
shiftlist[v]=-4
v +=1
roundlist[v]='SUMER IS ICUMEN IN'
notes[v]=[:f5,:e5,:d5,:e5,:f5,:f5,:e5,:d5,:c5,:a4,:a4,:bb4,:g4,:a4,:r,:f4,:a4,:g4,:bb4,:a4,:a4,:g4,:f4,:a4,:c5,:d5,:d5,:c5,:r]
notes[v].concat [:f5,:d5,:f5,:r,:c5,:a4,:bb4,:g4,:a4,:c5,:bb4,:a4,:f4,:a4,:g4,:e4,:f4,:r,:a4,:a4,:g4,:bb4,:c5,:c5,:d5,:e5]
notes[v].concat [:f5,:e5,:d5,:e5,:f5,:r,:c5,:d5,:c5,:bb4,:a4,:f4,:a4,:bb4,:g4,:a4,:bb4,:c5,:a4,:c5,:g4,:e4,:f4,:r]
dur[v]=[c,q,c,q,c,q,q,q,q,c,q,c,q,cd,cd,c,q,c,q,c,q,c,q,c,q,c,q,cd,cd]
dur[v].concat [cd,cd,cd,cd,c,q,c,q,c,q,c,q,c,q,c,q,cd,cd,c,q,c,q,c,q,c,q,c,q,c,q,cd,cd,cd,cd,cd,c,q,c,q,c,q,cd,c,q,c,q,c,q,cd,cd]
notesbass=[:f3,:g3,:f3,:g3,:a3,:c4,:bb3,:c4,:r]*8+[:f3,:g3,:f3]
durbass=[cd,cd,cd,c,q,cd,cd,cd,cd]*8+[cd,cd,cd]
tempolist[v]=160
gapslist[v]=4*cd
partslist[v]=4
shiftlist[v]=-5
#END OF ROUNDS DATA SECTION==============================
end
define :printlist do |num| #prints round info on screen
0.upto(num-1) do |i|
puts "round "+(i+1).to_s+" '"+roundlist[i]+"'"
end
puts "" #blank line
end
define :adjustedchoices do |rlist| #bump choices in list by 1 for printing purposes
alist=[]
0.upto(4) do |i|
alist << (rlist[i]+1)
end
return alist
end
setuprounds(180) #prime the tempolist so it can be used as a parameter for subsequent calls
printlist(num)
#now play the rounds
if selectionmode then
rlist=range(0,num).shuffle #choose 5 rounds from the list in random order
puts "Selection choices: "+adjustedchoices(rlist).to_s #print them
limit=4
else limit=num
end
0.upto(limit) do |i| #play the choices
if selectionmode then
ch=rlist[i]
else
ch=i
end
#adjust duration arrays for correct tempo
setuprounds((tempolist[ch]))
#print info on the screen
puts "round "+(ch+1).to_s+" of "+num.to_s+" now playing:"
puts "'"+roundlist[ch]+"'"
puts partslist[ch].to_s+" voices"
#allocate choices for the current round
notes=notes[ch]
dur=dur[ch]
gaps=gapslist[ch]
shift=shiftlist[ch]
with_fx :reverb,room: 0.6 do #comment out reverb and corresponding end line if on model B or B+
if roundlist[ch]=='SUMER IS ICUMEN IN' then #deal with the special case of bass part for this round
in_thread {plarray(instlist[ch][4][0],instlist[ch][4][1],notesbass,durbass,shift)}
end
in_thread {plarray(instlist[ch][0][0],instlist[ch][0][1],notes,dur,shift)}
sleep gaps
in_thread {plarray(instlist[ch][1][0],instlist[ch][1][1],notes,dur,shift)}
sleep gaps
in_thread {plarray(instlist[ch][2][0],instlist[ch][2][1],notes,dur,shift)}
sleep gaps
if partslist[ch]==4 then #add 4th part if 4 part round
in_thread {plarray(instlist[ch][3][0],instlist[ch][3][1],notes,dur,shift)}
sleep gaps
end
in_thread {plarray(instlist[ch][0][0],instlist[ch][0][1],notes,dur,12+shift)}
sleep gaps
in_thread {plarray(instlist[ch][1][0],instlist[ch][1][1],notes,dur,12+shift)}
sleep gaps
if partslist[ch]==4 then #4 part round
in_thread {plarray(instlist[ch][2][0],instlist[ch][2][1],notes,dur,12+shift)}
sleep gaps
plarray(instlist[ch][3][0],instlist[ch][3][1],notes,dur,12+shift)
else
plarray(instlist[ch][2][0],instlist[ch][2][1],notes,dur,12+shift)
end
sleep b #gap before next round
end #comment out this end if reverb commented out
end
puts "Finished!"
@rbnpi
Copy link
Author

rbnpi commented Mar 9, 2015

This program will probably require customisation for your particular setup. The ideals is a pi2 running Sonic Pi 2.5dev or later, but it can be customised for earlier versions and for other Pi models or Mac OSX or Windows PC.

Configuring the program for your system
The program was developed on a Pi2 which is much more powerful than the previous B and B+ models. On these models the Pi cannot cope with the reverb effect which is applied when a round plays, and so the relevant use_fx :reverb line should be commented out if you are using one of these machines, together with the associated end statement further down, both of which are marked. Also the Round 'SUMER IS ACUMIN IN' which has a 5th drone part will only work on the more powerful machines without casusing sound breakup. This is placed last in the list of rounds, so If you are using a Pi B or model B+ then set the variable num in line to one LESS than the number of rounds, which will exclude this one.
If using a version of Sonic Pi less then 2.5dev, then you will have to reduce the number of rounds in the data list. Simply delete a round section by removing the lines from roundlist[v]='ROUND NAME' up to the corresponding line shiftlist[v]=.
Also remove the PRECEDING v +=1 line.

The overall structure for a round data entry is

v +=1
roundlist[v]='''
notes[v]=[list of notes]
dur[v]=[list of durations]
tempolist[v]=
gapslist[v]=
partslist[v]=
shiftlist[v]=-

The FIRST round has v=0 preceding it instead of v +=1
If you include 'SUMER IS ACUMIN IN' it is a good idea to put it last in the list so that it can be excluded by adjusting the num variable as discussed above. In any case, if you alter the number of rounds you MUST manually adjust the line num = at the start of the program in the initial configuration section, to reflect the number of Rounds you actually have in the program. Changing num adjusts all the other sections that depend on the number of Rounds.

SINCE WRITING THIS, THE ADOPTION OF TCP COMMS WITHIN SONIC PI HAS BEE REVERSED BECAUSE OF STABILITY PROBLEMS, SO AT PRESENT THERE ARE STILL LIMITS ON MAX PROGRAM SIZE.YOU WILL HAVE TO REDUCE THE NUMBER OF ROUNDS IN THE PROGRAM BOTH FOR RPi AND FOR MAC FOR IT TO WORK. HOPEFULLY TCP WILL BE RESTORED BEFORE TOO LONG.
On a Pi or Windows PC with an an early version of Sonic PI, I think that up to about 20 rounds will probably work. On a MAC with an early version of Sonic PI then only about FOUR rounds will work. The symptom is that there will be no response or output from the program if you have too many present. You can of course have different versions of the program each loaded with a different selection of rounds. But this will all be solved when 2.5 is released (or you can build your own 2.5dev version right now).

The final configuration you can do is to alter whether you want to listen to all the rounds in sequence, or to listen to a selection of 5 chosen at random (don't choose this option on a MAC with a pre 2.5dev Sonic Pi as you will only have 4 rounds there!)
This is selected by adjusting the the lines below in the configuration section at the start of the program.

selectionmode=true #set to true for random selection of 5 choices or false to play all 26 rounds
use_random_seed(11111) #change seed number to get a different selection of choices if using selection mode

Setting the selectionmode to false will play all 26 rounds. About 20 minutes worth!
If you set the selectionmode to true, you will always get the same selection made, unless you alter the random seed in the line below. I like to use a 5 digit number here. Try 11111,22222,33333,12345,56789 etc Different numbers will give different selections.

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