Closed6
WebAudioのパフォーマンスを改善するぞ
実装している物
- Web上で音楽を作ってあそべる
- ブラウザ上でオシレーターやサンプルをいじってシンセを作り、それをピアノロールで発声させる機能がある
- WebAudioのAudioScheduleSourceNodeでは同時発声することができないので、同時に発声する場合には複数個のノードを作成している
現状見つかっている問題点
- OscillatorNodeをstopした時にノイズが発生する
- 同時に存在するノード数が一定数を越えると音が止まる(おそらくパフォーマンスの限界がきてる)
今考えている解決策
- OscillatorNodeとAudioBufferSourceNodeで実現しているものを、すべてAudioWorkletで実装しなおしてみる
- 現状のように複数個のノードを作成するのではなく、AudioWorklet側でMIDI信号を受けて発声している音階を管理しながら同時発声する
- これにより、Node数が多すぎることによる問題と、stopを都度実行することによるノイズを同時に解決する
WASM(Rust) + AudioWorkletでやりたい気持ちもあるが、とりあえず我慢する。
WASMを使うなら次を検証する
- AudioWorkletのスレッドでWASMを使う場合、インスタンスは同一のものになるのか
- それぞれのスレッドから同じメモリにアクセスし、波形情報をとったり入れたりできるのか
- そもそもどのくらいメモリ確保してもいいものなのか(44100Hz x 10s x 2chくらいの音声データを非圧縮で展開して耐えるのか)
事例
課題
現状エンベロープをつけたり、LFOや別の音源でモジュレーションする機能があり、それをどのように実装するべきか
方針1
いっそエフェクトやモジュレーションも同時にエミュレーションしてしまう
方針2
- モジュレーションに使うAudioNodeのパラメーターはprocessの第三引数で受ける
- エンベロープのみエミュレーションする
方針1の方が圧倒的に大変だが、方針2だとそれぞれの音階に対して共通のモジュレーションソースを使うため、表現の幅が落ちるのは確実
メモ:Rust WASMするくらいなら、OffscreenCanvas使ったほうがいい説
OffscreenCanvasをmessagePortから渡して、その中でthreejsでGPGPUして波形生成する
とりあえず、全部モジュレーションする方針にしようかな。
オシレーターとサンプルの基本的な発声を作りこんで、LFOとAmplitureEnvelopeがよさげに動いたら各種エフェクトのエミュレーションも実装する形で
このスクラップは2024/01/16にクローズされました