Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

Code-based music production? infiniWIP (TM)

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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)

Slide 7

Slide 7 text

MIDI

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Keyboard / Piano / Synthetizers photo by Clavia

Slide 10

Slide 10 text

MIDI controllers photo by Novation

Slide 11

Slide 11 text

Virtual Instruments (on computer)

Slide 12

Slide 12 text

Virtual Instruments (on iOS) photo by Korg

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

brew install portmidi

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

# 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})

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

Phoenix LiveView

Time is <%= @time %>

HTML? ✔

Slide 20

Slide 20 text

Phoenix LiveView SVG? ✔

Slide 21

Slide 21 text

Phoenix LiveView

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

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