├── BachPreludeInC.md ├── BeatlesFiles.md ├── JohnSouch.md ├── Morse.md ├── Playing with Chords and Lists ├── PurcellFuneralMusic.md ├── PurcellREADME.md ├── README.md ├── SonicPiPurcell.zip ├── Tutorial1.md ├── d1.wav └── wolfwhistle.md /BachPreludeInC.md: -------------------------------------------------------------------------------- 1 | ```Ruby 2 | #Bach Prelude in C Major, transcribed by Robin Newman Sept 2014 3 | #tested on Sonic-Pi ver 2.0.1 4 | #illustrates the use of volume settings for each note to allow for crescendo, diminuendo 5 | #also built in rallentando at end of the piece 6 | use_synth :tri #unless specified otherwise 7 | s = 1.0 / 8.5 #tempo about 64 c/minute 8 | 9 | #note durations (not all used) 10 | dsq = 1 * s 11 | sq = 2 * s 12 | q = 4 * s 13 | qd = 6 * s 14 | c = 8 * s 15 | cd = 12 * s 16 | m = 16 * s 17 | md = 24 * s 18 | b = 32 * s 19 | bd = 48 * s 20 | 21 | #dynamic settings 22 | pp = 0.1 23 | p = 0.15 24 | mp = 0.22 25 | mf = 0.3 26 | f = 0.5 27 | 28 | #volumes for part 1 29 | #first set up crescendo over 5 bars from pp to f 30 | cr = [pp] 31 | vol = pp 32 | npb=14#number of note elements/standard bar including rests 33 | inc = (f-pp)/(5*npb) 34 | (5*npb-1).times do 35 | cr = cr + [vol] 36 | vol=vol+inc 37 | end 38 | #now set up diminuendo from f to p over 2 bars 39 | dim = [f] 40 | vol = f 41 | inc = (p-f)/(2*npb) 42 | (2*npb-1).times do 43 | dim = dim + [vol] 44 | vol = vol + inc 45 | end 46 | #now assemble complete volume profile 47 | v1 = [p]*4*npb + [mf]*npb + [mp]*npb + [mf]*npb + [mp]*7*npb + [p]*7*npb +[pp]*2*npb +cr + [f]*npb + dim +[p]*(npb+npb+1+npb+1+1) #adjust for different bar structures at end 48 | 49 | #vols for part 2 50 | cr = [p] 51 | vol = p 52 | npb=4 #4 note +rest elements /standard bar 53 | inc = (f-pp)/(5*npb) 54 | (5*npb-1).times do 55 | cr = cr + [vol] 56 | vol=vol+inc 57 | end 58 | dim = [f] 59 | vol = f 60 | inc = (p-f)/(2*npb) 61 | (2*npb-1).times do 62 | dim = dim + [vol] 63 | vol = vol + inc 64 | end 65 | v2 = [p]*4*npb + [mf]*npb + [mp]*npb + [mf]*npb + [mp]*7*npb + [p]*7*npb +[pp]*2*npb +cr + [f]*npb + dim +[p]*(npb+npb-2+npb-2+1) #adjust for different bar structures at end 66 | 67 | #vols for part 3 68 | pp = 0.5*pp 69 | p = 0.5*p 70 | mp = 0.5*mp 71 | mf = 0.5*mf 72 | f = 0.5*f 73 | cr = [pp] 74 | vol = pp 75 | npb=2 #2 notes per standard bar 76 | inc = (f-pp)/(5*npb) 77 | (5*npb-1).times do 78 | cr = cr + [vol] 79 | vol=vol+inc 80 | end 81 | dim = [f] 82 | vol = f 83 | inc = (p-f)/(2*npb) 84 | (2*npb-1).times do 85 | dim = dim + [vol] 86 | vol = vol + inc 87 | end 88 | v3 = [p]*4*npb + [mf]*npb + [mp]*npb + [mf]*npb + [mp]*7*npb + [p]*7*npb +[pp]*2*npb +cr + [f]*npb + dim +[p]*(npb+1+1+1) #adjust for different bar structures at end 89 | 90 | #definition to play 3 arrays containing note pitch, duration and volume. Can also set global attack and synth 91 | #sustain set to 90% duration, release to 10% duration 92 | define :pl1 do |notearray,durationarray,volarray,attack=(dsq / 2),voice = :tri| 93 | with_synth voice do 94 | notearray.zip(durationarray,volarray).each do |notearray,durationarray,volarray| #zip traverses arrays together 95 | if notearray == :r #a rest 96 | sleep durationarray 97 | else 98 | play notearray,amp: volarray,sustain: durationarray * 0.9 - attack,release: durationarray * 0.1,attack: attack 99 | sleep durationarray 100 | end 101 | end 102 | end 103 | end 104 | 105 | #now define the three parts and the durations for each of their notes 106 | p1n = [:r,:g4,:c5,:e5,:g4,:c5,:e5,:r,:g4,:c5,:e5,:g4,:c5,:e5,:r,:a4,:d5,:f5,:a4,:d5,:f5,:r,:a4,:d5,:f5,:a4,:d5,:f5] 107 | p1d = [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 108 | #b3 109 | p1n.concat [:r,:g4,:d5,:f5,:g4,:d5,:f5,:r,:g4,:d5,:f5,:g4,:d5,:f5,:r,:g4,:c5,:e5,:g4,:c5,:e5,:r,:g4,:c5,:e5,:g4,:c5,:e5] 110 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 111 | #b5 112 | p1n.concat [:r,:a4,:e5,:a5,:a4,:e5,:a5,:r,:a4,:e5,:a5,:a4,:e5,:a5,:r,:fs4,:a4,:d5,:fs4,:a4,:d5,:r,:fs4,:a4,:d5,:fs4,:a4,:d5] 113 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 114 | #b7 115 | p1n.concat [:r,:g4,:d5,:g5,:g4,:d5,:g5,:r,:g4,:d5,:g5,:g4,:d5,:g5,:r,:e4,:g4,:c5,:e4,:g4,:c5,:r,:e4,:g4,:c5,:e4,:g4,:c5] 116 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 117 | #b9 118 | p1n.concat [:r,:e4,:g4,:c5,:e4,:g4,:c5,:r,:e4,:g4,:c5,:e4,:g4,:c5,:r,:d4,:fs4,:c5,:d4,:fs4,:c5,:r,:d4,:fs4,:c5,:d4,:fs4,:c5] 119 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 120 | #b11 121 | p1n.concat [:r,:d4,:g4,:b4,:d4,:g4,:b4,:r,:d4,:g4,:b4,:d4,:g4,:b4,:r,:e4,:g4,:cs5,:e4,:g4,:cs5,:r,:e4,:g4,:cs5,:e4,:g4,:cs5] 122 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 123 | #b13 124 | p1n.concat [:r,:d4,:a4,:d5,:d4,:a4,:d5,:r,:d4,:a4,:d5,:d4,:a4,:d5,:r,:d4,:f4,:b4,:d4,:f4,:b4,:r,:d4,:f4,:b4,:d4,:f4,:b4] 125 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 126 | #b15 127 | p1n.concat [:r,:c4,:g4,:c5,:c4,:g4,:c5,:r,:c4,:g4,:c5,:c4,:g4,:c5,:r,:a3,:c4,:f4,:a3,:c4,:f4,:r,:a3,:c4,:f4,:a3,:c4,:f4] 128 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 129 | #b17 130 | p1n.concat [:r,:a3,:c4,:f4,:a3,:c4,:f4,:r,:a3,:c4,:f4,:a3,:c4,:f4,:r,:g3,:b3,:f4,:g3,:b3,:f4,:r,:g3,:b3,:f4,:g3,:b3,:f4] 131 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 132 | #b19 133 | p1n.concat [:r,:g3,:c4,:e4,:g3,:c4,:e4,:r,:g3,:c4,:e4,:g3,:c4,:e4,:r,:bb3,:c4,:e4,:bb3,:c4,:e4,:r,:bb3,:c4,:e4,:bb3,:c4,:e4] 134 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 135 | #b21 136 | p1n.concat [:r,:a3,:c4,:e4,:a3,:c4,:e4,:r,:a3,:c4,:e4,:a3,:c4,:e4,:r,:a3,:c4,:eb4,:a3,:c4,:eb4,:r,:a3,:c4,:eb4,:a3,:c4,:eb4] 137 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 138 | #b23 139 | p1n.concat [:r,:b3,:c4,:d4,:b3,:c4,:d4,:r,:b3,:c4,:d4,:b3,:c4,:d4,:r,:g3,:b3,:d4,:g3,:b3,:d4,:r,:g3,:b3,:d4,:g3,:b3,:d4] 140 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 141 | #b25 142 | p1n.concat [:r,:g3,:c4,:e4,:g3,:c4,:e4,:r,:g3,:c4,:e4,:g3,:c4,:e4,:r,:g3,:c4,:f4,:g3,:c4,:f4,:r,:g3,:c4,:f4,:g3,:c4,:f4] 143 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 144 | #b27 145 | p1n.concat [:r,:g3,:b3,:f4,:g3,:b3,:f4,:r,:g3,:b3,:f4,:g3,:b3,:f4,:r,:a3,:c4,:fs4,:a3,:c4,:fs4,:r,:a3,:c4,:fs4,:a3,:c4,:fs4] 146 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 147 | #b29 148 | p1n.concat [:r,:g3,:c4,:g4,:g3,:c4,:g4,:r,:g3,:c4,:g4,:g3,:c4,:g4,:r,:g3,:c4,:f4,:g3,:c4,:f4,:r,:g3,:c4,:f4,:g3,:c4,:f4] 149 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 150 | #b31 151 | p1n.concat [:r,:g3,:b3,:f4,:g3,:b3,:f4,:r,:g3,:b3,:f4,:g3,:b3,:f4,:r,:g3,:bb3,:e4,:g3,:bb3,:e4,:r,:g3,:bb3,:e4,:g3,:bb3,:e4] 152 | p1d.concat [q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq] 153 | #b33 154 | p1n.concat [:r,:f3,:a3,:c4,:f4,:c4,:a3,:c4,:a3,:f3,:a3,:f3,:d3,:f3,:d3,:r,:g4,:b4,:d5,:f5,:d5,:b4,:d5,:b4,:g4,:b4,:d4,:f4,:e4,:d4] 155 | #set up the rit in the last bar. (nb chord bar follows this) 156 | p1d.concat [q,sq,sq,sq,sq,sq,sq,sq,sq,sq,sq,sq,sq,sq,sq,q,sq,sq,sq,sq,sq,sq,sq,sq*1.1,sq*1.2,sq*1.3,sq*1.4,sq*1.5,sq*1.6,sq*1.7 ] 157 | 158 | #second part 159 | p2n = [:r,:e4,:r,:e4,:r,:d4,:r,:d4,:r,:d4,:r,:d4,:r,:e4,:r,:e4,:r,:e4,:r,:e4,:r,:d4,:r,:d4,:r,:d4,:r,:d4,:r,:c4,:r,:c4] 160 | p2d = [sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c] 161 | #b9 162 | p2n.concat [:r,:c4,:r,:c4,:r,:a3,:r,:a3,:r,:b3,:r,:b3,:r,:bb3,:r,:bb3,:r,:a3,:r,:a3,:r,:ab3,:r,:ab3,:r,:g3,:r,:g3,:r,:f3,:r,:f3] 163 | p2d.concat [sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c] 164 | #b17 165 | p2n.concat [:r,:f3,:r,:f3,:r,:d3,:r,:d3,:r,:e3,:r,:e3,:r,:g3,:r,:g3,:r,:f3,:r,:f3,:r,:c3,:r,:c3,:r,:f3,:r,:f3,:r,:f3,:r,:f3] 166 | p2d.concat [sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c] 167 | #b25 168 | p2n.concat [:r,:e3,:r,:e3,:r,:d3,:r,:d3,:r,:d3,:r,:d3,:r,:eb3,:r,:eb3,:r,:e3,:r,:e3,:r,:d3,:r,:d3,:r,:d3,:r,:d3,:r,:c3,:r,:c3] 169 | p2d.concat [sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c,sq,qd+c] 170 | #b33 171 | p2n.concat [:r,:c3,:r,:b3,:c3] 172 | #compensate for rit in penultimate bar and add pause 173 | p2d.concat [sq,qd+c+m,sq,qd+c+m+2.8*sq,b*1.1] 174 | 175 | #third part 176 | p3n = [:c4,:c4,:c4,:c4,:b3,:b3,:c4,:c4,:c4,:c4,:c4,:c4,:b3,:b3,:b3,:b3] 177 | p3d = [m,m,m,m,m,m,m,m,m,m,m,m,m,m,m,m] 178 | #b9 179 | p3n.concat [:a3,:a3,:d3,:d3,:g3,:g3,:g3,:g3,:f3,:f3,:f3,:f3,:e3,:e3,:e3,:e3] 180 | p3d.concat [m,m,m,m,m,m,m,m,m,m,m,m,m,m,m,m] 181 | #b17 182 | p3n.concat [:d3,:d3,:g2,:g2,:c3,:c3,:c3,:c3,:f2,:f2,:fs2,:fs2,:ab2,:ab2,:g2,:g2] 183 | p3d.concat [m,m,m,m,m,m,m,m,m,m,m,m,m,m,m,m] 184 | #b25 185 | p3n.concat [:g2,:g2,:g2,:g2,:g2,:g2,:g2,:g2,:g2,:g2,:g2,:g2,:g2,:g2,:c2,:c2] 186 | p3d.concat [m,m,m,m,m,m,m,m,m,m,m,m,m,m,m,m] 187 | #b33 188 | p3n.concat [:c2,:c2,:c2] 189 | #compensate for rit in penultimate bar and add pause 190 | p3d.concat [b,b+2.8*sq,b*1.1] 191 | 192 | #==========start playing here ============ 193 | #now play the piece with some reverb set 194 | with_fx :reverb, room: 0.4 do 195 | #first two parts in threads to play concurrently with third part 196 | in_thread do 197 | #parameters for pl1 are notearray,durationarray,volarray,attack=(dsq / 2),voice = :tri_s 198 | pl1(p1n,p1d,v1) 199 | #play last bar chord, adjusted for pause, vol set to p 200 | play_chord [:e4,:g4,:c5],sustain: 0.9*b*1.1,release: 0.1*b*1.1,amp: p 201 | sleep b * 1.1 202 | end 203 | #second part thread 204 | in_thread do 205 | pl1(p2n,p2d,v2) 206 | end 207 | #third part 208 | pl1(p3n,p3d,v3,0,:saw) 209 | end 210 | ``` 211 | -------------------------------------------------------------------------------- /BeatlesFiles.md: -------------------------------------------------------------------------------- 1 | I have for the moment removed the three Beatles songs, while I investigate possibile copyright issues. 2 | Apologies: however I will be adding further pieces shortly which will definitely NOT have any such issues. 3 | -------------------------------------------------------------------------------- /JohnSouch.md: -------------------------------------------------------------------------------- 1 | ```Ruby 2 | #Sir John Souch his Galiard John Dowland transcribed for Sonic Pi 2 by Robin Newman July 2014 3 | 4 | s = 1.0 / 16 #s is speed multiplier 1.0 / 8 makes crotchet 1s or 60 crotchets/minute the default bpm 5 | #note use of 1.0 to make the variable floating point and not integer 6 | dsq = 1 * s #demi-semi-quaver 7 | sq = 2 * s #semi-quaver 8 | sqd = 3 * s #semi-quaver dotted 9 | q = 4 * s #quaver 10 | qd = 6 * s #quaver dotted 11 | qdd = 7 * s #quaver double dotted 12 | c = 8 * s #crotchet 13 | cd = 12 * s #crotchet dotted 14 | cdd = 14 * s #crotchet double dotted 15 | m = 16 * s #minim 16 | md = 24 * s #minim dotted 17 | mdd = 28 * s #minim double dotted 18 | b = 32 * s #brevea 19 | bd = 48 * s #breve dotted 20 | 21 | use_synth :saw #default 22 | 23 | define :tune do|pitch,duration,shift=0,amp= 0.3| 24 | pitch.zip(duration).each do |p,d| #zip arrays together and traverse them 25 | if p == :r #if a rest, then just wait 26 | sleep d 27 | else #otherwise play a note and wait 28 | with_transpose shift*12 do #transpose if set 29 | play p,sustain: 0.95*d-q/25,release: 0.05*d,attack: q/25,amp: amp 30 | sleep d 31 | end 32 | end 33 | 34 | end 35 | end 36 | #arryas of note pitches and durations follow 37 | n1a = [:c5,:b4,:a4,:gs4,:a4,:b4,:c5,:a4,:gs4,:e5,:d5,:c5,:b4,:g4,:c5,:b4,:a4,:gs4,:a4] 38 | d1a = [m,m,m,md,c,m,m,b,bd,m,m,m,b,c,c+c,m,m,c,bd] 39 | n2a = [:e4,:e4,:e4,:e4,:e4,:e4,:e4,:d4,:e4,:g4,:g4,:g4,:g4,:d4,:e4,:f4,:g4,:e4,:e4,:e4] 40 | d2a = [m,m,m,b,m,md,c,m,bd,m,m,m,m,m,cd,q,m,md,c,bd] 41 | n3a = [:a4,:b4,:c5,:b4,:e4,:e5,:d5,:c5,:b4,:a4,:b4,:c5,:d5,:f5,:e5,:d5,:c5,:b4,:d5,:c5,:d5,:g4,:a4,:b4,:cs5] 42 | d3a = [m,m,m,m,b,m,c,c,c,c,bd,m,c,c,m,cd,q,c,c,m,c,m,c,m,bd] 43 | n4a = [:e4,:e4,:fs4,:gs4,:a4,:b4,:g4,:c5,:a4,:b4,:c5,:d5,:r,:b4,:e5,:e4,:r,:e4,:g4,:a4,:b4,:g4,:g4,:d5,:c5,:b4,:a4] 44 | d4a = [m,md,c,c,c,md,c,c,m,q,q,m,c,c,m,m,c,c,md,c,m,b,c,m,c,m,bd] 45 | n5a = [:a2,:gs2,:a2,:e3,:f3,:g3,:a3,:f3,:e3,:c3,:b2,:c3,:g3,:f3,:e3,:b2,:c3,:a2,:e3,:a2] 46 | d5a = [m,m,m,md,c,m,m,b,bd,m,m,m,md,c,m,m,c,c,m,bd] 47 | define :sec1 do |vol| #first section 48 | in_thread do #play the various parts together using threads 49 | tune(n1a,d1a,0,vol) 50 | end 51 | in_thread do 52 | tune(n2a,d2a,0,vol) 53 | end 54 | in_thread do 55 | tune(n3a,d3a,-1,vol*1.2) 56 | end 57 | in_thread do 58 | tune(n4a,d4a,-1,vol*1.2) 59 | end 60 | tune(n5a,d5a,0,vol) 61 | end 62 | #define notes and durations for the second section 63 | n1b = [:g4,:a4,:g4,:f4,:e4,:d4,:e4,:f4,:g4,:c5,:b4,:c5,:a4,:b4,:c5,:d5,:c5,:b4,:a4,:gs4] 64 | d1b = [m,m,cd,q,cd,q,c,c,m,b,m,bd,m,m,m,b,m,m,b,bd] 65 | n2b = [:e4,:g4,:f4,:e4,:d4,:c4,:d4,:e4,:f4,:g4,:f4,:e4,:f4,:a4,:g4,:f4,:e4,:f4,:a4,:g4,:f4,:e4,:f4,:d4,:f4,:e4,:e4,:d4,:e4] 66 | d2b = [c,c,c,c,m,md,c,cd,q,c,q,q,c,c,cd,q,bd,c,c,md,q,q,md,c,c,c,b,m,bd] 67 | n3b = [:b4,:e5,:d5,:c5,:b4,:c5,:b4,:a4,:g4,:g4,:d5,:c5,:c5,:f5,:d5,:e5,:a4,:d5,:b4,:c5,:d5,:e5,:d5,:c5,:b4,:a4,:b4] 68 | d3b = [c,c,c,m,c,md,q,q,m,m,b,bd,c,c,c,m,c+c,m,c,cd,q,c,m,m,q,q,bd] 69 | n4b = [:g4,:c5,:a4,:a4,:d5,:g4,:a4,:b4,:c5,:c5,:d5,:e5,:a4,:a4,:b4,:g4,:g4,:a4,:f4,:g4,:a4,:b4,:g4,:c5,:a4,:a4,:b4,:c5,:b4,:g4,:a4,:e5,:e4] 70 | d4b = [c,c,cd,q,c,c+c,q,q,m,cd,q,m,cd,q,c,c,bd,c,c,q,q,q,q,m,m,m+q,q,c+q,q,c,b,m,b] 71 | n5b = [:e3,:f3,:g3,:c3,:e3,:d3,:c3,:f3,:d3,:g3,:c3,:f3,:d3,:g3,:e3,:a3,:d3,:e3,:f3,:g3,:a3,:g3,:f3,:e3] 72 | d5b = [m,m,m,b+c,c+c,q,q,c,c,m,bd,c,c,c,c,m,cd,q,cd,q,m,m,b,bd] 73 | define :sec2 do |vol| #define section 2 play 74 | in_thread do #play the 5 parts using 4 threads and one direct 75 | tune(n1b,d1b,0,vol) 76 | end 77 | in_thread do 78 | tune(n2b,d2b) 79 | end 80 | in_thread do 81 | tune(n3b,d3b,-1,vol*1.2) 82 | end 83 | in_thread do 84 | tune(n4b,d4b,-1,vol*1.2) 85 | end 86 | tune(n5b,d5b,0,vol) 87 | end 88 | #define section 3 notes and durations 89 | n1c = [:r,:e5,:c5,:e5,:d5,:r,:c5,:a4,:c5,:b4,:c5,:b4,:a4,:gs4,:r,:r,:d5,:b4,:g4,:c5,:a4,:b4,:a4,:gs4,:a4,:b4,:a4] 90 | d1c = [c,c,c,m,c,c,c,c,m,c,md,c,m,b,m,c,c,c,c,c,c,b,m,md,c,m,bd] 91 | n2c = [:r,:g4,:e4,:g4,:f4,:e4,:f4,:a4,:g4,:f4,:e4,:e4,:d4,:e4,:r,:a4,:g4,:g4,:g4,:fs4,:g4,:d4,:e4,:d4,:e4,:e4,:e4] 92 | d2c = [c,c,c,m,c,m,c,m,c+c,cd,q,m,c,b,c,c,m,c,m,c,m,c,m,c,b,m,bd] 93 | n3c = [:c5,:c5,:b4,:c5,:e5,:d5,:e5,:e5,:e5,:d5,:c5,:b4,:a4,:b4,:c5,:d5,:e5,:d5,:d5,:b4,:g4,:c5,:a4,:b4,:a4,:gs4,:a4] 94 | d3c = [md,c,m,c,c,c,cd,q,c+c,c,md,q,q,b,m,md,m,c+c,c,c,c,c,c,md,m,c,bd] 95 | n4c = [:g4,:g4,:r,:c4,:f4,:e4,:f4,:g4,:a4,:a4,:d5,:b4,:e4,:b4,:e4,:a4,:g4,:r,:d5,:b4,:e5,:b4,:c5,:b4,:b4,:cs5] 96 | d4c = [b,m,c,c,c,cd,q,c,m,md,c,m,b,md,c,m,b,c,c,c,cd,q,c,cd,q,bd] 97 | n5c = [:c3,:g2,:a2,:d3,:a2,:e3,:a3,:g3,:f3,:e3,:d3,:c3,:b2,:g2,:c3,:a2,:d3,:g2,:e3,:c3,:f3,:e3,:a2] 98 | d5c = [b,m,m,c,c,m,md,c,m,md,c,m,m,c,c,c,c,md,c,c,c,bd,bd] 99 | define :sec3 do |vol| #define section 3 play 100 | in_thread do 101 | tune(n1c,d1c,0,vol) 102 | end 103 | in_thread do 104 | tune(n2c,d2c,0,vol) 105 | end 106 | in_thread do 107 | tune(n3c,d3c,-1,vol*1.2) 108 | end 109 | in_thread do 110 | tune(n4c,d4c,-1,vol*1.2) 111 | end 112 | tune(n5c,d5c,0,vol) 113 | end 114 | with_fx :reverb,room: 0.6 do #add some reverb 115 | sec1(0.4) #play sectgions adjusting volumes 116 | sec1(0.2) 117 | with_synth :tri do #change synth for middle section 118 | sec2(0.4) 119 | sec2(0.2) 120 | end 121 | sec3(0.2) 122 | sec3(0.4) 123 | end 124 | ``` 125 | -------------------------------------------------------------------------------- /Morse.md: -------------------------------------------------------------------------------- 1 | ```Ruby 2 | #sonic-pi 2 does morse! by Robin Newman 28th June 2014 3 | #you can send a-zA-Z and 0-9 and ,.!? (other characters could be added) 4 | msg = "Sonic Pi 2 can generate morse code." #the message to be sent 5 | 6 | 7 | sp = 0.08 #set the speed 0.08 is about 18 words/minute 8 | dit = 1 * sp #timings for individual elements 9 | dah = 3 * sp 10 | gs = 1 * sp #gap between elements 11 | cs = 3 * sp #gap between characters 12 | ws = 7 * sp -cs # gap between words (cs already included by playarray so subtract it) 13 | pt = :c6 #note pitch 14 | 15 | note=[] #empty arrays for note and durations 16 | dur=[] 17 | #define alphabetic characters each is an array entry for notes and for durations 18 | a = [[pt,pt],[dit,dah]] 19 | b = [[pt,pt,pt,pt],[dah,dit,dit,dit]] 20 | c = [[pt,pt,pt,pt],[dah,dit,dah,dit]] 21 | d = [[pt,pt,pt],[dah,dit,dit]] 22 | e = [[pt],[dit]] 23 | f = [[pt,pt,pt,pt],[dit,dit,dah,dit]] 24 | g = [[pt,pt,pt],[dah,dah,dit]] 25 | h = [[pt,pt,pt,pt],[dit,dit,dit,dit]] 26 | i = [[pt,pt],[dit,dit]] 27 | j = [[pt,pt,pt,pt],[dit,dah,dah,dah]] 28 | k = [[pt,pt,pt],[dah,dit,dah]] 29 | l = [[pt,pt,pt,pt],[dit,dah,dit,dit]] 30 | m = [[pt,pt],[dah,dah]] 31 | n = [[pt,pt],[dah,dit]] 32 | o = [[pt,pt,pt],[dah,dah,dah]] 33 | p = [[pt,pt,pt,pt],[dit,dah,dah,dit]] 34 | q = [[pt,pt,pt,pt],[dah,dah,dit,dah]] 35 | r = [[pt,pt,pt],[dit,dah,dit]] 36 | s = [[pt,pt,pt],[dit,dit,dit]] 37 | t = [[pt],[dah]] 38 | u = [[pt,pt,pt],[dit,dit,dah]] 39 | v = [[pt,pt,pt,pt],[dit,dit,dit,dah]] 40 | w = [[pt,pt,pt],[dit,dah,dah]] 41 | x = [[pt,pt,pt,pt],[dah,dit,dit,dah]] 42 | y = [[pt,pt,pt,pt],[dah,dit,dah,dah]] 43 | z = [[pt,pt,pt,pt],[dah,dah,dit,dit]] 44 | #put characters in a lookup array 45 | lookup = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z] 46 | #traverse the characters in the message converted to lowercase and to byte values 47 | msg.downcase.each_byte do|ch| 48 | case ch #deal with non-alphabetic characters 49 | #nb a "rest" of appropriate duration is added after each 50 | when 32 #space 51 | note << :r 52 | dur << ws #for word gap 53 | when 33 # exclamation mark 54 | note << [pt,pt,pt,pt]<< :r 55 | dur << [dah,dah,dah,dit]<< cs 56 | when 63 #question mark 57 | note << [pt,pt,pt,pt,pt,pt]<< :r 58 | dur << [dit,dit,dah,dah,dit,dit]<< cs 59 | when 46 # fullstop 60 | note << [pt,pt,pt,pt,pt,pt]<< :r 61 | dur << [dit,dah,dit,dah,dit,dah]<< cs 62 | when 44 #comma 63 | note << [pt,pt,pt,pt,pt,pt]<< :r 64 | dur << [dah,dah,dit,dit,dah,dah]<< cs 65 | when 45 # hyphen 66 | note << [pt,pt,pt,pt,pt,pt]<< :r 67 | dur << [dah,dit,dit,dit,dit,dah]<< cs 68 | when 48 #0 69 | note << [pt,pt,pt,pt,pt]<< :r 70 | dur << [dah,dah,dah,dah,dah]<< cs 71 | when 49 #1 72 | note << [pt,pt,pt,pt,pt]<< :r 73 | dur << [dit,dah,dah,dah,dah]<< cs 74 | when 50 #2 75 | note << [pt,pt,pt,pt,pt]<< :r 76 | dur << [dit,dit,dah,dah,dah]<< cs 77 | when 51 #3 78 | note << [pt,pt,pt,pt,pt]<< :r 79 | dur << [dit,dit,dit,dah,dah]<< cs 80 | when 52 #4 81 | note << [pt,pt,pt,pt,pt]<< :r 82 | dur << [dit,dit,dit,dit,dah]<< cs 83 | when 53 #5 84 | note << [pt,pt,pt,pt,pt]<< :r 85 | dur << [dit,dit,dit,dit,dit]<< cs 86 | when 54 #6 87 | note << [pt,pt,pt,pt,pt]<< :r 88 | dur << [dah,dit,dit,dit,dit]<< cs 89 | when 55 #7 90 | note << [pt,pt,pt,pt,pt]<< :r 91 | dur << [dah,dah,dit,dit,dit]<< cs 92 | when 56 #8 93 | note << [pt,pt,pt,pt,pt]<< :r 94 | dur << [dah,dah,dah,dit,dit]<< cs 95 | when 57 #9 96 | note << [pt,pt,pt,pt,pt]<< :r 97 | dur << [dah,dah,dah,dah,dit]<< cs 98 | else #otherwise it is an alphabetic character 99 | note << lookup[ch - 97][0].flatten << :r #look it up in the lookup array 100 | #97 = a which is first char in array so subtract 97 to get index 0 101 | dur << lookup[ch - 97][1].flatten << cs #flatten removes the [] 102 | end 103 | end 104 | 105 | 106 | define :playarray do |narray,darray,shift=0,vol=0.3,voice = :saw| 107 | with_synth voice do 108 | narray.zip(darray).each do |narray,darray| 109 | if narray == :r #if a gap or rest wait the required time 110 | sleep darray 111 | else 112 | with_transpose shift do #allows transposition (may be 0) 113 | play narray,amp: vol,sustain: darray * 0.9,release: darray * 0.1 #play note 114 | sleep darray + gs #gap till next note 115 | end 116 | end 117 | end 118 | end 119 | end 120 | 121 | playarray(note.flatten,dur.flatten,0) #remove remaining [] and send arrays to playarray, Third param is transpose shift 122 | ``` 123 | -------------------------------------------------------------------------------- /Playing with Chords and Lists: -------------------------------------------------------------------------------- 1 | #Playing with chords and lists on Sonic-Pi 2 2 | There are two commands which will play chords on Sonic-Pi 2. The first one looks like this:- you can type it in a new Worksheet 3 | ```ruby 4 | play_chord [:c4, :e4, :g4] 5 | ``` 6 | note there must be a space between chord and the opening [. This will sound the three notes together. If you want you can have more than three notes, by typing further notes separated by commas in the list between the [ ]. If you add the next two lines and run the program again, you will see the alternative way of playing a three note chord: 7 | ```ruby 8 | play_chord [:c4, :e4, :g4] 9 | sleep 1 10 | play chord(:c4,:major) 11 | ``` 12 | In this case we describe the chord in a slightly different way. You type the bottom note or the tonic of the chord (here :c4) and follow it with the type of chord you want to play, after a separating comma. In this case we play a C major chord. Other types you could try are ~ :minor, :dom7, :dim7 and there are a host of others. Some contain numbers and have to be put inside apostrophes or speech marks, eg '11+' or "m+5", but that goes a bit further than we will just now 13 | What we are going to do is to explore the way Sonic-Pi holds details of the notes when the chord is played, and how we can manipulate and change chords. 14 | Add the last line below, and press run again: 15 | ```ruby 16 | play_chord [:c4, :e4, :g4] 17 | sleep 1 18 | play chord(:c4,:major) 19 | puts chord(:c4,:major) 20 | ``` 21 | You will hear the two chords, which sound identical, and if you look at the output pane, you will see [60, 64, 67] in blue type. This is produced by the puts command which asks Sonic-Pi to print what follows, in this case chord(:c4,:major) and the result is a list of three numbers, separated by commas inside square brackets. 22 | This is same way that the first play_chord specified the notes to be played, but we see the equivalent midi-note numbers corresponding to the symbols :c4, :e4 and :g4 23 | We can in fact ask Sonic_pi to do the conversion for us explicitly by adding 3 further lines to get: 24 | ```ruby 25 | play_chord [:c4, :e4, :g4] 26 | sleep 1 27 | play chord(:c4,:major) 28 | puts chord(:c4,:major) 29 | puts note_info(:c4).midi_note 30 | puts note_info(:e4).midi_note 31 | puts note_info(:g4).midi_note 32 | ``` 33 | #Looking at a list and changing it 34 | The last three similar commands asks Sonic_Pi to print in the output pane information about the note in the form of its midi note number, and we will see the answers 60 64 and 67 again, one on each line. 35 | Now we will use another idea. We are going to store the list of notes in the chord in a variable which we will call nlist. This is rather like a box in which we will put a piece of aper with sopme information on it. Later we can go back to the box and get the piece of paper and read what is on it. Add a further two lines (you can miss out the comments - the bits after the # if you don't want to type too much) to give: 36 | ```ruby 37 | play_chord [:c4, :e4, :g4] 38 | sleep 1 39 | play chord(:c4,:major) 40 | puts chord(:c4,:major) 41 | puts note_info(:c4).midi_note 42 | puts note_info(:e4).midi_note 43 | puts note_info(:g4).midi_note 44 | nlist = chord(:c4,:major) #stores the notes in the chord like writing on a bit of paper, in the variable or box nlist 45 | puts nlist #gets the contents of nlist (like what is written on the piece of paper in the box, and prints them 46 | ``` 47 | When you run this you will see an addition [60, 64, 67] at the bottom of the output pane. 48 | This is called a list. It has three items in it, the numbers 60 64 and 67. We can change the list by adding extra numbers, or by taking some away, or by altering their order. These are all things that can be done in teh Ruby language in which Sonic-Pi is written. 49 | First we will add an extra number on the end, which will give us a four note chord when we play it. Add the extra lines onto the program show below: 50 | ```ruby 51 | play_chord [:c4, :e4, :g4] 52 | sleep 1 53 | play chord(:c4,:major) 54 | puts chord(:c4,:major) 55 | puts note_info(:c4).midi_note 56 | puts note_info(:e4).midi_note 57 | puts note_info(:g4).midi_note 58 | nlist = chord(:c4,:major) #stores the notes in the chord like writing on a bit of paper, in the variable or box nlist 59 | puts nlist #gets the contents of nlist (like what is written on the piece of paper in the box, and prints them 60 | nlist = nlist + [:c5] 61 | sleep 1 62 | play_chord nlist 63 | puts nlist 64 | ''' 65 | When you run this you will hear three chords played. The first two are identical 3 note chords. The last one plays the four note chord we have generated, and the final puts nlist command prints out the list of four notes on the output screen 66 | Notice how we add the extra note to the list. We don't just say + :c5 We have to put it into a one element list [:c5] - a list with one pice of information in it - and then we add the two lists together to make a single longer list. It is like having a line of three railway trucks couple together (our nlist) and we couple another line of 1 trucks onto the end, giving a longer line of four trucks. The trucks themselves could be different: a coal truck, a cement truck, a flatbed truck (like the different notes in this case), but they are all trucks and can be joined together. 67 | nlist doesn't know about notes, so the list contains three numbers and one symbol :c4. All will be converted to midi numbers when they are played by the play_chord command. We could have done it ourselves by adding 72 instead of :c5 to the list. 68 | #moving things around 69 | Now we will go back to the original C major chord play chord(:c4,:major). If you have done any music theory, you may have come across the idea of chord inversions. To produce the first inversion of the chord, we take the bottom note off the chord, put it up an octave, and add it on the top. So our chord :c4, :e4, :g4 becomes the chord :e4, :g4, :c5 We can of course do this manually, but since we are playing with lists we can get Ruby commands to do it for us. 70 | For this section it is easiest to start with a fresh workspace. You can use the save button to save what we have done so far, if you wish, but then delete everything in the workspace, or select another empty one. 71 | Now type in the following code: 72 | ```ruby 73 | nlist = chord(:c4,:major) 74 | puts nlist 75 | play_chord nlist 76 | sleep 1 77 | n0 = nlist[0] 78 | puts n0 79 | nremainder = nlist[1..-1] 80 | ntop = [n0 + 12] #adding 12 puts it up an octave 81 | n1stinversion = nremainder + ntop #add two lists together to get the final inversion chord list 82 | puts n1stinversion 83 | play_chord n1stinversion 84 | ``` 85 | If you run this you will hear the original C major chord, and see its note list printed in the output pane. [60, 64, 67]. After a second delay you will hear the first inversion chord play, and see its note list on the output screen [64, 67, 72] 86 | So how does this work? Ruby does the work for us. the line n0 = nlist[0] creates another variable (or storage box) called n0. It stores in it the first element or number in the list stored in nlist. ONe thing to note, is that when you are referring to the number in a list, Ruby numbers them from 0, not from 1. So the first element or number is element 0, the second one element 1 and so on. 87 | so n0 has the number 60 stored in it. If you want to check this you could add the line puts n0 just after the line n0 = nlist[0] 88 | The next line is a bit trickier. We make another variable called nremainder and in it we store a list of the remaining two numbers in nlist. The syntax or grammar of how this is done is to use nlist[1..-1] This means starting with element 1 (remember this will be the second number of the three in the list as they number from 0) go up to the last number (-1) however many there are. It looks a bit odd, but that is the way it works. 89 | The next thing to do is to make the note number for the final note to go on the top of the chord. Since there are 12 semitones in an octave, the midi note number for notes an octave apart differ by 12, 1 for each semitone. So the top note which we will store in another variable called ntop is produced by the line: 90 | ```ruby 91 | ntop = [n0 + 12] #adding 12 puts it up an octave 92 | ``` 93 | Note that we put the new note number inside [ ] before storing it in ntop. This makes ntop a LIST containing a single element rather than just a number. 94 | The final stage of the process is to add to the two LISTS nremainder and ntop together giving us the new inverted chord LIST. That is done by the line 95 | ```ruby 96 | n1stinversion = nremainder + ntop #add two lists together to get the final inversion chord list 97 | ``` 98 | Finally we can print this new list to the output pane and play the resulting chord, which is what the last two lines do. 99 | #Where next? 100 | In this tutorial we have looked at how chords are played and represented in Sonic_pi. We have also seen how Ruby LISTS can be manipulated to produce new chords. As an exercise you might like to go through a similar process to the one we have used to produce the firstinversion of C major to produce the second inversion. You want to remove the new bottom note of the chord, put it up an octave and add it on the top again. 101 | Lists are used a lot in Sonic-Pi. You might also like to explore the command to reverse the items in a list. For example 102 | ```ruby 103 | n = [:c4, :d4,:e4, :f4, :g4, :a4, :b4, :c5] 104 | ``` 105 | is the list of notes in a C major scale. 106 | If you type this in and then type: 107 | ```ruby 108 | use_bpm 240 109 | play_pattern n 110 | ``` 111 | it will play this scale. You can then try adding the following lines 112 | ```ruby 113 | sleep 1 114 | play_pattern n.reverse 115 | sleep 1 116 | ``` 117 | These modify the list containing the scale. The first reverses it, the second selects each element once at random. 118 | Have fun! 119 | play_pattern n.shuffle 120 | 121 | 122 | -------------------------------------------------------------------------------- /PurcellFuneralMusic.md: -------------------------------------------------------------------------------- 1 | ```Ruby 2 | #The Queen's Funeral Music by Henry Purcell transcribed by Robin Newman for Sonic Pi 2. Sept 2014 3 | #REQUIRES SAMPLE :d1 TO BE INSTALLED ON YOUR SYSTEM 4 | #combines synth for instruments and a sample for the drum 5 | #also features trills and rits 6 | set_sched_ahead_time! 4 #on RPi 4, Mac 0.25 7 | #on an RPi turn off Print output in prefs 8 | #select the appropriate line below for your system, and adjust where you have saved the sample d1 9 | #use_sample_pack '/users/rbn/Desktop/samples' #comment out when using Raspberry Pi 10 | use_sample_pack '/home/pi/samples' #comment out when using a Mac 11 | load_sample :d1 12 | 13 | use_synth :saw 14 | s = 1.0 / 8#s is speed multiplier to give correct tempo 15 | #note use of 1.0 to make the variable floating point and not integer 16 | 17 | sh=0 #transpose shift. Can alter if you want 18 | 19 | #The following are variables for note durations values defined in setup function 20 | dsq=sq=sqd=q=qd=qdd=c=cd=cdd=m=md=mdd=b=bd=1*s #declare note duration variables here to make them global 21 | 22 | define :setup do |s| #actual note timings defined here 23 | dsq = 1 * s #demi-semi-quaver 24 | sq = 2 * s #semi-quaver 25 | sqd = 3 * s #semi-quaver dotted 26 | q = 4 * s #quaver 27 | qd = 6 * s #quaver dotted 28 | qdd = 7 * s #quaver double dotted 29 | c = 8 * s #crotchet 30 | cd = 12 * s #crotchet dotted 31 | cdd = 14 * s #crotchet double dotted 32 | m = 16 * s #minim 33 | md = 24 * s #minim dotted 34 | mdd = 28 * s #minim double dotted 35 | b = 32 * s #breve 36 | bd = 48 * s #breve dotted 37 | end 38 | 39 | define :bass4 do |x| 40 | i=1 41 | 4.times do 42 | sample :d1,amp:1+ i,start: 0.01,finish: 1 43 | sleep x/4 44 | i=i+1 45 | end 46 | end 47 | 48 | define :bass1 do |x,amp = 4| 49 | sample :d1,amp: amp,start: 0.01,finish: 1 50 | sleep x 51 | end 52 | 53 | define :rbass do 54 | bass1(cd,4) 55 | bass1(q,2) 56 | bass1(c,3) 57 | bass1(c,4) 58 | end 59 | 60 | define :tune do|pitch,duration,shift=0,amp= 0.3,ratio = 0.9| 61 | pitch.zip(duration).each do |p,d| 62 | if p == :r 63 | sleep d 64 | else 65 | with_transpose shift do 66 | play p,sustain: ratio*d,release: (1-ratio)*d,attack: 0,amp: amp 67 | sleep d 68 | end 69 | end 70 | end 71 | end 72 | 73 | define :trn do |n,num,offset=2| #produces trill sequence using n and tone (or semitone) above: n notes total 74 | n = note_info(n).midi_note 75 | return [n+offset,n]*(num / 2) #trill set to start on upper note. Can be swapped over 76 | end 77 | define :trd do |d,num| #produces trill note durations. d is total duration, num number of notes 78 | return [d/num]*num 79 | end 80 | 81 | setup(1.0/8)#check values of durations correct to set up the arrays 82 | n1 = [:g4,:ab4]+trn(:ab4,14)+[:g4,:ab4,:g4,:r,:g4,:c5,:c5,:b4,:r,:d5,:c5,:a4,:bb4,:r,:bb4,:ab4,:f4,:g4,:r,:c5,:c5,:b4,:c5] 83 | d1 = [b,m]+trd(c+qd,14)+[dsq,dsq,b,b,b,m,m,b,b,b,m,m,b,b,b,m,m,b,b,b,m,m,b*1.2] #add pause on last note 84 | n2 = [:e4,:f4,:f4,:e4,:r,:eb4,:eb4,:f4,:g4,:r,:bb4,:a4,:fs4,:g4,:r,:g4,:f4,:d4,:eb4,:r,:g4,:ab4,:g4,:e4] 85 | d2 = [b,m,m,b,b,b,m,m,b,b,b,m,m,b,b,b,m,m,b,b,b,m,m,b*1.2] 86 | n3 = [:c4,:c4,:c4,:c4,:r,:c4,:c4,:c4,:d4,:r,:g4,:eb4,:d4,:d4,:r,:eb4,:c4,:bb3,:bb3,:r,:eb4,:d4,:d4,:c4] 87 | d3 = [b,m,m,b,b,b,m,m,b,b,b,m,m,b,b,b,m,m,b,b,b,m,m,b*1.2] 88 | n4 = [:c3,:f3,:f3,:c3,:r,:c3,:ab3,:ab3,:g3,:r,:g3,:c4,:d4,:g3,:r,:eb3,:ab3,:bb3,:eb3,:r,:c3,:f3,:g3,:c3] 89 | d4 = [b,m,m,b,b,b,m,m,b,b,b,m,m,b,b,b,m,m,b,b,b,m,m,b*1.2] 90 | 91 | define :sec1 do |x| 92 | #drum part solo bar 93 | bass4(b) 94 | 95 | in_thread do #now start synced parts together 96 | i=1 97 | 5.times do #drum part 98 | rbass 99 | bass1(m) 100 | bass1(m) 101 | bass4(b) 102 | if i<5 103 | rbass 104 | end 105 | i=i+1 106 | end 107 | end 108 | sleep 0.02 #sync bodge to get timing right with drums 109 | in_thread do #start synth parts after sync timing 110 | tune(n1,d1,sh,x,0.95) 111 | end 112 | in_thread do 113 | tune(n2,d2,sh,x,0.95) 114 | end 115 | in_thread do 116 | tune(n3,d3,sh,x,0.95) 117 | end 118 | tune(n4,d4,sh,x,0.95 ) 119 | end 120 | 121 | setup(1.0/16) #set timings for canzon (a bit faster) 122 | define :trsetup do #timings for trill in section 1 123 | y=dsq 124 | yd=[dsq] 125 | total=dsq #for debugging 126 | inc=(2*c-12*dsq) #increase in time per note calculated 127 | inc=inc/66 #on these two lines 128 | 11.times do 129 | y=y + inc 130 | total=total+y 131 | yd = yd + [y] 132 | end 133 | #puts total 134 | return yd 135 | end 136 | 137 | n1b = [:r,:c5,:c5,:c5,:d5,:eb5,:d5,:eb5,:b4,:c5,:d5,:eb5,:f5,:b4,:b4,:g5,:g5,:r,:f5,:f5,:r,:eb5,:eb5,:r,:d5,:d5] 138 | d1b = [b,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,m,c,c,m,c,c,m,c,c] 139 | n1b.concat [:r,:b4,:c5,:d5,:eb5,:d5,:eb5,:f5,:g5,:g5,:g5,:g5,:ab5,:g5,:ab5,:f5,:g5,:f5,:g5,:eb5,:f5,:eb5,:f5,:g5,:eb5,:d5]+trn(:d5,12,1)+[:c5,:c5] 140 | d1b.concat [c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c*1.1,c*1.2]+trsetup+[q*1.4,b*1.2] 141 | n2b = [:g4,:g4,:g4,:g4,:ab4,:g4,:ab4,:f4,:g4,:f4,:g4,:d4,:eb4,:f4,:g4,:ab4,:g4,:g4,:r,:c5,:c5,:r,:bb4,:bb4,:r,:ab4,:ab4,:r] 142 | d2b = [c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,m,c,c,m,c,c,m,c,c,m] 143 | n2b.concat [:g4,:g4,:r,:c5,:c5,:c5,:d5,:eb5,:d5,:eb5,:c5,:f5,:eb5,:f5,:d5,:eb5,:d5,:eb5,:c5,:d5,:c5,:d5,:d5,:g4,:a4,:g4,:g4,:e4] 144 | d2b.concat [c,c,m,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c*1.1,c*1.2,c*1.3,c*1.4,b*1.2] 145 | n3b = [:r,:c4,:c4,:c4,:d4,:eb4,:d4,:eb4,:b3,:c4,:eb4,:f4,:c4,:eb4,:d4,:eb4,:c4,:d4,:c4,:d4,:f4] 146 | d3b = [b*3,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c] 147 | n3b.concat [:eb4,:d4,:eb4,:f4,:g4,:g4,:r,:eb4,:eb4,:r,:d4,:d4,:r,:c4,:c4,:c4,:c4,:b3,:b3,:c4,:c4,:b3,:b3,:c4] 148 | d3b.concat [c,c,c,c,c,c,b,c,c,m,c,c,m,c,c,c,c,c,c,c*1.1,c*1.2,c*1.3,c*1.4,b*1.2] 149 | n4b = [:r,:g3,:g3,:g3,:g3,:ab3,:g3,:ab3,:f3,:g3,:f3,:g3,:eb3,:f3,:eb3,:f3,:bb2] 150 | d4b = [4*b,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c] 151 | n4b.concat [:eb3,:eb3,:eb4,:d4,:c4,:c4,:r,:c4,:c4,:r,:f3,:f3,:r,:eb3,:eb3,:r,:ab3,:f3,:ab3,:g3,:g3,:c4,:f3,:g3,:g3,:c3] 152 | d4b.concat [c,c,c,c,c,c,m,c,c,m,c,c,m,c,c,c,c,c,c,c,c,c*1.1,c*1.2,c*1.3,c*1.4,b*1.2] 153 | define :sec2 do |x| 154 | in_thread do 155 | with_merged_synth_defaults pan: -0.7 do 156 | tune(n1b,d1b,sh,x,0.95) 157 | end 158 | end 159 | in_thread do 160 | with_merged_synth_defaults pan: 0.7 do 161 | tune(n2b,d2b,sh,x,0.95) 162 | end 163 | end 164 | in_thread do 165 | with_merged_synth_defaults pan: -0.4 do 166 | tune(n3b,d3b,sh,x,0.95) 167 | end 168 | end 169 | with_merged_synth_defaults pan: 0.4 do 170 | tune(n4b,d4b,sh,x,0.95) 171 | end 172 | end 173 | 174 | #set up trill durations with rall used in part n1c 175 | define :ysetup do |t| #change t to 2 for smaller rit 176 | y=dsq 177 | yd=[dsq] 178 | total=dsq 179 | inc = c*1.2/t/276 #increase in time per note 180 | 23.times do 181 | y=y + inc 182 | total=total+y 183 | yd = yd + [y] 184 | end 185 | puts total 186 | return yd 187 | end 188 | 189 | #define arrays for sec3 here to make them global 190 | tr=dr=n1c=n2c=n3c=n4c=d1c=d2c=d3c=d4c=[] 191 | 192 | define :setuppart3 do |n| #change n 1 or 2 for 1st time 2nd time 193 | case n 194 | when 1 195 | p2=1.5 196 | p3=1.3 197 | p4=1.7 198 | p5=1.2 199 | p6=1.4 200 | p7=1.6 201 | p8=1.8 202 | when 2 203 | p2=1.2 204 | p3=1.15 205 | p4=1.35 206 | p5=1.1 207 | p6=1.2 208 | p7=1.3 209 | p8=1.4 210 | end 211 | #last two bars for part n1c with trill and rall 212 | tr = trn(:d5,24,1)+[:c5,:c5] 213 | dr = ysetup(n) + [c*p8,b*p2] 214 | 215 | n1c = [:g5,:g5,:g5,:g5,:ab5,:g5,:ab5,:f5,:g5,:f5,:g5,:eb5,:f5,:eb5,:f5,:g5,:eb5,:ab5,:ab5,:g5,:g5,:r,:f5,:f5,:r,:eb5,:eb5,:r] 216 | d1c = [c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,m,c,c,c,c,m,c,c,m,c,c,m] 217 | n1c.concat [:d5,:c5,:bb4]+trn(:a4,12,1)+[:g4,:g4,:g4,:g5,:g5,:d5,:d5,:eb5,:eb5,:b4,:b4,:c5,:c5,:d5,:d5,:d5,:d5,:d5,:d5,:d5,:d5] #add last 2 bars with trill here 218 | d1c.concat [c,q,q]+trd(cd,12)+[q,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c] #add duration last 2 bars with trill 219 | n2c = [:r,:c5,:c5,:c5,:d5,:eb5,:d5,:eb5,:c5,:d5,:c5,:d5,:b4,:c5,:c5,:c5,:c5,:r,:c5,:c5,:r,:bb4,:bb4,:r,:ab4,:ab4] 220 | d2c = [b,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,m,c,c,m,c,c,m,c,c] 221 | n2c.concat [:r,:g4,:g4,:fs4,:g4,:g4,:eb5,:eb5,:b4,:b4,:c5,:c5,:d5,:d5,:eb5,:eb5,:b4,:b4,:c5,:c5,:c5,:c5,:c5,:c5,:c5,:b4,:c5] 222 | d2c.concat [c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,m*p3,m*p4,b*p2] 223 | n3c = [:r,:g4,:g4,:g4,:g4,:ab4,:g4,:ab4,:f4,:g4,:f4,:g4,:eb4,:f4,:eb4,:f4,:d4,:eb4,:d4,:eb4,:c4] 224 | d3c = [b*3,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c] 225 | n3c.concat [:d4,:eb4,:d4,:d4,:b3,:b3,:r,:r,:g4,:g4,:d4,:d4,:c4,:eb4,:g4,:g4,:f4,:f4,:g4,:g4,:ab4,:ab4,:g4,:g4,:g4,:g4,:e4] 226 | d3c.concat [c,c,c,c,c,c,m,m,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c*p5,c*p6,c*p7,c*p8,b*p2] 227 | n4c = [:r,:c4,:c4,:c4,:d4,:eb4,:d4,:eb4,:c4,:d4,:c4,:d4,:bb3,:c4,:bb3,:c4,:ab3] 228 | d4c = [b*4,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c] 229 | n4c.concat [:bb3,:c4,:d4,:d4,:g3,:g3,:r,:g3,:g3,:r,:c3,:g3,:g3,:c4,:c4,:g3,:g3,:ab3,:ab3,:e3,:e3,:f3,:f3,:g3,:g3,:g3,:g3,:c3] 230 | d4c.concat [c,c,c,c,c,c,m,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c*p5,c*p6,c*p7,c*p8,b*p2] 231 | end 232 | 233 | define :sec3 do |x| 234 | in_thread do 235 | with_merged_synth_defaults pan: -0.7 do 236 | tune(n1c,d1c,sh,x,0.95) 237 | tune(tr,dr,sh,x,0.95) 238 | end 239 | end 240 | in_thread do 241 | with_merged_synth_defaults pan: 0.7 do 242 | tune(n2c,d2c,sh,x,0.95) 243 | end 244 | end 245 | in_thread do 246 | with_merged_synth_defaults pan: -0.4 do 247 | tune(n3c,d3c,sh,x,0.95) 248 | end 249 | end 250 | with_merged_synth_defaults pan: 0.4 do 251 | tune(n4c,d4c,sh,x,0.95) 252 | end 253 | end 254 | 255 | #===================play funeral march then cadenza ================== 256 | 257 | with_fx :reverb, home: 0.8 do 258 | setup(1.0/8)#set timings 259 | sec1(0.6) 260 | setup(1.0/16) 261 | sleep b 262 | sec2(0.4) 263 | sleep q 264 | sec2(0.2) 265 | sleep q 266 | setuppart3(2)#short rit set up the arrays 267 | sec3(0.4) 268 | setuppart3(1)#long rit set up the arrays 269 | sec3(0.8) 270 | end 271 | ``` -------------------------------------------------------------------------------- /PurcellREADME.md: -------------------------------------------------------------------------------- 1 | README for Purcell Funeral Music for Queen Mary 2 | The Sonic Pi program PurcellFuneralMusic.txt requires 3 | an audio sample file d1.wav to be installed before it 4 | will work. The file is shown separately here. The easiest way 5 | to download and install it is to download the zip file 6 | SonicPiPurcell.zip from this repository. 7 | The zip file contains teh program file, a sampels folder 8 | containing d1.wav and a README file containing installation notes. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SonicPi-Tutorials 2 | ================= 3 | 4 | Occasional tutorials for Sonic-Pi 2 5 | 6 | You should be familiar with the contents of the worksheets 7 | 8 | http://www.raspberrypi.org/learning/sonic-pi-2-taster/worksheet.md 9 | 10 | before starting to use these 11 | 12 | Some of the files contain snippets of code, or complete programs which you can try on your Raspberry Pi. 13 | You can view these files in raw format and copy and paste them into a Sonic Pi 2 workspace. In this case, delete the first line Ruby (+ three ticks) and the last line (three ticks) which are formatting lines to display the file nicely in github, before running the file in Sonic Pi. 14 | 15 | You may find it useful to look at my blog http://rbnrpi.wordpress.com for further information on these files, 16 | and on using Sonic Pi 17 | 18 | You can here some of these files recorded in a video here:- 19 | http://youtu.be/2ReslTXY7A8 20 | -------------------------------------------------------------------------------- /SonicPiPurcell.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbnpi/SonicPi-Tutorials/50bb6adfd3b4c7c44ea55334bd5357ac2c9fbbf8/SonicPiPurcell.zip -------------------------------------------------------------------------------- /Tutorial1.md: -------------------------------------------------------------------------------- 1 | #Playing with chords & lists on Sonic-Pi 2 2 | There are two commands which will play chords on Sonic-Pi 2. The first one looks like this:- you can type it in a new workspace 3 | ```Ruby 4 | play_chord [:c4, :e4, :g4] 5 | ``` 6 | note there must be a space between chord and the opening [. When you press Run, this will sound the three notes together. If you want you can have more than three notes, by typing further notes separated by commas in the list between the [ ]. If you add the next two lines and run the program again, you will see the alternative way of playing a three note chord: 7 | ```Ruby 8 | play_chord [:c4, :e4, :g4] 9 | sleep 1 10 | play chord(:c4,:major) 11 | ``` 12 | In this case we describe the chord in a slightly different way. You type the bottom note or the tonic of the chord (here :c4) and follow it with the type of chord you want to play, after a separating comma. In this case we play a C major chord. Other types you could try include :minor, :dom7, :dim7 and there are a host of others. Some contain numbers and have to be put inside apostrophes or speech marks, eg '11+' or "m+5", but that goes a bit further than we will just now. 13 | What we are going to do is to explore the way Sonic-Pi holds details of the notes when the chord is played, and how we can manipulate and change chords. 14 | 15 | Add the last line below, and press run again: 16 | ```Ruby 17 | play_chord [:c4, :e4, :g4] 18 | sleep 1 19 | play chord(:c4,:major) 20 | puts chord(:c4,:major) 21 | ``` 22 | You will hear the two chords, which sound identical, and if you look at the output pane, you will see [60, 64, 67] in blue type. This is produced by the puts command which asks Sonic-Pi to print what follows, in this case chord(:c4,:major) and the result is a list of three numbers, separated by commas inside square brackets. 23 | This is the same way that the first play_chord specified the notes to be played, but we see the equivalent midi-note numbers corresponding to the symbols :c4, :e4 and :g4 24 | We can in fact ask Sonic_Pi to do the conversion for us explicitly by adding 3 further lines to get: 25 | ```Ruby 26 | play_chord [:c4, :e4, :g4] 27 | sleep 1 28 | play chord(:c4,:major) 29 | puts chord(:c4,:major) 30 | puts note_info(:c4).midi_note 31 | puts note_info(:e4).midi_note 32 | puts note_info(:g4).midi_note 33 | ``` 34 | 35 | The last three similar commands asks Sonic_Pi to print in the output pane information about the note in the form of its midi note number, and we will see the answers 60 64 and 67 again, one on each line. 36 | 37 | #Looking at a list and changing it 38 | 39 | Now we will use another idea. We are going to store the list of notes in the chord in a variable which we will call nlist. This is rather like a box in which we will put a piece of paper with some information on it. Later we can go back to the box and get the piece of paper and read what is on it. Add a further two lines {you can miss out the comments - the bits after the # if you don't want to type too much} to give: 40 | 41 | ```Ruby 42 | play_chord [:c4, :e4, :g4] 43 | sleep 1 44 | play chord(:c4,:major) 45 | puts chord(:c4,:major) 46 | puts note_info(:c4).midi_note 47 | puts note_info(:e4).midi_note 48 | puts note_info(:g4).midi_note 49 | nlist = chord(:c4,:major) #stores the notes in the chord like writing on a bit of paper, in the variable or box nlist 50 | puts nlist #gets the contents of nlist (like what is written on the piece of paper in the box), and prints it 51 | ``` 52 | 53 | When you run this you will see an additional [60, 64, 67] at the bottom of the output pane. 54 | This is called a list. It has three items in it, the numbers 60 64 and 67. We can change the list by adding extra numbers, or by taking some away, or by altering their order. These are all things that can be done in the Ruby language in which Sonic-Pi is written. 55 | First we will add an extra number on the end, which will give us a four note chord when we play it. Add the extra lines onto the program shown below: 56 | 57 | ```Ruby 58 | play_chord [:c4, :e4, :g4] 59 | sleep 1 60 | play chord(:c4,:major) 61 | puts chord(:c4,:major) 62 | puts note_info(:c4).midi_note 63 | puts note_info(:e4).midi_note 64 | puts note_info(:g4).midi_note 65 | nlist = chord(:c4,:major) #stores the notes in the chord like writing on a bit of paper, in the variable or box nlist 66 | puts nlist #gets the contents of nlist (like what is written on the piece of paper in the box, and prints them 67 | nlist = nlist + [:c5] 68 | sleep 1 69 | play_chord nlist 70 | puts nlist 71 | ``` 72 | 73 | When you run this you will hear three chords played. The first two are identical 3 note chords. The last one plays the four note chord we have generated, and the puts nlist command in the last line prints out the list of four notes on the output screen 74 | Notice how we add the extra note to the list. We don't just say + :c5 We have to put it into a one element list [:c5] - a list with one piece of information in it - and then we add the two lists together to make a single longer list. It is like having a line of three railway trucks couple together (our nlist) and we couple another line consisting of 1 truck onto the end, giving a longer line of four trucks. The trucks themselves could be different: a coal truck, a cement truck, a flatbed truck (like the different notes in this case), but they are all trucks and can be joined together. 75 | nlist doesn't know about notes, so the list contains three numbers and one symbol :c4. All will be converted to midi numbers when they are played by the play_chord command. We could have done it ourselves by adding 72 instead of :c5 to the list. 76 | 77 | 78 | #moving things around 79 | Now we will go back to the original C major chord play chord(:c4,:major). If you have done any music theory, you may have come across the idea of chord inversions. To produce the first inversion of the chord, we take the bottom note off the chord, put it up an octave, and add it on the top. So our chord :c4, :e4, :g4 becomes the chord :e4, :g4, :c5 We can of course do this manually, but since we are playing with lists we can get Ruby commands to do it for us. 80 | For this section it is easiest to start with a fresh workspace. You can use the save button to save what we have done so far, if you wish, but then delete everything in the workspace, or select another empty one. 81 | Now type in the following code: 82 | 83 | ```Ruby 84 | nlist = chord(:c4,:major) 85 | puts nlist 86 | play_chord nlist 87 | sleep 1 88 | n0 = nlist[0] 89 | puts n0 90 | nremainder = nlist[1..-1] 91 | ntop = [n0 + 12] #adding 12 puts it up an octave 92 | n1stinversion = nremainder + ntop #add two lists together to get the final inversion chord list 93 | puts n1stinversion 94 | play_chord n1stinversion 95 | ``` 96 | 97 | 98 | If you run this you will hear the original C major chord, and see its note list printed in the output pane. [60, 64, 67]. After a second delay you will hear the first inversion chord play, and see its note list on the output screen [64, 67, 72] 99 | So how does this work? Ruby does the work for us. the line n0 = nlist[0] creates another variable (or storage box) called n0. It stores in it the first element or number in the list of numbers stored in nlist. One thing to note, is that when you are referring to a particular number in a list, Ruby numbers them from 0, not from 1. So the first element or number is element 0, the second one element 1 and so on. 100 | so n0 has the number 60 stored in it. If you want to check this you could add the line puts n0 just after the line n0 = nlist[0] 101 | The next line is a bit trickier. We make another variable called nremainder and in it we store a list of the remaining two numbers in nlist. The syntax or grammar of how this is done is to use nlist[1..-1] This means starting with element 1 (remember this will be the second number of the three in the list as they number from 0) go up to the last number (-1) however many there are. It looks a bit odd, but that is the way it works. 102 | The next thing to do is to make the note number for the final note to go on the top of the chord. Since there are 12 semitones in an octave, the midi note number for notes an octave apart differ by 12, 1 for each semitone. So the top note which we will store in another variable called ntop is produced by the line: 103 | ```Ruby 104 | ntop = [n0 + 12] #adding 12 puts it up an octave 105 | ``` 106 | Note that we put the new note number inside [ ] before storing it in ntop. This makes ntop a LIST containing a single element rather than just a number. 107 | The final stage of the process is to add the two LISTS nremainder and ntop together giving us the new inverted chord LIST. That is done by the line 108 | ```Ruby 109 | n1stinversion = nremainder + ntop #add two lists together to get the final inversion chord list 110 | ``` 111 | Finally we can print this new list to the output pane and play the resulting chord, which is what the last two lines do. 112 | #Where next? 113 | In this tutorial we have looked at how chords are played and represented in Sonic_Pi. We have also seen how Ruby LISTS can be manipulated to produce new chords. As an exercise you might like to go through a similar process to the one we have used to produce the first inversion of C major to produce the second inversion. You want to remove the new bottom note of the chord, put it up an octave and add it on the top again. 114 | Lists are used a lot in Sonic-Pi. You might also like to explore the command to reverse the items in a list. For example 115 | ```Ruby 116 | n = [:c4, :d4, :e4, :f4, :g4, :a4, :b4, :c5] 117 | ``` 118 | is the list of notes in a C major scale. 119 | If you type this in and then type: 120 | ```Ruby 121 | use_bpm 240 122 | play_pattern n 123 | ``` 124 | it will play this scale. You can then try adding the following lines 125 | ```Ruby 126 | sleep 1 127 | play_pattern n.reverse 128 | sleep 1 129 | play_pattern n.shuffle 130 | ``` 131 | These modify the list containing the scale. The first reverses it, the second selects each element once at random. 132 | Have fun exploring! 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /d1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbnpi/SonicPi-Tutorials/50bb6adfd3b4c7c44ea55334bd5357ac2c9fbbf8/d1.wav -------------------------------------------------------------------------------- /wolfwhistle.md: -------------------------------------------------------------------------------- 1 | ```Ruby 2 | define :wolfwhistle do |n| 3 | n=note_info(n).midi_note 4 | p = play n,sustain: 0.2,release: 0.1 5 | control p, note: n + 24, note_slide: 0.5 6 | sleep 0.5 7 | p = play n,sustain: 0.2,release: 0.1 8 | control p, note: n + 24, note_slide: 0.4 9 | sleep 0.2 10 | p = play n + 24,sustain: 0.12,release: 0.1 11 | control p, note: n+8, note_slide: 0.4 12 | sleep 0.1 13 | end 14 | 15 | in_thread do 16 | wolfwhistle(:c5) 17 | end 18 | wolfwhistle(:g5) 19 | ``` 20 | --------------------------------------------------------------------------------