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
350
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
110
Elixir, MIDI & LiveView (CodeElixir London 2019)
thbar
0
1.1k
Kiba ETL v2 - RubyKaigi 2018
thbar
4
1.7k
Elixir hot-reloading & MIDI events generation
thbar
1
490
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
220
Retour d'expérience sur le bootstrapping de WiseCash (produit SaaS)
thbar
0
830
Bootstrapping your SaaS product (with freelancing)
thbar
3
540
Prestations agiles avec Acunote et Freckle
thbar
3
560
Other Decks in Programming
See All in Programming
Cursorを活用したAIプログラミングについて 入門
rect
0
190
note の Elasticsearch 更新系を支える技術
tchov
9
3.6k
GitHub Copilot for Azureを使い倒したい
ymd65536
1
330
Rubyの!メソッドをちゃんと理解する
alstrocrack
1
290
KawaiiLT 登壇資料 キャリアとモチベーション
hiiragi
0
160
状態と共に暮らす:ステートフルへの挑戦
ypresto
3
1.2k
SwiftDataのカスタムデータストアを試してみた
1mash0
0
150
Golangci-lint v2爆誕: 君たちはどうすべきか
logica0419
1
250
Designing Your Organization's Test Pyramid ( #scrumniigata )
teyamagu
PRO
5
1.4k
カオスに立ち向かう小規模チームの装備の選択〜フルスタックTSという装備の強み _ 弱み〜/Choosing equipment for a small team facing chaos ~ Strengths and weaknesses of full-stack TS~
bitkey
1
140
On-the-fly Suggestions of Rewriting Method Deprecations
ohbarye
3
5.4k
20250429 - CNTUG Meetup #67 / DevOps Taiwan Meetup #69 - Deep Dive into Tetragon: Building Runtime Security and Observability with eBPF
tico88612
0
180
Featured
See All Featured
Rails Girls Zürich Keynote
gr2m
94
13k
Thoughts on Productivity
jonyablonski
69
4.6k
The Power of CSS Pseudo Elements
geoffreycrofte
75
5.8k
Reflections from 52 weeks, 52 projects
jeffersonlam
349
20k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.4k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
60k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.3k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
12k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
105
19k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
41
2.3k
Practical Orchestrator
shlominoach
187
11k
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