(Paris.Ex meetup)
Elixir, MIDI& LiveView
View Slide
@thibaut_barrereConsultantRuby / Elixir / AnsibleKiba ETL / Kiba ProRemote 100% (Charente Maritime)
Elixir =>Code-Centric DigitalAudio Workstation?infiniwip (tm)
Previous episodehttps://github.com/thbar/demo-elixir-reloading-musicCode.eval_file("music.exs")
MIDI
Note On{0x90 + channel, note, velocity}Note Off{0x80 + channel, note, release_velocity}
Keyboard / Piano / Synthetizersphoto by Clavia
MIDI controllersphoto by Novation
Virtual Instruments (on computer)
Virtual Instruments (on iOS)photo by Korg
Lightning = Inter-Device Audio & MIDI (IDAM)photo by Apple
ElixirCode / DRYRefactoring MusicAugmented Human (theory, scales)Soft realtime
brew install portmidi
# Start a process for MIDI event queue{:ok, pid} = PortMidi.open(:output, "Kontakt Virtual Input")note = 48 # C-4velocity = 127# Send "NOTE ON"PortMidi.write(pid, {0x90, note, velocity})# Send "NOTE OFF"PortMidi.write(pid, {0x80, note})
Computer: Note 60Human: WTF????
Translationdef note_number_to_latin_name(midi_note, middle_c \\ @default_middle_c) doremap_note(midi_note, @latin_names, middle_c)enddefp remap_note(midi_note, names, middle_c) dooffset = 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}"enddefp get_base_offset("C4"), do: -12
DocTests ❤## Examplesiex> MusicRef.note_number_to_latin_name(60)"Do4"iex> MusicRef.note_number_to_latin_name(78)"Fa#5"
Phoenix LiveViewTime is HTML? ✔
Phoenix LiveViewSVG? ✔
Phoenix LiveView# white notes# black notes
def note_on({channel, note, velocity}, device, portmidi \\ PortMidi) doPhoenix.PubSub.broadcast(Widgets.PubSub, "notes", {:note_on, note}):ok = portmidi.write(device, {0x90 + channel, note, velocity})end
Code & Demo