A self-contained version of what I have in my sonic-pi-experiments repo. It uses my guitar helper, so here I've pasted it 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 guitar helper, so here I've pasted it into the buffer so anyone can run it.
Here's a recording of it on Soundcloud.
| # Let it be - The Beatles (guitar) | |
| # Uses the guitar helper | |
| define :guitar do |tonic, name=nil, tuning=:guitar, debug=false| | |
| tunings = { | |
| :ukulele => [:g, :c, :e, :a], | |
| :guitar => [:e2, :a2, :d3, :g3, :b3, :e4] | |
| } | |
| tuning = tunings[tuning] || tuning | |
| # Next note higher or equal to base note n, that is in the chord c | |
| define :next_note do |n, c| | |
| # Make sure n is a number | |
| n = note(n) | |
| # Get distances to each note in chord, add smallest to base note | |
| n + (c.map {|x| (note(x) - n) % 12}).min | |
| end | |
| if tonic.respond_to?(:each) and name==nil then | |
| chrd = tonic | |
| else | |
| chrd = (chord tonic, name || :M) | |
| end | |
| # For each string, get the next higher note that is in the chord | |
| c = tuning.map {|n| next_note(n, chrd)} | |
| # We want the lowest note to be the root of the chord | |
| root = note(chrd[0]) | |
| first_root = c.take_while {|n| (n - root) % 12 != 0}.count | |
| # Drop up to half the lowest strings to make that the case if possible | |
| if first_root > 0 and first_root < tuning.count / 2 | |
| c = (ring :r) * first_root + c.drop(first_root) | |
| end | |
| # Display chord fingering | |
| if debug | |
| puts c.zip(tuning).map {|n, s| if n == :r then 'x' else (n - note(s)) end}.to_a.join, c | |
| end | |
| c | |
| end | |
| # Strum a chord with a certain delay between strings | |
| define :guitar_strum do |chrd, dt| | |
| in_thread do | |
| play_pattern_timed chrd.to_a.drop_while{|n| [nil,:r].include? n}, dt | |
| end | |
| end | |
| define :strum do |chrd, pattern=nil, t=0.25, dt=0.025| | |
| if pattern == nil then | |
| guitar_strum(chrd, dt) | |
| else | |
| pattern.split(//).each do |shape| | |
| case shape | |
| when 'D' | |
| guitar_strum chrd, dt | |
| when 'd' | |
| with_fx :level, amp: 0.7 do | |
| guitar_strum chrd, dt | |
| end | |
| when 'U' | |
| with_fx :level, amp: 0.8 do | |
| guitar_strum chrd.reverse, dt*0.9 | |
| end | |
| when 'u' | |
| with_fx :level, amp: 0.6 do | |
| guitar_strum chrd.reverse, dt*0.9 | |
| end | |
| else | |
| # nothing | |
| end | |
| sleep t | |
| end | |
| end | |
| end | |
| use_bpm 72 | |
| use_synth :pluck | |
| with_fx :reverb, room: 1 do | |
| with_fx :lpf, cutoff: 95 do | |
| 2.times do | |
| strum guitar(:c), 'D.du', 0.5 | |
| strum guitar(:g), 'D.du', 0.5 | |
| strum guitar(:a, :m), 'D.', 0.5 | |
| strum guitar(:a, :m7), 'du', 0.5 | |
| strum guitar(:f), 'D.du', 0.5 | |
| strum guitar(:c), 'D.du', 0.5 | |
| strum guitar(:g), 'D.du', 0.5 | |
| strum guitar(:f), 'D.', 0.5 | |
| strum [:e3, :g3], 'd', 0.5 | |
| strum [:d3, :g3], 'd', 0.5 | |
| strum guitar(:c), 'D...', 0.5 | |
| end | |
| end | |
| end |