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
74
LRパーサーはいいぞ
ydah
7
2k
Ruby on Railroad: The Power of Visualizing CFG
ydah
0
1.6k
Other Decks in Technology
See All in Technology
AI Agent SaaS を支える自社仮想化基盤への挑戦と実運用 / ai-agent-saas-virtualization
flatt_security
3
4.2k
AI時代のYAGNI:「爆速で無駄になった機能」からの学び / 20260720 Naoki Takahashi
shift_evolve
PRO
2
320
CSに"SLO"は要らない、経営層に"99.9%"は伝わらない - SREを全社に"翻訳"する3原則
cscengineer
PRO
1
5.1k
Making sense of Google’s agentic dev tools
glaforge
1
280
End-to-Endで考える信頼性 —LINEアプリにおけるクライアント開発×SRE連携の実践
maruloop
4
4.6k
マルチアカウント環境でSecurity Hubの運用、その後どうなった? / SRE NEXT 2026 miniLT会
genda
0
100
【Claude Code】鹿野さんに聞く 私の推しの並行開発環境 大公開 / claude-code-parallel-2026-07-15
tonkotsuboy_com
12
8.7k
プロダクト開発組織の現在地(Ver.2026/07) / product-organization
kaonavi
0
110
大量データに対しても、生成AIを用いてリーズナブルにデータ加工をしたい!Databricksのai_queryについて調べてみた
kamoshika
1
220
壊して学ぶAWS CDK: そのcdk deployで消えるもの、残るもの
k_adachi_01
1
410
ゴールデンパスは敷いただけでは道にならない ─ 企画部門のエンジニアが技術標準を事業価値に変えるまで
mhrtech
1
220
Amazon EVS で VCF 9.0 / 9.1 のサポート開始まとめ
mtoyoda
0
310
Featured
See All Featured
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
410
A Soul's Torment
seathinner
6
3.1k
Balancing Empowerment & Direction
lara
6
1.2k
What does AI have to do with Human Rights?
axbom
PRO
1
2.2k
From π to Pie charts
rasagy
0
240
BBQ
matthewcrist
89
10k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
490
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
770
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
180
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
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