Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Elixir, MIDI and LiveView
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Thibaut Barrère
June 18, 2019
Programming
420
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.2k
Kiba ETL v2 - RubyKaigi 2018
thbar
4
2k
Elixir hot-reloading & MIDI events generation
thbar
1
580
De Rails à Phoenix - retour d'expérience sur une réécriture d'application SaaS
thbar
3
2.4k
Processing data with Ruby and Kiba ETL
thbar
0
260
Retour d'expérience sur le bootstrapping de WiseCash (produit SaaS)
thbar
0
930
Bootstrapping your SaaS product (with freelancing)
thbar
3
630
Prestations agiles avec Acunote et Freckle
thbar
3
630
Other Decks in Programming
See All in Programming
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
4
3.5k
Seven New Principles of Software Engineering
yegor256
0
390
graphql-ruby を Spinel で速くしようとした話
mtsmfm
0
130
golang-bob.pdf
iwatsukayura
0
150
作れる、でも消せるか?──安全に「枯らして消す」機能削除術 / Drain, Then Delete
chobishiba
3
1.3k
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
utakaha
3
1.9k
Compiling a real-world CLI tool to native with Static Hermes
tmikov2023
0
140
GraphQL の onError と Nullability のこれから
quramy
0
200
TS 7.0 で baseUrl が使えなくなった今、パスエイリアスをどうするか
bicstone
1
280
선언형 햅틱 라이브러리 진동을 소개합니다
l2hyunwoo
1
140
PyConTW 2026 - AI Coding 不只是工具升級, 區域醫院醫療資訊系統協作開發與資訊團隊轉型實踐
cclai999
0
210
Modernizing iOS Apps
seyfoyun
0
140
Featured
See All Featured
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
Designing for humans not robots
tammielis
254
26k
Scaling GitHub
holman
464
140k
Information Architects: The Missing Link in Design Systems
soysaucechin
1
1.2k
GitHub's CSS Performance
jonrohan
1033
470k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
8.2k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
How to Think Like a Performance Engineer
csswizardry
28
2.9k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
590
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
340
Making the Leap to Tech Lead
cromwellryan
135
10k
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