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
410
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Elixir, MIDI and LiveView
(Paris.Ex meetup)
Thibaut Barrère
June 18, 2019
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
150
Elixir, MIDI & LiveView (CodeElixir London 2019)
thbar
0
1.1k
Kiba ETL v2 - RubyKaigi 2018
thbar
4
2k
Elixir hot-reloading & MIDI events generation
thbar
1
560
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
250
Retour d'expérience sur le bootstrapping de WiseCash (produit SaaS)
thbar
0
910
Bootstrapping your SaaS product (with freelancing)
thbar
3
620
Prestations agiles avec Acunote et Freckle
thbar
3
610
Other Decks in Programming
See All in Programming
Gmail/Google DriveをトリガーにAIエージェントを動かそう! / Run AI agents with Gmail/Google Drive as triggers!
har1101
3
460
AI Readyの正体はデータマネジメントだ メダリオン2.0の最前線
freee
PRO
0
440
Deep dive into the select statement (GopherCon UK)
jespino
0
150
書籍「プロフェッショナルAI駆動開発」紹介スライド
juntaromatsumoto
0
800
How I Won Prize Money at a Hackathon Using Codex and Symphony Alpha
yasei_no_otoko
0
130
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
160
Loosening the Reins: Go Generics Get More Flexible
kuro_kurorrr
0
350
Press start. Python's next generation.
willingc
PRO
3
270
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
650
関東Kaggler会_NVIDIA_Nemotron_コンペ_振り返り
rick_ds
0
730
PyConJP2026_wat_Python × Signal Processing: How to Draw Pictures with Sound Using Spectrogram Art
wat
0
580
異なる設計思想のフレームワークを経験して得た学び
amekuhideki
2
850
Featured
See All Featured
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
74
42k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
The Pragmatic Product Professional
lauravandoore
37
7.4k
The Limits of Empathy - UXLibs8
cassininazir
1
620
Fashionably flexible responsive web design (full day workshop)
malarkey
408
67k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
360
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.1k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.5k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
530
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
430
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
180
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