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
ruby.wasm で作る MIDI コントローラー
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
nagachika
June 12, 2026
Technology
92
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ruby.wasm で作る MIDI コントローラー
松江Ruby会議12 にて発表した ruby.wasm と Web MIDI API を活用して作成した自作シーケンサー専用の MIDI コントローラーの紹介。
nagachika
June 12, 2026
More Decks by nagachika
See All by nagachika
Pure Intonation on Browser: Building a Sequencer with Ruby
nagachika
1
1k
Functional Music Composition
nagachika
1
780
怠惰なRubyistへの道 - Enumerator::Lazy の使いかた@福岡Ruby会議01
nagachika
5
2.2k
ruby trunk changes 統計版
nagachika
3
340
怠惰なRubyistへの道 - Enumerator::Lazy の使いかた
nagachika
17
7.7k
Ruby Kaja のご提案
nagachika
8
2.2k
Other Decks in Technology
See All in Technology
OTel × Datadog で 「AI活用」を計測し、改善に繋げる
shihochan
2
1.1k
AI時代のコスト管理を考えよう〜明日から使える実践AWSノウハウ~
yoshimi0227
0
970
ご挨拶「10周年を迎える共創ラボのこれまでとこれから」
iotcomjpadmin
0
150
時期が悪い!それでもRaspberry Piを買って遊んで活用するには / 20260627-osc26do-rpi-jikigawarui
akkiesoft
1
910
飲食店もAIで。レジ締めやハンディシステムをつくってる話 / Using AI for restaurant management
vtryo
0
210
フルAIで個人開発して学んだあれこれ / yuruai vol.1
isaoshimizu
0
160
事業会社は今こそSWEを高給で雇ってWebシステムを内製しよう
masaokb
0
110
自作お家AIエージェントスタックチャンFWで困っている所紹介
74th
0
160
AWS Summit 2026で見えたSIerにとっての Amazon Quickの位置づけ
maf_0521
0
120
「勝手に広まる」人気 AI エージェントを爆速で作ろう!(AWS Summit Japan 2026講演資料)
minorun365
PRO
10
2.6k
#エンジニアBooks 30分でわかる 「技術記事を書く技術」 / engineer-books 2026-06-30
jnchito
1
130
From Prompt Engineering to Loop Engineering
shibuiwilliam
1
290
Featured
See All Featured
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.1k
Tell your own story through comics
letsgokoyo
1
980
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
200
GitHub's CSS Performance
jonrohan
1033
470k
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.9k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
170
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
250
The Limits of Empathy - UXLibs8
cassininazir
1
370
Side Projects
sachag
455
43k
Transcript
দߐ3VCZձٞ SVCZXBTNͰ࡞Δ .*%*ίϯτϩʔϥʔ !OBHBDIJLB
8)0".* w !OBHBDIJLB w $3VCZ$PNNJUUFS$3VCZTFSJFTNBJOUBJOFS w SVCZUSVOLDIBOHFT w "/%1"%'VLVPLBSC w
4PVOE1SPHSBNNFS8BOOBCF
"HFOEB w ։ൃಈػ w .*%*ͷϚοϐϯά w 8FC.*%*"1* w ϒϥβͷαϙʔτঢ়گ w
ແઢରԠ w 8FC$PNQPOFOUTԽ
։ൃಈػ
QVSJ fi FETZOUI w SVCZXBTN 8FC"VEJP"1*Ͱ։ൃ͍ͯ͠Δ७ਖ਼γʔέϯαʔ w 3VCZ,BJHJͷηογϣϯͰհ w ֨ࢠਤΤσΟλͰԻΛߏ
QVSJ fi FETZOUIͷ֨ࢠਤΤσΟλ w جԻ ֨ࢠͷதԝ ͔Β9࣠ Y ɺ:࣠ Y
Y Y ͷपൺ ֨ࢠͷҐஔͰԻߴ͕ܾ·Δ w 1"%ܕͷίϯτϩʔϥʔͰೖྗ͍ͨ͠ Y Y
1BEܕͷ.*%*ίϯτϩʔϥʔ w ࢢൢͷ1BEίϯτϩʔϥʔ΄΅ͯ͢Y Y YͳͲ ۮYۮͷύου͕ஔ͞Ε͍ͯΔͷ
حYح͕ཉ͍͠ w QVSJ fi FETZOUIͷ֨ࢠΤσΟλجԻΛத৺ʹ্Լࠨӈରশ ˠحYحͷ֨ࢠʹରԠͨ͠1BEஔͷίϯτϩϥʔ͕ཉ͍͠ w ͳ͍ͳΒ࡞Δ͔͠ͳ͍ w ཧσόΠε
w QVSJ fi FETZOUIͷΑ͏ʹ8FCΛͬͯεϚϗλϒϨοτͰಈ͔͍ͤ ͍͍Μ͡ΌͶ
PEEQBE w IUUQTOBHBDIJLBHJUIVCJPPEEQBE w SVCZXBTN 8FC.*%*"1*Ͱಈ͘Yͷύουίϯτϩʔϥʔ w QVSJ fi FETZOUIͷૢ࡞ʹಛԽͨ͠.*%*Ϛοϐϯάઃఆ
.*%*Ϛοϐϯά
.*%* .VTJDBM*OTUSVNFOU%JHJUBM*OUFSGBDF w ָثͷʮԋσʔλʯΛػثؒͰ௨৴͢ΔͨΊͷن֨ w ʮԋσʔλʯ㲈ʮԻߴʯʮൃԻͷ͞ʯʮԻͷڧ͞ʯFUDʜ w ʮԋσʔλʯ㱠ʮԻσʔλʯԻͦͷͷͰͳ͍ w CZUF
CJUT ͷόΠφϦσʔλΛෳ ଟͭ͘ ·ͱΊͨͷΛ .*%*ϝοηʔδͱݺͿ w දతʹʮεςʔλενϟϯωϧʯʮϊʔτ൪߸ʯʮϕϩγςΟʯ ͷͭΛૹ৴͢Δ
.*%*ϝοηʔδͷϚοϐϯά w όΠτͷϝοηʔδΛͲ͏ղऍ͢Δ͔ϗετʹΑΔ w Ұൠతͳ.*%*ίϯτϩʔϥʔ%"8Ͱͭ·ΈεϥΠμʔΛԿͷૢ࡞ʹ ׂΓͯΔ͔ઃఆ͢Δ͜ͱ͕Ͱ͖Δ w QVSJ fi FETZOUI֨ࢠΤσΟλ༻ʹಠࣗͷεςʔλεͷׂΓͯΛߦͳ͏
QVSJ fi FETZOUIͷ.*%*Ϛοϐϯά w OPUF൪߸ CZUF Λ֨ࢠͷҐஔʹׂΓͯΔ w $POUSPM$IBOHF $$
w ࣍ݩมߋ w ΦΫλʔϒมߋ w ϚελʔϘϦϡʔϜ
8FC.*%*"1*
8FC.*%*"1*ͷجૅ w OBWJHBUPSSFRVFTU.*%*"DDFTT .*%*ར༻ͷݖݶཁ w NJEJ"DDFTTJOQVUTೖྗϙʔτϦετ w NJEJ"DDFTTPVUQVUTग़ྗϙʔτϦετ w NJEJ*OQVUPO.*%*.FTTBHFϝοηʔδड৴࣌ίʔϧόοΫ
w NJEJ0VUQVUTFOE .*%*ϝοηʔδૹ৴ w Ҏ্ɻ͏͚ͩͳΒΊͬͪΌγϯϓϧ
ϒϥβͷαϙʔτঢ়گ
8FC.*%*ͷࠔͳ w ϒϥβͷαϙʔτঢ়گ
8FC.*%*ͷࠔͳ w ϒϥβͷαϙʔτঢ়گ w 4BGBSJະαϙʔτ w J044BGBSJ'JSFGPY$ISPNF͍ͣΕະαϙʔτ w αʔυύʔςΟʔͷΞϓϦ 8FC.*%*
.*%*8FC ͋Δ͕ಈ࡞ෆ҆ఆ w "OESPJE$ISPNF0QFSBαϙʔτ'JSFGPYະαϙʔτ ະ֬ೝ
ϞόΠϧͰͷ8FC.*%*αϙʔτঢ়گ w J04΄΅ར༻ෆՄ αʔυύʔςΟʔϒϥβ͋Δ͕සൟʹΫϥογϡ w "OESPJE$ISPNFͰ҆ఆͯ͠ಈ࡞͢Δ ೦ͳ͕ΒJ1BEͰಈ࡞͠ͳ͍ "OESPJEλϒϨοτΛಋೖ
8FC.*%*"1*ར༻ͷϋʔυϧ w ϢʔβʔΞΫγϣϯ ΫϦοΫ ʹԠ͢ΔΠϕϯτத͔͠ॳظԽͰ͖ͳ͍ w Ϣʔβʔͷ֬ೝμΠΞϩάͰͷೝՄ͕ඞਢ ϚΠΫΧϝϥͱಉ༷ w
ޡͬͯڋ൱͢ΔͱϦηοτ͢Δͷ͕ࠔ "OESPJE൛$ISPNFͰαΠτຖ ೝՄϦετʹ.*%*͕ग़ݱ͠ͳ͍ͨΊۙͷαΠτใશআ͕ඞཁ w 5-4ଓ͕ඞਢ ͘͠DISPNFTFUUJOHT͔Βྫ֎ొ w 64#έʔϒϧଓ࣌ʹຖճ༻్Λࢦఆ͢Δඞཁ͕͋Δ
ແઢରԠ
ແઢଓରԠ w 8FC#MVFUPPUI"1* #MVFUPPUI.*%* w ϞόΠϧଆͰೝࣝͤ͞Δ͜ͱ͕Ͱ͖ͣஅ೦ w 8FC4PDLFU .*%**"$υϥΠό w
1SPT.*%*ͷ͑ͳ͍J04 J1BE Ͱ͑Δ w $POT8FC.*%*"1*Λͬͯͳ͍ʜʜ ίϯτϩʔϥʔଆ
8FC4PDLFU .*%**"$υϥΠό w .*%**"$υϥΠόNBD04্Ͱ.*%*৴߸Λհ͢ΔԾσόΠε 4PVOE fl PXFSͷ.*%*൛ͱ͍͑Θ͔ΔਓʹΘ͔Δ Bridge server odd-pad
purified- synth 8FC4PDLFU .*%*ϝοηʔδ
8FC$PNQPOFOUTԽ
8FC$PNQPOFOUTԽ w QVSJ fi FETZOUIͰը໘ίϯϙʔωϯτ)5.- +4Ͱॻ͍ͨ w 8FC$PNQPOFOUT w 3FBDU7VFͷΑ͏ʹ+4ͰΧελϜίϯϙʔωϯτΛఆٛͰ͖Δ
w SVCZXBTNΛར༻ͯ͠3VCZͷΫϥεͰίϯϙʔωϯτ͕ॻ͚ͦ͏
8FC$PNQPOFOUTԽ w ͜Μͳײ͡Ͱ8FC$PNQPOFOUϞδϡʔϧΛఆٛ module WebComponent module ClassMethods def register(tag_name) ruby_class_name
= name js_code = <<~JS (() => { class RubyComponent extends HTMLElement { connectedCallback() { const id = App.eval(` inst = #{ruby_class_name}.new id = WebComponent::WC_REGISTRY.size WebComponent::WC_REGISTRY[id] = inst inst.connected_callback(this_elem) `).toJS(); this.__rubyId = id; } } customElements.define('#{tag_name}', RubyComponent); })(); JS JS.eval(js_code) end end end
8FC$PNQPOFOUTԽ w 8FC$PNQPOFOUΛJODMVEFͯ͠ίϯϙʔωϯτΫϥεΛఆٛ class PadGrid include WebComponent def connected_callback(js_element) @element
= js_element render_grid attach_events end def render_grid doc = JS.global[:document] @grid = doc.call(:createElement, "div") @grid[:className] = "grid" VIEW_YS.reverse_each do |y| VIEW_XS.each do |x| btn = doc.call(:createElement, "button") btn[:dataset][:x] = x btn[:dataset][:y] = y btn[:textContent] = note.to_s @grid.call(:appendChild, btn) end end @shadow.call(:appendChild, @grid) end
ࠓޙͷల
ࠓޙͷల w PEEQBE୯ମͰԻΛ໐Β͍ͨ͠ w ιϯάػೳ γʔέϯαʔػೳΛ͚͍ͨ w ࣗಈϘΠγϯά ԻߴͷΦΫλʔϒࣗಈௐ
w ʜʜ͋ΕɺQVSJ fi FETZOUI͍Βͳ͍ࢠ w ࡞Γ͍ͨͷ͕ͲΜͲΜ༙͍ͯ͘Δ