https://github.com/cho45/complex-analyser-node
WebAudio の AnalyserNode は実数計算しかしないタイプ (仕様でそう決まっている) ですが、IQの2ch入力の信号を FFT して表示したいので、ほぼ類似のAPIを持つComplexAnalyserNodeを作ってみました。
簡単な割に IQ 信号を WebAudio で処理する際のデバッグに便利です。
FFT部分はwasmにコンパイルしたrustfftを呼んでおり、自分では実装していません。
AudioWorkletNode と AudioWorkletProcessorの使いわけ
AudioWorkletNode と AudioWorkletProcessor をうまく使いわける必要があるのですが、今回は以下のようにしています
- AudioWorkletProcessor (audio スレッドで動く)
- 入力をそのまま出力にコピーするだけ
- 入力をバッファとして貯めこみ、port 経由で AudioWorkletNode にそのまま転送する
- AudioWorkletNode (メインスレッドで動く)
- AudioWorkletProcessor からくるバッファを管理し、FFT 用のバッファを保持する
- getFloatFrequencyData() に応じてバッファの内容をFFTして返す
- 対数変換やUSB/LSBの並び換え(fftshift)も rust でやってます
こういう構成なので、wasm は普通にメインスレッドで読みこんでメインスレッドで使っています。Analyser の場合は audio スレッドで信号内容に手を加えるということはしないので、余計なことを audio スレッドでやらせたくないという気持ちがあります。
もともと WebAudio にある AnalyserNode とインターフェイスを似せようとすると同期的にしなくてはいけないので若干制約があります。全部非同期にすればもうちょいやりようがある気はします。