読者です 読者をやめる 読者になる 読者になる

音の鳴るブログ

鳴らないこともある

クソコードは世界を救う

以前に書いた一部のマニアには垂涎もののウェブアプリがFirefoxで動いていなかったので修正した。簡単に内容を説明するとWeb Audio APIのAudioParamの遷移をグラフ化するやつです。

グラフの値を取得するにあたって 1 だけを出力する AudioBufferSource を GainNode に接続して使っていたのだけど、どうもバッファのデータが反映されていないらしく、 0 を出力 → GainNode を通しても 0 のままとなっていたっぽい。

+--------------------+
| AudioBufferSource  | * 常に 1 を出力
| - buffer: [ 1, 1 ] |
+--------------------+
  |
+-----------+
| GainNode  | * 入力と x を積算して出力
| - gain: x |   = AudioParam の値の遷移が分かる
+-----------+
  |
+--------------------------+
| audioContext.destination |
+--------------------------+

修正前 (WebKit系なら動くけどFirefoxでは動いてなかった)

bufSrc = audioContext.createBufferSource()

bufSrc.buffer = audioContext.createBuffer(1, 2, 44100)
bufSrc.buffer.getChannelData(0).set [ 1, 1 ]

bufSrc.loop = true

修正後 (コメントと1行追加)

bufSrc = audioContext.createBufferSource()

bufSrc.buffer = audioContext.createBuffer(1, 2, 44100)
bufSrc.buffer.getChannelData(0).set [ 1, 1 ]

# 不安だからもう一度
bufSrc.buffer = bufSrc.buffer

bufSrc.loop = true

どうも bufSrc.buffer に AudioBuffer が代入された時点でバッファの内容がコピーされて、それ以降の変更がC++側に無視されている気がする。ので、再代入することで変更を反映させた。JITコンパイラが賢くなると再代入の行自体が無視されてやっぱり動かなくなるかも知れない。

この変が該当箇所だと思うけど良く分からなかった。


次回のクソコード選手権にエントリーして、散々馬鹿にされたいと思います。