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
370
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.9k
Elixir hot-reloading & MIDI events generation
thbar
1
520
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
870
Bootstrapping your SaaS product (with freelancing)
thbar
3
590
Prestations agiles avec Acunote et Freckle
thbar
3
570
Other Decks in Programming
See All in Programming
CSC307 Lecture 09
javiergs
PRO
1
850
Head of Engineeringが現場で回した生産性向上施策 2025→2026
gessy0129
0
200
AIとペアプロして処理時間を97%削減した話 #pyconshizu
kashewnuts
1
170
Geminiの機能を調べ尽くしてみた
naruyoshimi
0
190
Rubyと楽しいをつくる / Creating joy with Ruby
chobishiba
0
200
AIコーディングの理想と現実 2026 | AI Coding: Expectations vs. Reality 2026
tomohisa
0
800
ご飯食べながらエージェントが開発できる。そう、Agentic Engineeringならね。
yokomachi
1
270
TROCCOで実現するkintone+BigQueryによるオペレーション改善
ssxota
0
110
モジュラモノリスにおける境界をGoのinternalパッケージで守る
magavel
0
3.3k
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
110
PJのドキュメントを全部Git管理にしたら、一番喜んだのはAIだった
nanaism
0
220
朝日新聞のデジタル版を支えるGoバックエンド ー価値ある情報をいち早く確実にお届けするために
junkiishida
1
290
Featured
See All Featured
The Art of Programming - Codeland 2020
erikaheidi
57
14k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
55k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.2k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
110
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
280
The Limits of Empathy - UXLibs8
cassininazir
1
240
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
Documentation Writing (for coders)
carmenintech
77
5.3k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.2k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
190
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
2
480
Leading Effective Engineering Teams in the AI Era
addyosmani
9
1.7k
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