Chrome でのウェブ オーディオ アプリのプロファイリング

about://tracingAudion(Chrome DevTools の WebAudio 拡張機能)を使用して、Chrome で Web Audio アプリのパフォーマンスをプロファイリングする方法を学びます。

この記事にアクセスしているということは、Web Audio API を使用するアプリを開発していて、出力からポップ音などの予期しないグリッチが発生した、または予期しない音が聞こえたということでしょう。すでに crbug.com のディスカッションに参加していて、Chrome エンジニアから「トレースデータ」のアップロードやグラフの可視化の確認を求められている場合があります。この記事では、問題を把握し、根本的な問題を解決できるように、関連情報を取得する方法について説明します。

ウェブ オーディオのプロファイリング ツール

Web Audio のプロファイリングには、about://tracing と Chrome DevTools の WebAudio 拡張機能の 2 つのツールが役立ちます。

about://tracing はどのような場合に使用しますか?

原因不明の「グリッチ」が発生した場合。トレースツールでアプリをプロファイリングすると、次の分析情報を得ることができます。

  • 異なるスレッドで特定の関数呼び出しに費やされた時間スライス
  • タイムライン ビューの音声コールバックのタイミング

通常、音声コールバックの期限が切れたか、予期しない音声グリッチの原因となる大規模なガベージ コレクションを示します。この情報は根本的な問題を理解するのに役立つため、特にローカルでの再現が不可能な場合は、Chromium エンジニアがよく尋ねます。トレースに関する一般的な手順については、こちらをご覧ください。

Web Audio DevTools 拡張機能はどのような場合に使用しますか?

音声グラフを可視化して、音声レンダラがどのように動作しているかをリアルタイムでモニタリングする場合。音声グラフ(音声ストリームを生成して合成する AudioNode オブジェクトのネットワーク)は複雑になることが多いですが、グラフ トポロジは設計上不透明です。(Web Audio API には、ノード/グラフのイントロスペクション機能はありません)。グラフに変化があり、音声が聞こえなくなりました。次に、リッスニングによるデバッグを行います。簡単なことではありません。音声グラフが大きいほど難しくなります。Web Audio DevTools 拡張機能を使用すると、グラフを可視化できます。

この拡張機能を使用すると、レンダリング容量の推定値をモニタリングできます。これは、特定のレンダリング バジェット(48KHz で約 2.67 ms など)でウェブ オーディオ レンダラがどのように動作するかを示します。容量が 100% 近くに達している場合、レンダラが指定された予算内で処理を完了できないため、アプリでグリッチが発生する可能性があります。

about://tracing

トレース データをキャプチャする方法

以下の手順は Chrome 80 以降を対象としています。

最良の結果を得るには、他のタブとウィンドウをすべて閉じて、拡張機能を無効にしてください。または、Chrome の新しいインスタンスを起動するか、別のリリース チャンネル(Beta や Canary など)の他のビルドを使用することもできます。ブラウザの準備ができたら、次の手順を行います。

  1. タブでアプリケーション(ウェブページ)を開きます。
  2. 別のタブを開き、about://tracing に移動します。
  3. [録画] ボタンを押して、[設定を手動で選択] を選択します。
  4. [記録カテゴリ] セクションと [デフォルトで無効なカテゴリ] セクションの両方で [なし] ボタンを押します。
  5. [Record Categories] セクションで、次の項目を選択します。
    • audio
    • blink_gc
    • media
    • v8.executeAudioWorklet JS コードのパフォーマンスに興味がある場合)
    • webaudio
  6. [デフォルトで無効なカテゴリ] セクションで、次の項目を選択します。
    • audio-workletAudioWorklet スレッドの開始位置を確認する場合)
    • webaudio.audionodeAudioNode ごとに詳細なトレースが必要な場合)
  7. 下部にある [録画] ボタンを押します。
  8. [アプリケーション] タブに戻り、問題の原因となった手順をやり直します。
  9. 十分なトレース データが収集されたら、[トレース] タブに戻り、[停止] を押します。
  10. [トレース] タブに結果が可視化されます。

    トレース完了後のスクリーンショット。

  11. [保存] を押して、トレースデータを保存します。

トレースデータを分析する方法

トレースデータは、Chrome のウェブ オーディオ エンジンが音声をレンダリングする方法を表します。レンダラには、オペレーティング システム モードワークレット モードの 2 つのレンダリング モードがあります。各モードで使用するスレッドモデルが異なるため、トレース結果も異なります。

オペレーティング システム モード

オペレーティング システム モードでは、AudioOutputDevice スレッドがすべてのウェブオーディオ コードを実行します。AudioOutputDevice は、オーディオ ハードウェア クロックで駆動されるブラウザの Audio Service から発信されるリアルタイム優先度スレッドです。このレーンのトレースデータに不規則性がある場合は、デバイスからのコールバックのタイミングがジッターしている可能性があります。Linux と Pulse Audio の組み合わせでは、この問題が発生することが知られています。詳しくは、Chromium の問題 #825823#864463 をご覧ください。

オペレーティング システム モード トレースの結果のスクリーンショット。

ワークレット モード

AudioOutputDevice から AudioWorklet スレッドへの 1 つのスレッドジャンプを特徴とする Worklet モードでは、以下に示すように、2 つのスレッドレーン内に適切に配置されたトレースが表示されます。ワークレットが有効になると、すべてのウェブオーディオ オペレーションが AudioWorklet スレッドによってレンダリングされます。このスレッドは現在、リアルタイムの優先度 1 ではありません。一般的な不規則性は、ガベージ コレクションやレンダリングの期限切れによって発生する大きなブロックです。どちらの場合も、音声ストリームにグリッチが発生します。

ワークレット モード トレース結果のスクリーンショット。

どちらの場合も、理想的なトレースデータは、音声デバイスのコールバック呼び出しが適切に調整され、レンダリング タスクが指定されたレンダリング バジェット内で完了していることが特徴です。上記の 2 つのスクリーンショットは、理想的なトレースデータの良い例です。

実際の例から学ぶ

例 1: レンダリング タスクがレンダリング バジェットを超過している

次のスクリーンショット(Chromium の問題 #796330)は、AudioWorkletProcessor のコードに時間がかかりすぎて、指定されたレンダリング バジェットを超過している典型的な例です。コールバックのタイミングは適切ですが、Web Audio API のオーディオ処理関数呼び出しが、次のデバイス コールバックの前に処理を完了できませんでした。

レンダリング タスクの予算オーバーにより発生した音声のグリッチを示す図。

選択できるオプション:

  • AudioNode インスタンスの数を減らして、オーディオグラフのワークロードを軽減します。
  • AudioWorkletProcessor のコード ワークロードを減らす。
  • AudioContext のベース レイテンシを増やします。

例 2: ワークレット スレッドで大量のガベージ コレクションが発生する

オペレーティング システムのオーディオ レンダリング スレッドとは異なり、ガベージ コレクションはワークレット スレッドで管理されます。つまり、コードでメモリの割り当て/割り当て解除(新しい配列など)を行うと、最終的にガベージ コレクションがトリガーされ、スレッドが同期的にブロックされます。ウェブ オーディオ オペレーションとガベージ コレクションのワークロードが指定されたレンダリング バジェットよりも大きい場合、音声ストリームにグリッチが発生します。次のスクリーンショットは、このケースの極端な例です。

ガベージ コレクションが原因で音声が途切れる。

選択できるオプション:

  • メモリを事前に割り当て、可能な限り再利用します。
  • SharedArrayBuffer に基づいて異なる設計パターンを使用します。これは完璧なソリューションではありませんが、いくつかのウェブ音声アプリは、SharedArrayBuffer で同様のパターンを使用して、負荷の高い音声コードを実行しています。例:

例 3: AudioOutputDevice からのジッターのあるオーディオ デバイス コールバック

ウェブ オーディオで最も重要なのは、オーディオ コールバックの正確なタイミングです。これは、システムで最も正確な時計である必要があります。オペレーティング システムまたはそのオーディオ サブシステムが確実なコールバック タイミングを保証できない場合、その後のすべてのオペレーションに影響します。次の画像は、ジッターのある音声コールバックの例です。前の 2 つの画像と比較すると、各コールバックの間隔は大きく異なります。

不安定なコールバックと安定したコールバックのタイミングを比較したスクリーンショット。

選択できるオプション:

  • latencyHint オプションを調整して、システム オーディオ コールバック バッファサイズを増やします。
  • 問題が見つかった場合は、トレースデータとともに crbug.com で問題を報告してください。

Web Audio DevTools 拡張機能を使用する

Web Audio API 専用に設計された DevTools 拡張機能も使用できます。トレースツールとは異なり、グラフとパフォーマンス指標をリアルタイムで検査できます。

この拡張機能は Chrome ウェブストアからインストールする必要があります。

インストールが完了したら、Chrome DevTools を開き、上部のメニューで [Web Audio] をクリックしてパネルにアクセスします。

Chrome DevTools で Web Audio パネルを開く方法を示すスクリーンショット。

Web Audio パネルには、コンテキスト セレクタ、プロパティ インスペクタ、グラフ ビジュアライザ、パフォーマンス モニターの 4 つのコンポーネントがあります。

Chrome DevTools の [Web Audio] パネルのスクリーンショット。

コンテキスト選択ツール

ページには複数の BaseAudioContext オブジェクトを含めることができるため、このプルダウン メニューでは、検査するコンテキストを選択できます。左側のゴミ箱アイコンをクリックして、ゴミ収集を手動でトリガーすることもできます。

物件査定士

サイドパネルには、ユーザーが選択したコンテキストまたは AudioNode のさまざまなプロパティが表示されます。AudioParam の動的値の検査はサポートされていません。

グラフ ビジュアライザ

このビューには、ユーザーが選択したコンテキストの現在のグラフ トポロジが表示されます。この可視化はリアルタイムで動的に変化します。可視化内の要素をクリックすると、プロパティ インスペクタで詳細情報を確認できます。

パフォーマンス モニター

下部にあるステータスバーは、選択した BaseAudioContext がリアルタイムで実行される AudioContext の場合にのみ有効になります。このバーには、選択した AudioContext の瞬間的な音声ストリーム品質が表示され、1 秒ごとに更新されます。次の情報が提供されます。

  • コールバック間隔(ms): コールバック間隔の加重平均/分散が表示されます。理想的には、平均は安定し、分散はゼロに近い値になるはずです。ばらつきが大きい場合は、システムレベルの音声コールバック関数のタイミングが不安定で、音声ストリームの品質が低下する可能性があります。(上記の例 3 をご覧ください)。

  • レンダリング容量(%): 容量が 100% に近づくと、レンダラが特定のレンダリング バジェットに対して過剰な処理を行っていることを意味します。この場合は、処理を減らすことを検討してください(グラフで使用する AudioNodes オブジェクトを減らすなど)。

ゴミ箱アイコンをクリックすると、ガベージ コレクタを手動でトリガーできます。

以前の WebAudio DevTools パネル

この拡張機能は Chrome Web Audio チームが推奨する方法ですが、従来の WebAudio DevTools パネルも使用できます。このパネルにアクセスするには、DevTools の右上にあるその他アイコンをクリックし、[その他のツール]、[WebAudio] の順に選択します。

Chrome DevTools で WebAudio パネルを開く方法を示すスクリーンショット。

まとめ

音声のデバッグは困難です。ブラウザで音声をデバッグするのはさらに困難です。ただし、これらのツールを使用すると、ウェブ オーディオ コードのパフォーマンスに関する有用な分析情報を確認できるため、負担を軽減できます。ただし、Chrome または拡張機能に問題が見つかることもあります。問題が解決しない場合は、crbug.com または拡張機能の Issue Tracker でバグを報告してください。

写真: Jonathan Velasquez(Unsplash