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
ruby.wasm で作る MIDI コントローラー
Search
nagachika
June 12, 2026
Technology
140
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
1.3k
Functional Music Composition
nagachika
1
800
怠惰なRubyistへの道 - Enumerator::Lazy の使いかた@福岡Ruby会議01
nagachika
5
2.3k
ruby trunk changes 統計版
nagachika
3
350
怠惰なRubyistへの道 - Enumerator::Lazy の使いかた
nagachika
17
7.7k
Ruby Kaja のご提案
nagachika
8
2.3k
Other Decks in Technology
See All in Technology
OpenSharing について熱く語る〜AI アセットの共有について〜
kameitomohiro
0
260
LLM機能を自作して分かるSnowflake Cortex AIの強み
nayuts
0
360
転んだ話が背中を預ける理由になる / A_story_about_falling_down_gives_you_a_reason_to_watch_each_other_s_backs.pdf
pauli
3
360
OSC2026on_the-world-is-waiting-for-your-voice.pdf
naruoga
0
370
二歩目のフロントエンド・ウェブアクセシビリティ
camiha
2
380
オンラインゲームのシステム全体像 - コロプラ 2026年度 新卒研修
colopl
0
1.1k
夫婦で子育てするための育児標準化
codmoninc
PRO
0
180
DGX Spark でどこまでハッキングができるのか?
kash1064
0
620
Execution in the Kingdom of Agents: Reflections on Abstraction and Complexity
bcantrill
0
940
TinyGoでオブザーバビリティ?OpenTelemetryはTinyGoで使えるのか / Is OpenTelemetry available in TinyGo environment?
ymotongpoo
2
130
Claude Code本は、どのように執筆チームで書かれたか
oikon48
1
360
実践!Cloud Run ハンズオン!! / Cloud Run handson
y0hgi
0
210
Featured
See All Featured
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
2
2k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
22k
Building Flexible Design Systems
yeseniaperezcruz
330
41k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
490
The Cost Of JavaScript in 2023
addyosmani
55
10k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
450
エンジニアに許された特別な時間の終わり
watany
109
250k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
560
A Tale of Four Properties
chriscoyier
163
24k
Believing is Seeing
oripsolob
1
240
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 ࡞Γ͍ͨͷ͕ͲΜͲΜ༙͍ͯ͘Δ