$30 off During Our Annual Pro Sale. View Details »

Playing with Music: Ruby and Sonic Pi

Josep Egea
November 14, 2022

Playing with Music: Ruby and Sonic Pi

Sonic Pi is a fantastic tool for playing music and learning to code. And it uses Ruby!!!

In this talk we'll have a quick overview of Sonic Pi's capabilities and explore how much it can benefit from the power and flexibility provided by Ruby.

And we'll try to play some music while we're at it!!

A Madrid.rb talk: https://www.madridrb.com/events/october-2022-playing-with-music-ruby-and-sonic-pi-715

Josep Egea

November 14, 2022
Tweet

More Decks by Josep Egea

Other Decks in Programming

Transcript

  1. PLAYING WITH MUSIC: RUBY AND SONIC PI
    JOSEP EGEA
    [email protected]

    View Slide

  2. KICK OFF!!

    View Slide

  3. THANKS FOR COMING!!!
    Thanks to members of Madrid.rb
    Thanks to people from outside of Madrid!
    Thanks to our Sponsors! We
    ❤️ you!

    View Slide

  4. WHO'S JOSEP
    Software developer & Entrepreneur
    [email protected]
    https://www.josepegea.com
    https://github.com/josepegea

    View Slide

  5. BEFORE WE START …

    View Slide

  6. 🇺🇦 STOP THE WAR
    🇺🇦

    View Slide

  7. ABOUT TODAY

    View Slide

  8. I'M NOT A MUSICIAN!!
    But I do love music!!
    Specially, I love to play with music
    And I love to play with Ruby
    So Ruby and Music mixed must be super fun!!

    View Slide

  9. EXPECTED TAKEWAYS
    You get a new reason to love Ruby
    We have some fun

    View Slide

  10. WHY I WANT TO GIVE THIS TALK

    View Slide

  11. MUSIC AND CODING

    View Slide

  12. STEREOTYPE???
    Music lives in the right side of your brain. Coding lives in the left one

    View Slide

  13. LET'S PLAY A GAME!!

    View Slide

  14. MUSICIAN OR CODER??

    View Slide

  15. MUSICIAN OR CODER??

    View Slide

  16. MUSICIAN OR CODER??

    View Slide

  17. MUSICIAN OR CODER??

    View Slide

  18. MEET SONIC PI

    View Slide

  19. A RUBY REPL, FOR MUSIC!!!

    View Slide

  20. WITH MUCH TO LOVE ABOUT IT
    A completely self-sufficient music environment
    Open source
    Oriented to education
    It uses Ruby (and many other cool technologies!!!)

    View Slide

  21. AND SOME STRONG OPINIONS…
    😃

    View Slide

  22. SOME OF ITS FEATURES
    It can synthesize sounds
    It can work with samples
    It has convenient music helpers
    It can apply great effects
    It can manage timing and concurrence
    It can interact with other instruments

    View Slide

  23. SYNTHESIZING SOUNDS
    play :c

    sleep 1

    play :e

    sleep 1

    play :g

    sleep 1

    View Slide

  24. WORKING WITH SAMPLES
    sample :drum_bass_hard

    sleep 1

    sample :drum_snare_hard

    sleep 1

    View Slide

  25. MUSIC HELPERS
    s = scale :c, :major
    loop do

    play s.pick

    sleep 0.5

    end

    View Slide

  26. APPLYING EFFECTS
    use_bpm 120

    with_fx :reverb, room:1 do

    3.times do

    use_synth :blade

    use_synth_defaults amp: 1

    play :c

    sleep 1

    play :e

    sleep 1

    play :g

    sleep 2

    end

    end

    View Slide

  27. MANAGING CONCURRENCE
    in_thread do

    c = chord :c, :major

    loop do

    play c.pick

    sleep 0.5

    end

    end

    in_thread do

    loop do

    sample :drum_bass_hard

    sleep 1

    sample :drum_snare_hard

    sleep 1

    end

    end

    View Slide

  28. INTERACTING WITH OTHER INSTRUMENTS
    use_bpm 90

    in_thread do

    loop do

    use_real_time

    note, velocity = sync "/midi:lpk25:1/note_on"

    synth :piano, note: note, amp: velocity / 127.0

    end

    end

    in_thread do

    loop do

    sample :drum_bass_hard

    sleep 1

    sample :drum_snare_hard

    sleep 1

    end

    end

    View Slide

  29. MAKING IT MORE INTERESTING
    manual_beats = {

    48 => :drum_bass_hard,

    50 => :drum_snare_hard,

    52 => :drum_splash_hard

    }

    in_thread do

    loop do

    use_real_time

    note, velocity = sync "/midi:lpk25:1/note_on"

    if manual_beats[note]

    sample manual_beats[note]

    else

    synth :piano, note: note, amp: velocity / 127.0

    end

    end

    end

    View Slide

  30. OR EVEN MORE …
    live_audio :guitar, input: 1, amp: 1

    with_fx :lpf, cutoff: 115 do

    with_fx :distortion, distort: 0.99 do

    live_audio :guitar, input: 1, amp: 1

    end

    end

    View Slide

  31. HOW SONIC PI IS USED

    View Slide

  32. TEACHING

    View Slide

  33. DJ PERFORMANCES
    Sam Aaron live coding an ambient electro set w/ Sonic Pi
    Sam Aaron live coding an ambient electro set w/ Sonic Pi

    View Slide

  34. WHAT CAN WE ADD HERE?
    Something that's not techno/DJ oriented
    Some more emphasis on Ruby

    View Slide

  35. LET'S PLAY A SONG

    View Slide

  36. LET'S START WITH A RIFF
    song_tick = 0.125

    riff_notes = [:g5, :a5, :fs6, :a5, :g5, :a5, :d6, :a5].ring

    riff_note_duration = song_tick * 2

    riff_idx = 0

    use_synth :supersaw

    live_loop :riff do

    note = riff_notes[riff_idx]

    play note

    sleep riff_note_duration

    riff_idx += 1

    end

    View Slide

  37. LET'S ADD SOME DRUMS
    live_loop :drums_1 do

    sample :drum_bass_hard

    sleep song_tick * 4

    end

    live_loop :drums_2 do

    sleep song_tick * 4

    sample :drum_snare_hard

    sleep song_tick * 4

    end

    View Slide

  38. A BASS LINE…
    chord_values = [:D2, :C2, :G1, :D2].ring

    chords = chord_values.map { |c| chord(c, :major) }.ring

    bass_idx = 0

    live_loop :bass do

    use_synth :bass_foundation

    chord_notes = chords[bass_idx / 16]

    play chord_notes.pick

    sleep song_tick * 2

    bass_idx += 1

    end

    View Slide

  39. MAYBE SOME STRINGS
    string_chord_values = [:D4, :C4, :G3, :D4].ring

    string_chords = string_chord_values

    .map { |c| chord(c, :major) }.ring

    strings_idx = 0

    live_loop :strings do

    use_synth :zawa

    chord_notes = string_chords[strings_idx]

    play chord_notes, amp: 2, range: 10, phase: 2,

    attack: 1, sustain: song_tick * 30

    sleep song_tick * 32

    strings_idx += 1

    end

    View Slide

  40. ISN'T IT A BIT MANUAL?

    View Slide

  41. WHAT IF WE WANT A MORE COMPLEX RHYTHM?
    def make_bool_ring(pattern)

    pattern.chars

    .reject { |c| c == '|' }

    .map { |c| c == '*' }

    .ring

    end

    alias mbr make_bool_ring

    def sample_pattern_live_loop(*args, **kwargs)

    sample_patterns = kwargs.delete(:sample_patterns)

    sample_tick = kwargs.delete(:sample_tick)

    sample_idx = 0

    live_loop(*args, **kwargs) do

    sample_patterns.each do |sample_key, pattern|

    sample sample_key if pattern[sample_idx]

    end

    sleep sample_tick

    sample_idx += 1

    end

    end

    drum_patterns = {

    View Slide

  42. AND HOW DO WE COMBINE OUR PIECES?
    DEFAULT_TIME_PARTS = {

    half_pulse: 2,

    pulse: 2,

    bar: 4,

    chord: 2,

    verse: 4

    }

    class SongController < Object

    attr_accessor :time_parts, :song_parts, :tick_name, :tick_time

    def initialize(time_parts: DEFAULT_TIME_PARTS, song_parts:, tic
    @time_parts = time_parts

    @song_parts = song_parts

    @tick_name = tick_name

    @tick_time = tick_time

    @total_ticks = time_parts.values.reduce(1, &:*)

    end

    def run(start_part = 0)
    @idx = start_part * @total_ticks

    $sonic_pi.live_loop @tick_name, delay: 1 do

    $sonic_pi.cue @tick_name

    View Slide

  43. LET'S STITCH IT TOGETHER

    View Slide

  44. RECAP

    View Slide

  45. TAKEAWAY
    If you like Ruby and you like Music you have to try Sonic Pi

    View Slide

  46. DID I DO MY JOB?
    Are you more in love with Ruby?
    Did you have fun?

    View Slide

  47. REFERENCES
    Sonic Pi
    Ruby Fragments used in this talk
    https://sonic-pi.net/
    https://github.com/josepegea/sonic_pi_talk

    View Slide

  48. BIG THANKS!!
    And thank you for the music!!
    |
    [email protected] www.josepegea.com

    View Slide