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
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
570
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
920
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
AI主導のプログラミング学習アプリを作ってみた
econanringo
0
130
AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”
mpyw
0
490
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
1.2k
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
140
CodeRabbitの効果検証と過ごしてみた3ヶ月
armondando
0
200
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
170
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
360
Kubernetes祭り #2 OP/ED
bells17
0
110
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
5
5k
Simple Storage Service(S3) is not simple
iwatsukayura
0
230
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
450
IBM Bob でAI駆動開発『QC-Playbook』
ichirokano2
0
100
Featured
See All Featured
The Curious Case for Waylosing
cassininazir
1
560
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
2
2k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
3
3.9k
Skip the Path - Find Your Career Trail
mkilby
1
250
How to Think Like a Performance Engineer
csswizardry
28
2.9k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Crafting Experiences
bethany
1
380
Bash Introduction
62gerente
615
220k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
[RailsConf 2023] Rails as a piece of cake
palkan
59
7.1k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
350
Thoughts on Productivity
jonyablonski
76
5.4k
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