A self-contained version of what I have in my sonic-pi-experiments repo. It uses my play-helper and drum sequencer helpers, so here I've pasted them into the buffer so anyone can run it.
Here's a recording of it on Soundcloud.
A self-contained version of what I have in my sonic-pi-experiments repo. It uses my play-helper and drum sequencer helpers, so here I've pasted them into the buffer so anyone can run it.
Here's a recording of it on Soundcloud.
| # Smoke on the Water - Deep Purple | |
| # Self-contained version of https://github.com/emlyn/sonic-pi-experiments/blob/master/covers/Deep%20Purple%20-%20Smoke%20on%20the%20Water.rb | |
| use_debug false | |
| use_bpm 110 | |
| #### Some helper functions | |
| def pl(notes, sus: 0.5, rel: nil) | |
| rel ||= 1 - sus | |
| notes.each_slice(2) do |n,d| | |
| if d.respond_to?(:each) then # slur | |
| dtot = d.reduce(:+) | |
| synth = play n[0], sustain: sus * dtot, release: rel * dtot | |
| sleep d[0] | |
| d[1..-1].zip(n[1..-1]).each do |dd, nn| | |
| control synth, note: nn | |
| sleep dd | |
| end | |
| else | |
| play n, sustain: sus * d, release: rel * d | |
| sleep d | |
| end | |
| end | |
| end | |
| define :seq_expand do |sample, pat| | |
| # Expand sample base and pattern to array of samples | |
| pat.split('').map do |c| | |
| case c | |
| when '*' | |
| sample | |
| when 'x', 's', 'S' | |
| (sample.to_s + '_soft').to_sym | |
| when 'X', 'h', 'H' | |
| (sample.to_s + '_hard').to_sym | |
| when 'o', 'O' | |
| (sample.to_s + '_open').to_sym | |
| when 'c', 'C' | |
| (sample.to_s + '_closed').to_sym | |
| when '.', ' ' | |
| nil | |
| end | |
| end | |
| end | |
| define :seq do |parts, t=1| | |
| # Drum sequencer | |
| parts.each_slice(2).map{|s,p| seq_expand s,p}.transpose.each do |ss| | |
| ss.each do |s| | |
| sample s if s | |
| end | |
| sleep t | |
| end | |
| end | |
| define :bar do |n| | |
| return 4 * n | |
| end | |
| #### Define the different drum beats | |
| define :beat1 do # 1 bar | |
| # during intro | |
| seq [:drum_cymbal, "cccc"*4, | |
| :drum_bass, "X.X."*4], 0.25 | |
| end | |
| define :beat2 do # 1 bar | |
| # after beat1 | |
| seq [:drum_cymbal, "cccc.ccc"*2, | |
| :drum_bass, "X.X.X.X."*2, | |
| :drum_tom_mid, "....X..."*2], 0.25 | |
| end | |
| define :beat3 do # 1 bar | |
| # last bar before verse starts | |
| seq [:drum_cymbal, "c.c.c.c.........................", | |
| :drum_bass, "X.......X.......X.......X.......", | |
| :drum_tom_mid, "........X...XXXXX.X...XXX.X.X..."], 0.125 | |
| end | |
| define :beat4 do # 4 bars | |
| # during verse | |
| seq [:drum_cymbal, "o...c...c...c...", | |
| :drum_bass, "X.......X.X.....", | |
| :drum_tom_mid, "....X.......X..."], 0.25 | |
| seq [:drum_cymbal, "c...c..."*2, | |
| :drum_bass, "X.X....."*2, | |
| :drum_tom_mid, "....X..x"*2], 0.25 | |
| seq [:drum_cymbal, "c.c.c.c.c.c.c.c.", | |
| :drum_bass, "X.......X.X.....", | |
| :drum_tom_mid, "....X..x....X..x"], 0.25 | |
| seq [:drum_cymbal, "o.c.c.c.c.c.c...", | |
| :drum_bass, "X.......X.X.....", | |
| :drum_tom_mid, "....X..x....X..x", | |
| :drum_tom_hi, "..............x."], 0.25 | |
| end | |
| #### Define the instrumental parts | |
| define :lead_intro do # 4 bars | |
| sus=0.8 | |
| rel=0.15 | |
| pl [[:D, :G], 1, [:F, :Bb], 1, [:G, :C5], 1, :r, 0.5], sus: sus, rel: rel | |
| pl [[:D, :G], 1, [:F, :Bb], 1, [:Ab, :Db5], 0.5, [:G, :C5], 1.5, :r, 0.5], sus: sus, rel: rel | |
| pl [[:D, :G], 1, [:F, :Bb], 1, [:G, :C5], 1, :r, 0.5], sus: sus, rel: rel | |
| pl [[:F, :Bb], 1, [:D, :G], 1.5, :r, 2], sus: sus, rel: rel | |
| end | |
| define :lead_verse do | |
| Gm = (chord :G4, :m, invert: -1) # :D4, G4, :Bb4 | |
| Gm2= (chord :G4, :m, invert: -2) # :Bb3, :D4, G4 | |
| Gm7= (chord :G4, :m7, invert: -3)# :Bb3, :D4, :F4, :G4 | |
| F = (chord :F4, :M, invert: -1) # :C4, :F4, :A4 | |
| pl [Gm, 0.5, Gm, 0.5, :r, 2, Gm, 0.5, F.drop(1), 0.5]*2 | |
| pl [Gm, 1, Gm, 1, F, 0.5, F, 0.5, :r, 0.5] | |
| pl [Gm2, 2.5, [:D4,:r], 0.25, [:Bb3,:r], 0.25, [:G3,:r], 0.5, :r, 1] | |
| pl [Gm, 0.5, Gm, 0.5, :r, 0.5, Gm, 0.5, :r, 1, Gm, 0.5, :r, 0.5]*2 | |
| pl [Gm, 1, Gm, 1, F, 0.5, F, 0.5, :r, 0.5] | |
| pl [F, 1.5, :r, 2.5, :F4, 0.5] | |
| pl [Gm, 0.5, Gm, 0.5, :r, 0.5, Gm, 0.5, :r, 0.5, Gm, 0.5, :r, 1]*2 | |
| pl [Gm, 1, Gm, 1, F, 0.5, F, 0.5, :r, 0.5] | |
| pl [Gm2, 1.5, Gm7, 1, Gm7, 1, [:D4,:r], 0.25, [:Bb3,:r], 0.25, [:G3,:r], 0.25, :r, 0.25] | |
| pl [Gm, 0.5, Gm, 0.5, :r, 0.5, Gm, 0.5, :r, 1, Gm, 0.5, :r, 0.5] | |
| pl [Gm, 0.5, Gm, 0.5, :r, 0.5, Gm, 0.5, :r, 1, Gm, 0.5, Gm, 0.5] | |
| pl [Gm, 1, Gm, 1, F, 0.5, F, 0.5, :r, 0.5, Gm2, 2.5, :r, 2] | |
| end | |
| define :lead_chorus do | |
| at [0, 1, 2], [[:C4, 4], [:G4, 3], [:E5, 2]] do |notes| | |
| pl notes | |
| end | |
| sleep 4 | |
| at [0, 1, 2], [[:Ab3, 4], [:Eb4, 3], [:C5, 2]] do |notes| | |
| pl notes | |
| end | |
| sleep 4 | |
| pl [:r, 1, [:F4, :Bb4], 0.5, [:D4, :G4], 0.5, [:F4, :Bb4], 0.5, [:D4, :G4], 0.5, [:C4, :F4], 0.5] | |
| pl [[:D4, :G4], 1, [:D4, :G4], 0.5, [:F4, :Bb4], 0.5, [:D4, :G4], 0.5, [:F4, :Bb4], 0.5, [:D4, :G4], 0.5, [:C4, :F4], 0.5, [:D4, :G4], 0.5] | |
| at [0, 1, 2], [[:C4, 4], [:G4, 3], [:E5, 2]] do |notes| | |
| pl notes | |
| end | |
| sleep 4 | |
| at [0, 1, 2], [[:Ab3, 4], [:Eb4, 3], [:C5, 2]] do |notes| | |
| pl notes | |
| end | |
| sleep 4 | |
| end | |
| define :bass do # 1.5 beats upbeat | |
| # upbeat | |
| pl [[:D2, :D3], 0.5, [:F2, :F3], 0.5, [:Fs2, :Fs3], 0.5] | |
| # start | |
| pl [[:G2, :G3], 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5, :G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5] | |
| pl [:G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5, :G2, 0.5, :G3, 0.5, :F2, 0.5, :G3, 0.5] | |
| pl [:G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5, :C3, 0.5, :C4, 0.5, :C3, 0.5, :Bb3, 0.5] | |
| pl [:Bb2, 0.5, :G3, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5] | |
| # repeat | |
| pl [[:G2, :G3], 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5, :G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5] | |
| pl [:G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5, :G2, 0.5, :G3, 0.5, :F2, 0.5, :G3, 0.5] | |
| pl [:G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5, :C3, 0.5, :C4, 0.5, :C3, 0.5, :Bb3, 0.5] | |
| pl [:G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5] * 2 | |
| # verse | |
| 2.times do | |
| pl [:G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5] * 2 | |
| end | |
| pl [:G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5, :F2, 0.5, :F2, 0.5, :F3, 0.5, :F2, 0.5] | |
| 3.times do | |
| 3.times do | |
| pl [:G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5] * 2 | |
| end | |
| pl [:G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5, :F2, 0.5, :F2, 0.5, :F3, 0.5, :F2, 0.5] | |
| end | |
| pl [:G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5] * 2 | |
| # chorus | |
| pl [:C3, 0.5, :C4, 0.5] * 4 | |
| pl [:Ab2, 0.5, :Ab3, 0.5] * 4 | |
| 2.times do | |
| pl [:G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5] * 2 | |
| end | |
| pl [:C3, 0.5, :C4, 0.5] * 4 | |
| pl [:Ab2, 0.5, :Ab3, 0.5] * 4 | |
| # outro | |
| 2.times do | |
| pl [[:G2, :G3], 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5, :G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5] | |
| pl [:G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5, :G2, 0.5, :G3, 0.5, :F2, 0.5, :G3, 0.5] | |
| pl [:G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5, :C3, 0.5, :C4, 0.5, :C3, 0.5, :Bb3, 0.5] | |
| pl [:Bb2, 0.5, :G3, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5, :G2, 0.5, :G3, 0.5, :G2, 0.5] | |
| end | |
| end | |
| #### And the vocals | |
| define :verse1 do # 16 bars, plus a half-beat upbeat | |
| puts "We all came down to Montreux" | |
| pl [:F5, 0.5, :G5, 1, :G5, 1, :F5, 1, :D5, 0.5, :F5, 1, :D5, 1.5, :r, 1] | |
| puts "On the Lake Geneva shoreline" | |
| pl [:C5, 0.5, :Bb4, 0.5, [:Db5, :C5], [0.25, 0.75], :Bb4, 0.5, :C5, 1.5, :D5, 0.5] | |
| pl [[:Bb4, :G4], [0.5, 0.5], :G4, 1, :r, 3] | |
| puts "To make records with the mobile" | |
| pl [:F5, 0.5, :F5, 1, :F5, 0.5, :D5, 0.5, :F5, 0.5, :D5, 0.5, :G5, 1, :D5, 1, :r, 4.5] | |
| puts "We didn't have much time" | |
| pl [:Db5, 0.5, :C5, 0.5, :Bb4, 0.5, :Db5, 0.5, :Db5, 1, :G4, 1, :r, 2.5] | |
| puts "Frank Zappa and the Mothers" | |
| pl [:G5, 1, :G5, 0.5, :F5, 0.5, :G5, 0.5, :F5, 0.5, :G5, 1, :G5, 1.5, :r, 1] | |
| puts "Were at the best place around" | |
| pl [:Bb4, 0.5, :C5, 0.5, :Bb4, 0.5, :Db5, 1, :C5, 1, [:Bb4, :D5, :Db5, :D5], [0.5, 0.125, 0.125, 1.25], :r, 3.5] | |
| puts "But some stupid with a flare gun" | |
| pl [:D5, 0.5, :F5, 1, :F5, 0.5, :D5, 0.5, :F5, 0.5, :D5, 0.375, :r, 0.125, :F5, 1, :G5, 1, :r, 2] | |
| puts "Burned the place to the ground" | |
| pl [:F5, 0.5, :D5, 0.5, :D5, 1, :C5, 0.5, :D5, 1, [:Bb4, :G4], [0.25, 1.25], :r, 3] | |
| end | |
| define :chorus do # 6 bars | |
| puts "Smoke on the water" | |
| pl [[:G4, :E5], 3, [:F4, :D5], 0.5, [:E4, :C5], 0.5, [:Gb4, :Eb5], 2, [:E4, :C5], 1.5, :r, 1] | |
| puts "And fire in the sky" | |
| pl [:G4, 0.5, [:Bb4, :G4], [0.5, 0.5], :Bb4, 0.5, :G4, 0.5, [:F4, :G4], [0.5, 0.5], :r, 4] | |
| puts "Smoke on the water" | |
| pl [[:G4, :E5], 3, [:F4, :D5], 0.5, [:E4, :C5], 0.5, [:Gb4, :Eb5], 2, [:E4, :C5], 1.5, :r, 0.5] | |
| end | |
| #### Now let's put it all together (only 1 verse): | |
| # bar 0: start intro | |
| # bar 8: drums start | |
| # bar 16: bass starts, drums beat2 | |
| # bar 24: verse 1 | |
| # bar 40: chorus | |
| # bar 46: outro | |
| # bar 54: end | |
| with_fx :reverb, room: 0.8, slide: 3 do |fx| | |
| at bar 0 do | |
| use_synth :fm | |
| with_fx :distortion, distort: 0.9 do | |
| 6.times do | |
| lead_intro | |
| end | |
| sleep bar 22 | |
| 2.times do | |
| lead_intro | |
| end | |
| end | |
| end | |
| at bar 8 do | |
| with_fx :level, amp: 1.5 do |f| | |
| 8.times do | |
| beat1 | |
| end | |
| control f, level: 3 | |
| 7.times do | |
| beat2 | |
| end | |
| beat3 | |
| 4.times do | |
| beat4 | |
| end | |
| 14.times do | |
| beat2 | |
| end | |
| end | |
| end | |
| at (bar 16) - 1.5 do | |
| use_synth :fm | |
| use_synth_defaults cutoff: 70, amp: 1.5 | |
| with_fx :distortion, distort: 0.7 do | |
| bass | |
| end | |
| end | |
| at bar 24 do | |
| use_synth :fm | |
| use_synth_defaults amp: 1.5 | |
| lead_verse | |
| lead_chorus | |
| end | |
| at (bar 24) - 0.5 do | |
| use_synth :fm | |
| use_synth_defaults depth: 2, slide: 0.02, amp: 1.5 | |
| verse1 | |
| chorus | |
| end | |
| at bar 53 do | |
| control fx, amp: 0 | |
| end | |
| end | |
| # |
Good job! Thank you.