ブラウザDAWのオーディオエンジン仕組みを徹底解説【AudioWorklet・WebAssembly】
ブラウザDAWのオーディオエンジン:「なぜブラウザで本格的な音楽制作ができるのか」
「ブラウザDAWのオーディオエンジン」で検索する人が最も知りたいのは、なぜ・どうやってブラウザ上でDAWが動くのかという仕組みの核心です。インストール不要でリアルタイム音声処理・マルチトラック録音・エフェクトチェーンが動作するのは魔法ではなく、Web Audio API、AudioWorklet、WebAssembly(Wasm)という3つの技術スタックが組み合わさった結果です。この記事では、ブラウザDAWのオーディオエンジンがどのように設計されているか、TrackBus/MasterBusの役割、そしてWebAssemblyリライトによって何が変わったかを技術的に解説します。
Web Audio API:ブラウザDAWの土台
すべての起点は Web Audio API(W3C勧告)です。これはブラウザが標準で持つオーディオ処理グラフで、ノード(AudioNode)をつなぎ合わせることでリバーブ・EQ・コンプレッサーなどのエフェクトチェーンを構築できます。
Web Audio APIが提供するビルトインノードには次のものがあります。
- GainNode:音量調整(フェーダー)
- BiquadFilterNode:EQや簡易フィルタ
- ConvolverNode:インパルス応答を使ったリバーブ
- DynamicsCompressorNode:コンプレッサー
- DelayNode:ディレイ効果
- AnalyserNode:スペクトルアナライザー用の周波数データ取得
ただし、これだけでは複雑なカスタムDSP(Digital Signal Processing)は書けません。そこで登場するのがAudioWorkletです。
AudioWorklet:メインスレッドを止めない音声処理の鍵
Web Audio APIの旧バージョンにはScriptProcessorNodeというカスタムDSPノードがありましたが、これはメインスレッドで動作するため、UIの描画やJavaScriptの実行負荷と競合して「ぷつぷつ音切れ」が発生していました。
これを根本的に解決したのが AudioWorklet(Chrome 66 / 2018年〜)です。AudioWorkletはオーディオスレッド(Audio Rendering Thread)と呼ばれる専用スレッドで動作し、メインスレッドとは独立してサンプル精度の処理を行います。
AudioWorkletの動作フロー
- AudioWorkletProcessor の登録:
registerProcessor('my-processor', MyProcessor)でワークレットファイルにカスタムクラスを登録する - AudioWorkletNode の生成:メインスレッドから
new AudioWorkletNode(context, 'my-processor')でノードを作成し、Webオーディオグラフに接続する - process() コールバック:オーディオスレッドが128サンプル(約2.9ms @ 44.1kHz)ごとに
process(inputs, outputs, parameters)を呼び出す - MessageChannel 通信:メインスレッドとオーディオスレッドは
port.postMessage()で非同期通信する(SharedArrayBufferを使うとロックフリー通信も可能)
128サンプルのバッファサイズはWeb Audio APIの仕様で固定されており、これが処理レイテンシーの基本単位となります。44.1kHzなら約2.9ms、48kHzなら約2.67msです。
AudioWorkletとScriptProcessorNodeの比較
- ScriptProcessorNode:メインスレッド処理、バッファサイズ256〜16384サンプル、UI負荷でドロップアウト発生、現在は非推奨
- AudioWorklet:専用オーディオスレッド、128サンプル固定、メインスレッドと独立、低レイテンシーで安定
WebAssembly:ネイティブ並みのDSP処理を実現
AudioWorkletのprocess()内部でJavaScriptだけでエフェクトアルゴリズムを実装すると、GCポーズやJITコンパイルの揺らぎで音が乱れる場合があります。そこで多くのブラウザDAWは WebAssembly(Wasm) をAudioWorklet内で動かすアーキテクチャを採用しています。
WebAssemblyはC/C++/RustなどのコードをブラウザでGCなしに実行できるバイナリフォーマットです。C++で書かれたリバーブアルゴリズムやコンプレッサーをEmscriptenでWasmにコンパイルすると、JavaScriptより2〜10倍高速なDSP処理が得られます。
Wasm + AudioWorkletのパイプライン
- C/C++/Rustで書いたDSPロジックをEmscripten/wasm-packでコンパイル →
.wasmファイル生成 - AudioWorkletProcessorのスクリプト内で
WebAssembly.instantiate()してWasmモジュールをロード process()のたびにWasm側の処理関数を呼び出し、TypedArray(Float32Array)でサンプルデータをやり取り- ゼロコピーを狙う場合はWasmのメモリを直接Float32Arrayとして参照(
new Float32Array(wasmMemory.buffer, ptr, len))
この構成により、リバーブ・コンプレッサー・EQ・ディストーション・コーラスなど重いエフェクトも安定したリアルタイム処理が可能になります。
TrackBus / MasterBus 設計:DAWミキサーのアーキテクチャ
ここからはDAWエンジン固有の設計の話です。ブラウザDAWでマルチトラックを正しくミックスするには、TrackBus(トラックバス)とMasterBus(マスターバス)の概念が欠かせません。
TrackBusとは
TrackBusは「1トラック分のオーディオ信号フロー」をカプセル化したオブジェクトです。典型的な構成は以下のとおりです。
- ソースノード:AudioBufferSourceNode(オーディオクリップの再生)またはAudioWorkletNode(プラグインインストゥルメント)
- エフェクトチェーン:挿入したプラグインエフェクトのノード列(ReverbWorklet → CompressorNode → EQWorklet など)
- フェーダー&パン:GainNode × 2(L/R)またはStereoPannerNode
- センドバス:リバーブ・ディレイ用のパラレルルーティング(GainNode → 共通エフェクトノード)
- 出力:MasterBusへ接続するGainNode
MasterBusとは
MasterBusはすべてのTrackBusが最終的に接続される「マスターミックスバス」です。ここでマスターリバーブ、マスターコンプ、マスターリミッター、マスターEQなどを通したあとAudioContext.destination(スピーカー出力)へ繋ぎます。
コード上のイメージ(擬似コード):
// 各TrackBusの出力をMasterBusに集約
for (const track of tracks) {
track.outputGain.connect(masterCompressor);
}
masterCompressor.connect(masterLimiter);
masterLimiter.connect(audioContext.destination);
オフラインバウンス(エクスポート)の実装
リアルタイム再生とは別に、OfflineAudioContextを使うとリアルタイムより高速(CPUが許す限り)でオーディオをバウンスできます。OfflineAudioContextはスピーカーに出力せず、startRendering()で処理を完走させてAudioBufferとして返します。ただし、AudioWorkletやWasmプラグインをOfflineAudioContextで正しく動かすには追加の設計が必要で、これが「オフラインエクスポート対応のエンジンリライト」が難しい理由の一つです。
プラグインインストゥルメントを含むすべてのトラックを正確にエクスポートするためには、リアルタイムと同じTrackBus/MasterBusのトポロジーをOfflineAudioContext上で再現する必要があります。
WebAssembly DAWリライト:エンジンを作り直す理由と得られるもの
初期実装のブラウザDAWは「まず動かす」ことを優先してJavaScript中心の実装になりがちです。しかしユーザーが増えてプラグイン数・トラック数が増えると、JSのGCによる音切れや、エクスポート精度の問題が表面化します。そこで多くのブラウザDAWは段階的にオーディオエンジンをWebAssemblyでリライトします。
リライトの主な動機
- GCフリー:Wasmはガベージコレクションが発生しないため、
process()内でのDropout(音飛び)を排除できる - SIMD対応:WebAssembly SIMDを使うとFloat32×4の並列演算が可能になり、EQやコンプの処理速度が2〜4倍向上する
- 既存C++資産の流用:JUCE・DPF・VSTのオープンソース実装をほぼそのままEmscriptenでコンパイルできる
- オフラインエクスポートとリアルタイムの統一:同一のWasmコードをリアルタイム(AudioWorklet)とオフライン(OfflineAudioContext)両方で動かせるため、エクスポートの再現性が高い
リライト時の設計上の課題
- Wasm初期化コスト:
.wasmファイルのダウンロードとコンパイルに数百ms〜数秒かかるため、Service WorkerとIndexedDBでキャッシュする必要がある - メモリ管理:WasmのメモリはJS側から直接参照できるが、マルチスレッド(SharedArrayBuffer)を使う場合はSAB許可ヘッダー(
Cross-Origin-Opener-Policy等)が必要 - デバッグ:Wasmのデバッグはネイティブに比べて難しい。DWARF形式のデバッグシンボルを使うとChrome DevToolsでソースレベルデバッグが可能
WebGPUによるAI処理との組み合わせ
最新のブラウザDAWでは、オーディオ処理だけでなくAIモデルの推論にも WebGPU を活用するケースが増えています。たとえばボーカル除去・ステム分離・ピッチ補正などのAI機能は、GPUシェーダーで推論を行うことで、CPUだけの処理と比べて数倍〜十数倍の速度向上が期待できます。
アーキテクチャ的には、WebGPU推論(ONNXモデルのGPU実行)とAudioWorklet(リアルタイムDSP)は別スレッドで動き、処理結果をSharedArrayBufferやpostMessageで受け渡すパイプラインが一般的です。LA StudioのAIステム分離もこのWebGPUパイプラインを採用しており、インストール不要でブラウザ内に完結しています。
ブラウザDAWエンジン設計のまとめ:技術スタックの全体像
ここまでの内容を整理します。ブラウザDAWのオーディオエンジンは以下のレイヤー構造で成り立っています。
- Web Audio API(ブラウザ標準):オーディオグラフのルーティング基盤。GainNode・ConvolverNode等のビルトインDSP
- AudioWorklet:専用オーディオスレッドで動くカスタムDSP。128サンプル単位でリアルタイム処理
- WebAssembly(Wasm):AudioWorklet内でGCフリー・SIMD対応の高速DSP。C++/Rustの既存コードを流用可能
- TrackBus / MasterBus:DAW固有のミキサーアーキテクチャ。トラックごとのエフェクトチェーン+フェーダー+マスターバスへのルーティング
- OfflineAudioContext:リアルタイムより高速なバウンス処理。TrackBus/MasterBusのトポロジーを再現してオフラインエクスポート
- WebGPU(新世代):AIモデル推論をGPUで高速実行。ボーカル分離・ピッチ補正など重いAI処理をブラウザ内で完結
この設計を採用したブラウザDAWは「インストール不要」「クロスプラットフォーム(PC/Mac/Chromebook)」「ネイティブに近い処理速度」を同時に実現できます。LA Studioはこのアーキテクチャを採用し、20種以上のエフェクト・AIステム分離・NAMギターアンプシミュレーターなどを完全無料でブラウザ内に統合しています。
よくある質問
Q. AudioWorkletはすべてのブラウザで動きますか?
A. 2024年現在、Chrome・Firefox・Safari・EdgeのすべてのモダンブラウザがAudioWorkletをサポートしています。ただし、Safari 14.1以降での対応となるため、古いiOSではフォールバックが必要です。WebGPUはChrome/Edgeが先行対応しており、Firefoxは実験的フラグでの対応状況です。
Q. ブラウザDAWのオーディオレイテンシーはどのくらいですか?
A. Web Audio APIのAudioWorkletは128サンプル(44.1kHzで約2.9ms)が処理単位ですが、実際のレイテンシーはOS・ブラウザのオーディオバッファサイズに依存します。一般的にはChrome+ASIO対応環境で20〜30ms程度、通常のOS標準ドライバ環境で50〜100ms程度です。リアルタイム録音よりも編集・ミックス用途なら実用上問題ない範囲です。
Q. WebAssemblyでVSTプラグインをブラウザで動かせますか?
A. VSTのバイナリ(DLL/VST3)をそのままブラウザで動かすことはできませんが、VSTのC++ソースコードをEmscriptenでWasmにコンパイルすれば理論上ブラウザで動きます。実際にいくつかのオープンソースプラグイン(Surge XT、Dexedなど)がWasm移植されてブラウザDAWに組み込まれています。クローズドソースのVSTについては、VST Bridge(ネイティブアプリ経由でブラウザと通信するプロキシ)という手法も実用化されています。
Q. TrackBusとAuxバスの違いは何ですか?
A. TrackBusはトラックごとのメイン信号フロー(インサートエフェクト+フェーダー)を表します。Auxバス(センドバス)はトラックからパラレルに信号を分岐させてリバーブ・ディレイなどの共用エフェクトに送るための補助バスです。ブラウザDAWでは、TrackBusのGainNodeをAuxバスのGainNodeに接続し、Auxバスの出力をMasterBusに接続する形で実装します。これによりリバーブプラグインを1インスタンスだけ用意して複数トラックで共有できます。
Q. オフラインエクスポート(バウンス)とリアルタイム再生で音が違うことがあるのはなぜですか?
A. 主な原因はタイミング精度の差です。リアルタイム再生ではAudioWorkletのバッファスケジューリングがOS時間に依存するため、プラグインインストゥルメントのノートオンタイミングがわずかにずれることがあります。OfflineAudioContextはリアルタイム制約なく処理を実行できますが、AudioWorkletの初期化シーケンスや非同期ロードの扱いが不適切だと音が欠ける場合があります。TrackBus/MasterBusのトポロジーをOfflineAudioContextで完全に再現するエンジンリライトにより、この問題を解消できます。