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で音を視る
Search
ydah
June 06, 2026
Technology
560
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Rubyで音を視る
松江Ruby会議12「Rubyで音を視る」の発表スライド
https://matsue.rubyist.net/matrk12/
#matrk12
ydah
June 06, 2026
More Decks by ydah
See All by ydah
Liberating Ruby's Parser from Lexer Hacks
ydah
2
3.4k
ルールルルルルRubyの中身の予備知識 ── RubyKaigiの前に予習しなイカ?
ydah
1
960
計算機科学をRubyと歩む 〜DFA型正規表現エンジンをつくる~
ydah
3
890
進捗
ydah
2
330
Joy with 3D Graphics Using Ruby
ydah
1
160
構文解析器入門
ydah
7
3.2k
Regional.rb and the Kyoto City
ydah
0
73
LRパーサーはいいぞ
ydah
7
2k
Ruby on Railroad: The Power of Visualizing CFG
ydah
0
1.6k
Other Decks in Technology
See All in Technology
CIで使うClaude
iwatatomoya
0
290
Control Planeで育てるBtoB SaaSの認証基盤 - SRE NEXT 2026
pokohide
1
2.6k
AI時代のYAGNI:「爆速で無駄になった機能」からの学び / 20260720 Naoki Takahashi
shift_evolve
PRO
2
310
SREとQA 二人三脚で進めるSLO運用/sre-qa-slo
sugitak
0
820
関数型の考えを TypeScript に持ち込んで、テストしやすい純粋関数を増やす / Pure at the Core, Effects at the Edge: Bringing Functional Thinking into TypeScript
kaminashi
2
130
2年前に削除したPHPクラスが、 ある日突然決済をエラーにした
ykagano
1
280
Amazon EVS で VCF 9.0 / 9.1 のサポート開始まとめ
mtoyoda
0
310
Claude Code公式skillで 自分の仕事を少しずつ手放そう!(Claude Code開発ノウハウ大公開スペシャル by クラスメソッド)
kaym
1
480
そのドキュメント、自動化しませんか?
yuksew
1
290
Terraform共通モジュールをチーム横断で“変えられる”運用へ ― リリースと適用の分離
kekke_n
1
3.3k
シンガポールで登壇してきます
yama3133
0
240
Foxgloveについて 実際にExtensionを開発して公開するまでの話 / About Foxglove: The Story of Developing and Releasing an Extension
ry0_ka
0
290
Featured
See All Featured
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
340
Faster Mobile Websites
deanohume
310
32k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
250
Rails Girls Zürich Keynote
gr2m
96
14k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
1
370
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1k
A better future with KSS
kneath
240
18k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
370
Making the Leap to Tech Lead
cromwellryan
135
10k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
180
The World Runs on Bad Software
bkeepers
PRO
72
12k
SEO for Brand Visibility & Recognition
aleyda
0
4.6k
Transcript
2026/06/06 Ruby 12 Ruby seeing sound with ruby Yudai Takada,
ydah
None
None
None
None
None
Otsu City Traditional Performing Arts Hall Saturday, July 18, 2026
None
None
None
None
None
None
2026/06/06 Ruby 12 Ruby seeing sound with ruby Yudai Takada,
ydah
None
None
vizcore https://github.com/ydah/vizcore
Vizcore visualize( ) × core( ) Audio-reactive visuals Ruby DSL
Ruby scene renderer
2D/3D OpenGL
None
None
None
None
1
3
PCM samples Mic / File samples Array<Float> [ 0.0012, 0.0031,
-0.0028, . . . ]
None
Sample Window tick window 1024 60fps tick sample 圧
Samples RMS amplitude Sample RMS 夏 圧 0 [0.5, -0.5,
0.5, -0.5] (0.5 + -0.5 + 0.5 + -0.5) / 4 = 0 RMS = 1 N N ∑ i=1 x2 i
Samples FFT magnitudes / peak_frequency FFT 圧 WN = e−2πi/N
Ek = N/2−1 ∑ m=0 x2m Wkm N/2 Ok = N/2−1 ∑ m=0 x2m+1 Wkm N/2 Xk = Ek + Wk N Ok Xk+N/2 = Ek − Wk N Ok (k = 0,1,…, N 2 − 1)
magnitudes BandSplitter sub / low / mid / high FFT
Vizcore sub, low, mid, high sub: 20Hz . . 60Hz low: 60Hz . . 250Hz mid: 250Hz . . 4000Hz high: 4000Hz . . 20000Hz
Samples frame energy BeatDetector beat FFT beat beat frame 圧
E = 1 N N ∑ i=1 x2 i
beat beat_pulse beat boolean frame true 1 frame beat 圧
1.0 beat frame 0.86 長
beat history BPMEstimator bpm / beat_phase / bar_phase BPM beat
frame lag BPM beat beat beat = beat_pulse = bpm = beat_phase = bar_phase = bpm = 60.0 * frame_rate / best_lag
bands + onset drums con fi dence 圧 band onset
kick = sublow_strength * onset # sub/low ͷڧ͞ × onset snare = mid_strength * onset # mid ͷڧ͞ × onset hihat = high_strength * onset # high ͷڧ͞ × onset
magnitudes / spectrum spectral features FFT Spectral features FFT 圧
amplitude bands spectral features centroid: / rollo ff : / fl atness: / fl ux: /
raw features smoother audio features frame を EMA EMAt =
αxt + (1 − α)EMAt−1 amplitude: @sm.smooth(:amplitude, normalized[:amplitude]) bands: @sm.smooth_hash(normalized[:bands], namespace: :bands) fft: @sm.smooth_array(normalized[:fft], namespace: :fft)
amplitude bass / low high / treble beat beat_pulse bpm
/ phase spectral_* / / / / / を 長
None
audio features MappingResolver layer params map beat_pulse, to: :radius, gain:
160.0, min: 56, max: 164, attack: 1.0, release: 0.2
beat beat_pulse map beat_pulse, to: :radius, gain: 100, min: 50,
max: 150
beat map beat_pulse, to: :radius, gain: 100, min: 50, max:
150 100
beat map beat_pulse, to: :radius, gain: 100, min: 50, max:
150 50 150
beat map beat_pulse, to: :radius, gain: 100, min: 50, max:
150 radius
layer params audio_frame audio scene layers audio frame { “audio”:
{ "amplitude": 0.42, "beat": true, "beat_pulse": 1.0, "bands": { "low": 0.8 } }, "scene": { "name": "main", "layers": [ { "name": "rings", "params": { "radius": 140 } …
audio_frame WebSocket frontend WebGL renderer Frontend audio_frame Ruby Runtime Browser
Renderer (WebGL Runtime) Web Socket
6/4
BGM
None
None
50 6 4
2026/06/06 Ruby 12 Ruby seeing sound with ruby Yudai Takada,
ydah
圧 母 /
母
母 母 F1 / F2 spectral centroid low / mid
/ high ratio
F1/F2 母 F 圧 圧 : : : / :
:
母 0.0 1.0 1 F1 F2 母
None
/ / 圧 圧 burst fl atness ZCR nasal high
ratio
burst amplitude_delta = [ current[:amplitude] - previous[:amplitude], # લϑϨʔϜ͔ΒͷԻྔ૿Ճ 0.0
].max burst_strength = [ current[:onset], # Իͷ্ཱ͕ͪΓ current[:spectral_flux], # εϖΫτϧมԽྔ current.dig(:onsets, :mid), # தҬͷ্ཱ͕ͪΓ current.dig(:onsets, :high), # ߴҬͷ্ཱ͕ͪΓ amplitude_delta, # Իྔͷ૿Ճྔ recent_onset_max # ۙ૭ͷ࠷େ্ཱ͕ͪΓ ].max
spectral fl atness s_score = weighted_average([ high_ratio, # ߴҬͷڧ͞ flatness,
# ϊΠζͬΆ͞ zcr, # ܗͷࡉ͔͍༳Ε centroid # Իͷ໌Δ͞ ]) n_score = weighted_average([ nasal_score, # ඓԻͬΆ͞ 1.0 - high_ratio, # ߴҬ͕গͳ͍ low_mid_ratio, # ʙதҬͷڧ͞ 1.0 - zcr # ༳Ε͕গͳ͍ ])
attack feature attack = { strength: attack[:attack_strength], # ग़ͩ͠ͷڧ͞ centroid:
attack[:centroid_norm], # ग़ͩ͠ͷ໌Δ͞ high: attack[:high_ratio], # ߴҬͷڧ͞ low: attack[:low_ratio], # Ҭͷڧ͞ flatness: attack[:spectral_flatness],# ϊΠζͬΆ͞ zcr: attack[:zero_crossing_rate], # ࡉ͔͍༳Ε f1 : attack[:f1_frequency], # F1 ͬΆ͍ࢁ f2 : attack[:f2_frequency], # F2 ͬΆ͍ࢁ nasal: attack_nasal_score # ඓԻͬΆ͞ }
母 × kana_score = [ vowel_score * 0.55, # ԻΒ͠͞
consonant_score * 0.35, # ࢠԻΒ͠͞ burst_bonus * 0.10 # ग़ͩ͠ͷิਖ਼ ].sum candidate = { text: kana_table[consonant][vowel], # ͔ͳจࣈ vowel: vowel, # ਪఆԻ consonant: consonant, # ਪఆࢠԻ conf i dence: kana_score # ީิͷࣗ৴ }
None
vizcore Ruby ォ Ruby
$whoami ォ ydah ( ) SmartHR Ruby 西 Ruby Ruby
( 西 ) 西 圧 OSS 2