×
Copy
Open
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
Elixir, MIDI & LiveView
Slide 2
Slide 2 text
@thibaut_barrere Consultant Ruby / Elixir / Ansible Kiba ETL / Kiba Pro Remote 100% (Charente Maritime)
Slide 3
Slide 3 text
Elixir => Code-Centric Digital Audio Workstation? infiniwip (tm)
Slide 4
Slide 4 text
Previous episode https://github.com/thbar/demo-elixir-reloading-music Code.eval_file("music.exs")
Slide 5
Slide 5 text
MIDI
Slide 6
Slide 6 text
Note On {0x90 + channel, note, velocity} Note Off {0x80 + channel, note, release_velocity}
Slide 7
Slide 7 text
Keyboard / Piano / Synthetizers photo by Clavia
Slide 8
Slide 8 text
MIDI controllers photo by Novation
Slide 9
Slide 9 text
Virtual Instruments (on computer)
Slide 10
Slide 10 text
Virtual Instruments (on iOS) photo by Korg
Slide 11
Slide 11 text
Lightning = Inter-Device Audio & MIDI (IDAM) photo by Apple
Slide 12
Slide 12 text
Elixir Code / DRY Refactoring Music Augmented Human (theory, scales) Soft realtime
Slide 13
Slide 13 text
brew install portmidi
Slide 14
Slide 14 text
No content
Slide 15
Slide 15 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 16
Slide 16 text
No content
Slide 17
Slide 17 text
Computer: Note 60 Human: WTF????
Slide 18
Slide 18 text
Translation def note_number_to_latin_name(midi_note, middle_c \\ @default_middle_c) do remap_note(midi_note, @latin_names, middle_c) end defp remap_note(midi_note, names, middle_c) do offset = get_base_offset(middle_c) octave = div(midi_note + offset, 12) octave_note = rem(midi_note + offset, 12) octave_note = names |> Enum.at(octave_note) "#{octave_note}#{octave}" end defp get_base_offset("C4"), do: -12
Slide 19
Slide 19 text
DocTests ❤ ## Examples iex> MusicRef.note_number_to_latin_name(60) "Do4" iex> MusicRef.note_number_to_latin_name(78) "Fa#5"
Slide 20
Slide 20 text
Phoenix LiveView
Time is <%= @time %>
HTML? ✔
Slide 21
Slide 21 text
Phoenix LiveView SVG? ✔
Slide 22
Slide 22 text
Phoenix LiveView
Slide 23
Slide 23 text
No content
Slide 24
Slide 24 text
No content
Slide 25
Slide 25 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 26
Slide 26 text
No content
Slide 27
Slide 27 text
Code & Demo