Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Elixir, MIDI and LiveView
Search
Thibaut Barrère
June 18, 2019
Programming
0
360
Elixir, MIDI and LiveView
(Paris.Ex meetup)
Thibaut Barrère
June 18, 2019
Tweet
Share
More Decks by Thibaut Barrère
See All by Thibaut Barrère
Kiba ETL: feedback on OSS / open-core sustainability for a Ruby gem
thbar
0
120
Elixir, MIDI & LiveView (CodeElixir London 2019)
thbar
0
1.1k
Kiba ETL v2 - RubyKaigi 2018
thbar
4
1.8k
Elixir hot-reloading & MIDI events generation
thbar
1
500
De Rails à Phoenix - retour d'expérience sur une réécriture d'application SaaS
thbar
3
2.3k
Processing data with Ruby and Kiba ETL
thbar
0
230
Retour d'expérience sur le bootstrapping de WiseCash (produit SaaS)
thbar
0
860
Bootstrapping your SaaS product (with freelancing)
thbar
3
580
Prestations agiles avec Acunote et Freckle
thbar
3
560
Other Decks in Programming
See All in Programming
AIの弱点、やっぱりプログラミングは人間が(も)勉強しよう / YAPC AI and Programming
kishida
6
3.5k
乱雑なコードの整理から学ぶ設計の初歩
masuda220
PRO
16
3.7k
AIのバカさ加減に怒る前にやっておくこと
blueeventhorizon
0
160
Stay Hacker 〜九州で生まれ、Perlに出会い、コミュニティで育つ〜
pyama86
0
200
CSC509 Lecture 13
javiergs
PRO
0
240
Researchlyの開発で参考にしたデザイン
adsholoko
0
120
Inside of Swift Export
giginet
PRO
1
530
ノーコードからの脱出 -地獄のデスロード- / Escape from Base44
keisuke69
0
670
CSC509 Lecture 11
javiergs
PRO
0
300
Blazing Fast UI Development with Compose Hot Reload (Bangladesh KUG, October 2025)
zsmb
2
500
なぜ強調表示できず ** が表示されるのか — Perlで始まったMarkdownの歴史と日本語文書における課題
kwahiro
8
4.8k
AI時代に必須!状況言語化スキル / ai-context-verbalization
minodriven
3
370
Featured
See All Featured
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
Scaling GitHub
holman
463
140k
Java REST API Framework Comparison - PWX 2021
mraible
34
9k
Unsuck your backbone
ammeep
671
58k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
Building Flexible Design Systems
yeseniaperezcruz
329
39k
How to train your dragon (web standard)
notwaldorf
97
6.4k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.2k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
8k
The Invisible Side of Design
smashingmag
302
51k
Docker and Python
trallard
46
3.6k
Build The Right Thing And Hit Your Dates
maggiecrowley
38
2.9k
Transcript
Elixir, MIDI & LiveView
@thibaut_barrere Consultant Ruby / Elixir / Ansible Kiba ETL /
Kiba Pro Remote 100% (Charente Maritime)
Elixir => Code-Centric Digital Audio Workstation? infiniwip (tm)
Previous episode https://github.com/thbar/demo-elixir-reloading-music Code.eval_file("music.exs")
MIDI
Note On {0x90 + channel, note, velocity} Note Off {0x80
+ channel, note, release_velocity}
Keyboard / Piano / Synthetizers photo by Clavia
MIDI controllers photo by Novation
Virtual Instruments (on computer)
Virtual Instruments (on iOS) photo by Korg
Lightning = Inter-Device Audio & MIDI (IDAM) photo by Apple
Elixir Code / DRY Refactoring Music Augmented Human (theory, scales)
Soft realtime
brew install portmidi
None
# 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})
None
Computer: Note 60 Human: WTF????
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
DocTests ❤ ## Examples iex> MusicRef.note_number_to_latin_name(60) "Do4" iex> MusicRef.note_number_to_latin_name(78) "Fa#5"
Phoenix LiveView <div> <p> Time is <%= @time %> </p>
</div> HTML? ✔
Phoenix LiveView <svg> <%= for note <- notes do %>
<rect x="..." y="0" width="10" height="20" fill="<%= note.color %>"> <% end %> </svg> SVG? ✔
Phoenix LiveView <svg> <g> # white notes </g> <g> #
black notes </g> </svg>
None
None
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
None
Code & Demo