Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Anyone Can Play Guitar

Anyone Can Play Guitar

I’ve got the blues. I’ve been looking for the perfect guitar tone, but haven’t found it. To amp up my mood, let’s teach a computer to play the guitar through an amplifier.

Let’s string together object-oriented principles to orchestrate a blues shuffle. We’ll model our domain with the help of inheritance, composition, and dependency injection. This talk will strike a chord with you, whether you’ve strummed a guitar before or not.

Kevin Murphy

November 09, 2022
Tweet

More Decks by Kevin Murphy

Other Decks in Programming

Transcript

  1. 📷: Bob Bissett Stevie Ray Vaughan CC BY-SA 4.0 I

    use heavy strings, tune low, play hard, and fl oor it. Floor it. That's technical talk.
  2. @kevin j m ruby.social kevinjmurphy.com Use Heavy Strings 9 11

    16 24 32 42 13 15 19 28 38 58 Common Gauge SRV Gauge
  3. @kevin j m ruby.social kevinjmurphy.com Use Heavy Strings class GuitarString

    def heavy? gauge_number > common_gauge_number end end
  4. @kevin j m ruby.social kevinjmurphy.com Tune Low Eb Bb Gb

    Db Ab Eb Standard Down Half Step E B G D A E
  5. @kevin j m ruby.social kevinjmurphy.com Tune Low class Guitar def

    tune(tuning = :standard) case tuning end end
  6. @kevin j m ruby.social kevinjmurphy.com Tune Low class Guitar def

    tune(tuning = :standard) case tuning when :standard standard_tuning end end
  7. @kevin j m ruby.social kevinjmurphy.com Tune Low class Guitar def

    tune(tuning = :standard) case tuning when :standard standard_tuning when :down_half_step down_half_step_tuning end end
  8. @kevin j m ruby.social kevinjmurphy.com Tune Low class Guitar def

    tune(tuning = :standard) case tuning when :standard standard_tuning when :down_half_step down_half_step_tuning … end end
  9. @kevin j m ruby.social kevinjmurphy.com Tune Low class Guitar def

    tune(tuning = :standard) case tuning when :standard when :down_half_step when :drop_d when :open_a when :modal_c end end
  10. @kevin j m ruby.social kevinjmurphy.com Tune Low class Guitar def

    tune(tuning = :standard); end def standard_tuning; end end
  11. @kevin j m ruby.social kevinjmurphy.com Tune Low class Guitar def

    tune(tuning = :standard); end def standard_tuning; end def down_half_step_tuning; end end methods with similar names Pick out
  12. @kevin j m ruby.social kevinjmurphy.com class Guitar def tune(tuning =

    :standard); end def standard_tuning; end def down_half_step_tuning; end def drop_d_tuning; end end Tune Low methods with similar names Pick out
  13. @kevin j m ruby.social kevinjmurphy.com Tune Low class Guitar def

    tune(tuning = :standard); end def standard_tuning; end def down_half_step_tuning; end def drop_d_tuning; end def open_a_tuning; end end grouped related behavior Pick out
  14. @kevin j m ruby.social kevinjmurphy.com Tune Low class Guitar def

    tune(tuning = :standard); end def standard_tuning; end def down_half_step_tuning; end def drop_d_tuning; end def open_a_tuning; end def modal_c_tuning; end end grouped related behavior Pick out
  15. @kevin j m ruby.social kevinjmurphy.com Tune Low class Guitar def

    tune(tuning = :standard); end def standard_tuning; end def down_half_step_tuning; end def drop_d_tuning; end def open_a_tuning; end def modal_c_tuning; end … end grouped related behavior Pick out
  16. @kevin j m ruby.social kevinjmurphy.com Tune Low class Guitar def

    tune(tuning = :standard) Tuner.new end end
  17. @kevin j m ruby.social kevinjmurphy.com Tune Low class Guitar def

    tune(tuning = :standard) Tuner.new(self) end end
  18. @kevin j m ruby.social kevinjmurphy.com Tune Low class Guitar def

    tune(tuning = :standard) Tuner.new(self) .tune(tuning) end end
  19. 📷: Bob Bissett Stevie Ray Vaughan CC BY-SA 4.0 I

    use heavy strings, tune low, play hard
  20. @kevin j m ruby.social kevinjmurphy.com Play Hard > a_string =

    GuitarString.new > a_string.tune(note: :a)
  21. @kevin j m ruby.social kevinjmurphy.com Play Hard class Guitar def

    pick(string:, fret:) @strings[string -1].pluck(fret: fret) end end
  22. 📷: Bob Bissett Stevie Ray Vaughan CC BY-SA 4.0 I

    use heavy strings, tune low, play hard
  23. 📷: Bob Bissett Stevie Ray Vaughan CC BY-SA 4.0 I

    use heavy strings, tune low, play hard, and fl oor it.
  24. @kevin j m ruby.social kevinjmurphy.com Floor It > guitar =

    Guitar.new > guitar.restring(gauge_set: :srv)
  25. @kevin j m ruby.social kevinjmurphy.com Floor It > guitar =

    Guitar.new > guitar.restring(gauge_set: :srv) > guitar.tune(:down_half_step)
  26. @kevin j m ruby.social kevinjmurphy.com Floor It > song =

    Blues::Shuffle.new(guitar) > song.play
  27. @kevin j m ruby.social kevinjmurphy.com Floor It > song =

    Blues::Shuffle.new(guitar) > song.play => a, e, g_flat, e, g, e, g_flat, e d, a, b, a, c, a, b, a
  28. 📷: Bob Bissett Stevie Ray Vaughan CC BY-SA 4.0 I

    use heavy strings, tune low, play hard, and fl oor it.
  29. 📷: Bob Bissett Stevie Ray Vaughan CC BY-SA 4.0 I

    use heavy strings, tune low, play hard, and fl oor it. Floor it.
  30. @kevin j m ruby.social kevinjmurphy.com Floor It > song =

    Blues::Shuffle.new(guitar) > song.play
  31. @kevin j m ruby.social kevinjmurphy.com Floor It > song =

    Blues::Shuffle.new(guitar) > song.play => a2, e3, g_flat3, e3, g3, e3, g_flat3, e3 d3, a3, b3, a3, c4, a3, b3, a3
  32. @kevin j m ruby.social kevinjmurphy.com Floor It class Note def

    value; end def octave; end def to_s "#{value[0].upcase}#{'b' if flat?}#{octave}" end end
  33. @kevin j m ruby.social kevinjmurphy.com Floor It > song =

    Blues::Shuffle.new(guitar) > song.play
  34. @kevin j m ruby.social kevinjmurphy.com Floor It > song =

    Blues::Shuffle.new(guitar) > song.play => A2, E3, Gb3, E3, G3, E3, Gb3, E3 D3, A3, B3, A3, C4, A3, B3, A3
  35. 📷: Bob Bissett Stevie Ray Vaughan CC BY-SA 4.0 I

    use heavy strings, tune low, play hard, and fl oor it. Floor it.
  36. 📷: Bob Bissett Stevie Ray Vaughan CC BY-SA 4.0 I

    use heavy strings, tune low, play hard, and fl oor it. Floor it. That's technical talk.
  37. Stevie Ray Vaughan @kevin j m The problem with taking

    amps to a shop is that they come back sounding like another amp. 📷: Paul Lannuier CC BY-NC-ND 2.0
  38. @kevin j m ruby.social kevinjmurphy.com Amp class Amplifier def amplify(sound)

    pre_amp_stage(sound) power_amp_stage(sound) end end
  39. @kevin j m ruby.social kevinjmurphy.com class TubeAmp def pre_amp_tone if

    low_volume? || mid_volume? "💡" end end end Tube Amp Volume 0 10 Gain 0 10
  40. @kevin j m ruby.social kevinjmurphy.com class TubeAmp def pre_amp_tone if

    low_volume? || mid_volume? "💡" elsif high_volume? "🔥" end end end Tube Amp Volume 0 10 Gain 0 10
  41. @kevin j m ruby.social kevinjmurphy.com Tube Amp class TubeAmp <

    Amplifier end > amp = TubeAmp.new > amp.respond_to?(:amplify)
  42. @kevin j m ruby.social kevinjmurphy.com Tube Amp class TubeAmp <

    Amplifier end > amp = TubeAmp.new > amp.respond_to?(:amplify) => true
  43. @kevin j m ruby.social kevinjmurphy.com Solid State Amp class SolidStateAmp

    def pre_amp_tone "🫙" end end Volume 0 10 Gain 0 10
  44. @kevin j m ruby.social kevinjmurphy.com Solid State Amp class SolidStateAmp

    def pre_amp_tone "🫙" end end Volume 0 10 Gain 0 10
  45. @kevin j m ruby.social kevinjmurphy.com Solid State Amp > amp

    = SolidStateAmp.new > amp.weight => :light
  46. @kevin j m ruby.social kevinjmurphy.com Solid State Amp class SolidStateAmp

    < Amplifier end > amp = SolidStateAmp.new > amp.respond_to?(:amplify)
  47. @kevin j m ruby.social kevinjmurphy.com Solid State Amp class SolidStateAmp

    < Amplifier end > amp = SolidStateAmp.new > amp.respond_to?(:amplify) => true
  48. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class HybridAmp <

    TubeAmp, SolidStateAmp end (irb):2: syntax error, unexpected ',' expecting ';' or '\n'
  49. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class Amplifier def

    amplify(sound) pre_amp_stage(sound) power_amp_stage(sound) end end
  50. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class Amplifier def

    amplify(sound) pre_amp_stage(sound) power_amp_stage(sound) end end
  51. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp module TubePreAmp def

    pre_amp_tone if low_volume? || mid_volume? "💡" elsif high_volume? "🔥" end end end
  52. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class HybridAmp include

    TubePreAmp end > amp = HybridAmp.new(volume: 10)
  53. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class HybridAmp include

    TubePreAmp end > amp = HybridAmp.new(volume: 10) > amp.pre_amp_tone
  54. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class HybridAmp include

    TubePreAmp end > amp = HybridAmp.new(volume: 10) > amp.pre_amp_tone => "🔥"
  55. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class Amplifier def

    amplify(sound) pre_amp_stage(sound) power_amp_stage(sound) end end
  56. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class HybridAmp include

    TubePreAmp, SolidStatePowerAmp end > amp = HybridAmp.new(volume: 10)
  57. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class HybridAmp include

    TubePreAmp, SolidStatePowerAmp end > amp = HybridAmp.new(volume: 10) > amp.power_amp_weight
  58. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class HybridAmp include

    TubePreAmp, SolidStatePowerAmp end > amp = HybridAmp.new(volume: 10) > amp.power_amp_weight => :light
  59. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class HybridAmp <

    Amplifier include TubePreAmp, SolidStatePowerAmp end
  60. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class HybridAmp <

    Amplifier include TubePreAmp, SolidStatePowerAmp end > amp = HybridAmp.new(volume: 10)
  61. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class HybridAmp <

    Amplifier include TubePreAmp, SolidStatePowerAmp end > amp = HybridAmp.new(volume: 10) > amp.respond_to?(:amplify)
  62. @kevin j m ruby.social kevinjmurphy.com Hybrid Amp class HybridAmp <

    Amplifier include TubePreAmp, SolidStatePowerAmp end > amp = HybridAmp.new(volume: 10) > amp.respond_to?(:amplify) => true
  63. Stevie Ray Vaughan @kevin j m I fi gured out

    how to get the guitar to rumble. 📷: Paul Lannuier CC BY-NC-ND 2.0
  64. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > amp

    = SolidStateAmp.new(volume: 5) > amp.turn_on 

  65. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > amp

    = SolidStateAmp.new(volume: 5) > amp.turn_on 
 > guitar = Guitar.new
  66. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > amp

    = SolidStateAmp.new(volume: 5) > amp.turn_on 
 > guitar = Guitar.new > song = Blues::Shuffle.new(guitar)
  67. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > amp

    = SolidStateAmp.new(volume: 5) > amp.turn_on 
 > guitar = Guitar.new > song = Blues::Shuffle.new(guitar) > song.play { |sound| amp.amplify(sound) }
  68. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > amp

    = SolidStateAmp.new(volume: 5) > amp.turn_on 
 > guitar = Guitar.new > song = Blues::Shuffle.new(guitar) > song.play { |sound| amp.amplify(sound) } => A2
  69. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > amp

    = SolidStateAmp.new(volume: 5) > amp.turn_on 
 > guitar = Guitar.new > song = Blues::Shuffle.new(guitar) > song.play { |sound| amp.amplify(sound) } => A2🫙
  70. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > amp

    = SolidStateAmp.new(volume: 5) > amp.turn_on 
 > guitar = Guitar.new > song = Blues::Shuffle.new(guitar) > song.play { |sound| amp.amplify(sound) } => A2🫙🔊[5]
  71. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > amp

    = SolidStateAmp.new(volume: 5) > amp.turn_on 
 > guitar = Guitar.new > song = Blues::Shuffle.new(guitar) > song.play { |sound| amp.amplify(sound) } => A2🫙🔊[5]…D3🫙🔊[5]…A2🫙🔊[5]…E3🫙🔊[5]
  72. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > guitar

    = Guitar.new > song = Blues::Shuffle.new(guitar)
  73. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > guitar

    = Guitar.new > song = Blues::Shuffle.new(guitar) > song.play
  74. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble class Guitar

    def initialize @amplifier = SolidStateAmp.new(volume: 5) end end
  75. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble class Guitar

    def pick(string:, fret:) note = @strings[string -1].pluck(fret: fret) end end
  76. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble class Guitar

    def pick(string:, fret:) note = @strings[string -1].pluck(fret: fret) @amplifier.amplify(note) end end
  77. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > guitar

    = Guitar.new > song = Blues::Shuffle.new(guitar)
  78. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > guitar

    = Guitar.new > song = Blues::Shuffle.new(guitar) > song.play
  79. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > guitar

    = Guitar.new > song = Blues::Shuffle.new(guitar) > song.play => A2🫙🔊[5]…D3🫙🔊[5]…A2🫙🔊[5]…E3🫙🔊[5]
  80. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble class Guitar

    def initialize @amplifier = SolidStateAmp.new(volume: 5) end end
  81. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble class Guitar

    def initialize @amplifier = TubeAmp.new(volume: 9) end end
  82. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > guitar

    = Guitar.new > song = Blues::Shuffle.new(guitar) > song.play => 🔇🔇[0]…D3💡🔈[1]…A2💡🔉[6]…E3🔥🔊[9]
  83. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble class Guitar

    def initialize @amplifier = TubeAmp.new(volume: 9) end end
  84. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble class Guitar

    def initialize(amplifier: nil) @amplifier = amplifier end end
  85. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > solid_state_amp

    = SolidStateAmp.new(volume: 5) > Guitar.new(amplifier: solid_state_amp)
  86. @kevin j m ruby.social kevinjmurphy.com Hear the Rumble > solid_state_amp

    = SolidStateAmp.new(volume: 5) > Guitar.new(amplifier: solid_state_amp) > tube_amp = TubeAmp.new(volume: 9) > Guitar.new(amplifier: tube_amp)
  87. @kevin j m ruby.social kevinjmurphy.com Choices, Choices, Choices class HybridAmp

    < Amplifier include TubePreAmp class Guitar def tune = Tuner.new(self).tune
  88. @kevin j m ruby.social kevinjmurphy.com Choices, Choices, Choices class HybridAmp

    < Amplifier include TubePreAmp class Guitar def tune = Tuner.new(self).tune class Guitar def initialize(amplifier:)
  89. @kevin j m ruby.social kevinjmurphy.com Model YOUR Reality > amp

    = HybridAmp.new > guitar = Guitar.new(amplifier: amp) 

  90. @kevin j m ruby.social kevinjmurphy.com Model YOUR Reality > amp

    = HybridAmp.new > guitar = Guitar.new(amplifier: amp) 
 0 10 Flexibility
  91. @kevin j m ruby.social kevinjmurphy.com Model YOUR Reality > amp

    = HybridAmp.new > guitar = Guitar.new(amplifier: amp) 
 > guitar.tune(:down_half_step)
  92. @kevin j m ruby.social kevinjmurphy.com Model YOUR Reality > amp

    = HybridAmp.new > guitar = Guitar.new(amplifier: amp) 
 > guitar.tune(:down_half_step) collaborators to extract Pick out
  93. @kevin j m ruby.social kevinjmurphy.com Model YOUR Reality > amp

    = HybridAmp.new > guitar = Guitar.new(amplifier: amp) 
 > guitar.tune(:down_half_step) > song = Blues::Shuffle.new(guitar)
  94. @kevin j m ruby.social kevinjmurphy.com Model YOUR Reality > amp

    = HybridAmp.new > guitar = Guitar.new(amplifier: amp) 
 > guitar.tune(:down_half_step) > song = Blues::Shuffle.new(guitar) > song.play
  95. @kevin j m ruby.social kevinjmurphy.com Model YOUR Reality > amp

    = HybridAmp.new > guitar = Guitar.new(amplifier: amp) 
 > guitar.tune(:down_half_step) > song = Blues::Shuffle.new(guitar) > song.play => 🔇🔇[0]…D3💡🔈[1]…A2💡🔉[6]…E3🔥🔊[9]
  96. Stevie Ray Vaughan @kevin j m I don't know the

    names of what it is I'm doing. 📷: Paul Lannuier CC BY-NC-ND 2.0
  97. Stevie Ray Vaughan @kevin j m I learned how to

    make the sounds with my mouth and then copied that with my guitar. 📷: Paul Lannuier CC BY-NC-ND 2.0