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

Elixir, MIDI & LiveView (CodeElixir London 2019)

Elixir, MIDI & LiveView (CodeElixir London 2019)

In this talk, I demonstrate the use of Elixir, Phoenix LiveView with SVG and hot-code reloading to achieve live music coding.

Live demo at https://twitter.com/unnawut/status/1151939962855677952

Thibaut Barrère

July 18, 2019
Tweet

More Decks by Thibaut Barrère

Other Decks in Programming

Transcript

  1. Elixir, MIDI
    & LiveView
    @thibaut_barrere - I create data pipelines with Ruby & Elixir

    View Slide

  2. Code-based music
    production?
    infiniWIP (TM)

    View Slide

  3. Previous episode
    https://github.com/thbar/demo-elixir-reloading-music

    View Slide

  4. Detect when I save a code file
    def init(args) do
    {:ok, watcher_pid} = FileSystem.start_link(args)
    FileSystem.subscribe(watcher_pid)
    def handle_info({:file_event, watcher_pid, {path, events}}, state) do do
    IO.puts "The file at #{path} has changed!"
    {:noreply, state}
    end

    View Slide

  5. Re-evaluate it at runtime (hot reloading)
    def handle_info({:file_event, watcher_pid, {path, events}}, state) do do
    Code.eval_file(path)
    {:noreply, state}
    end

    View Slide

  6. AHA MOMENT
    GenServer reloading keeps the state across reloads.
    => We can keep the "current music position/tick"
    between reloads.
    defmodule Artist do
    use GenServer
    def handle_info(:tick, state) do
    Process.send_after(self(), :tick, @tick_period)

    View Slide

  7. MIDI

    View Slide

  8. Note On
    {0x90 + channel, note, velocity}
    Note Off
    {0x80 + channel, note, release_velocity}

    View Slide

  9. Keyboard / Piano / Synthetizers
    photo by Clavia

    View Slide

  10. MIDI controllers
    photo by Novation

    View Slide

  11. Virtual Instruments (on computer)

    View Slide

  12. Virtual Instruments (on iOS)
    photo by Korg

    View Slide

  13. Lightning = Inter-Device Audio & MIDI (IDAM)
    photo by Apple

    View Slide

  14. Elixir
    Code / DRY
    Refactoring Music
    Augmented Human (theory, scales)
    Soft realtime

    View Slide

  15. brew install portmidi

    View Slide

  16. View Slide

  17. # Start a process for MIDI event queue
    {:ok, pid} = PortMidi.open(:output, "Kontakt Virtual Input")
    note = 48 # C-4
    velocity = 127
    # Send "NOTE ON"
    PortMidi.write(pid, {0x90, note, velocity})
    # Send "NOTE OFF"
    PortMidi.write(pid, {0x80, note})

    View Slide

  18. View Slide

  19. Phoenix LiveView


    Time is


    HTML? ✔

    View Slide

  20. Phoenix LiveView





    SVG? ✔

    View Slide

  21. Phoenix LiveView


    # white notes


    # black notes


    View Slide

  22. View Slide

  23. View Slide

  24. def note_on({channel, note, velocity}, device, portmidi \\ PortMidi) do
    Phoenix.PubSub.broadcast(Widgets.PubSub, "notes", {:note_on, note})
    :ok = portmidi.write(device, {0x90 + channel, note, velocity})
    end

    View Slide

  25. View Slide

  26. Live Demo
    https://twitter.com/unnawut/status/1151939962855677952

    View Slide