ウェブ オーディオに関するよくある質問

ここ数か月で、WebKit の Web Audio API は、ウェブ上のゲームや音声アプリケーションにとって魅力的なプラットフォームとして台頭してきました。開発者がこの機能に慣れてくると、同様の質問が繰り返し寄せられるようになります。この簡単な更新は、Web Audio API の使用感をより快適にするために、よくある質問の一部に対応することを目的としています。

Q: 音が出ません。

A: Web Audio API を初めて使用する場合は、スタートガイドのチュートリアルまたは ユーザー インタラクションに基づいて音声を再生する Eric のレシピをご覧ください。

Q. オーディオ コンテキストはいくつ必要ですか?

A: 一般的に、1 ページに 1 つの AudioContext を含める必要があります。1 つの音声コンテキストで、それに接続された多くのノードをサポートできます。1 つのページに複数の AudioContext を含めることはできますが、パフォーマンスが低下する可能性があります。

Q: noteOn() で再生した AudioBufferSourceNode をもう一度再生したいのですが、noteOn() を呼び出しても何も起こりません。どうしたらよいでしょうか?

A: ソースノードは、一度再生を終了すると、それ以上再生できません。基盤となるバッファを再度再生するには、新しい AudioBufferSourceNode を作成して noteOn() を呼び出す必要があります。

ソースノードの再作成は非効率的に思えるかもしれませんが、ソースノードはこのパターンに合わせて大幅に最適化されています。また、AudioBuffer のハンドルを保持していれば、同じ音を再生するためにアセットに再度リクエストする必要はありません。このパターンを繰り返す必要がある場合は、playSound(buffer) などのシンプルなヘルパー関数で再生をカプセル化します。

Q: 音を再生するときに、毎回新しいソースノードを作成する必要があるのはなぜですか?

A: このアーキテクチャの目的は、音声アセットと再生状態を分離することです。レコード プレーヤーに例えると、バッファはレコード、ソースは再生ヘッドに相当します。多くのアプリケーションでは、同じバッファの複数のバージョンが同時に再生されるため、このパターンは不可欠です。

Q: audio タグと video タグの音声を処理するにはどうすればよいですか?

A: MediaElementAudioSourceNode は現在開発中です。利用可能な場合、おおむね次のように動作します(音声タグで再生されるサンプルにフィルタ効果を追加します)。

<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);

この機能はこちらの crbug で追跡されています。この設定では mediaSourceNode.noteOn() を呼び出す必要はありません。音声タグが再生を制御します。

Q: マイクから音が出るのはいつですか?

A: このオーディオ入力部分は、getUserMedia を使用して WebRTC の一部として実装され、Web Audio API の特別なソースノードとして利用できるようになります。createMediaElementSource と連携して動作します。

Q: AudioSourceNode の再生が終了したことを確認するにはどうすればよいですか?

A: 現在、Web Audio API はこの機能をサポートしていないため、JavaScript タイマーを使用する必要があります。Web Audio API スタートガイドの次のスニペットは、この動作の例です。

// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
    console.log('playback finished');
}, buffer.duration * 1000);

Web Audio API でより正確なコールバックを実装するための未解決のバグがあります。

Q: サウンドを読み込むと、UI スレッド全体がロックされ、UI が応答しなくなります。ヘルプ!**

A: decodeAudioData API を使用して非同期読み込みを行い、メインスレッドのブロックを回避します。こちらの例をご覧ください。

Q: Web Audio API を使用して、リアルタイムよりも速く音声を処理できますか?

A: はい、解決策に取り組んでいます。もうしばらくお待ちください。

Q: 素晴らしい Web Audio API アプリケーションを作成しましたが、実行中のタブがバックグラウンドに移動すると、音が変になります。

A: setTimeouts を使用していることが原因である可能性があります。 は、ページがバックグラウンドに移動すると動作が異なります。今後、Web Audio API は、ウェブ音声の内部タイマー(context.currentTime 属性)を使用して、特定の時間にコールバックできるようになります。詳しくは、こちらの機能リクエストをご覧ください。

一般に、アプリがバックグラウンドに移行したときに再生を停止することをおすすめします。Page Visibility API を使用すると、ページがバックグラウンドに移行したタイミングを検出できます。

Q: Web Audio API を使用して音の高さを変更するにはどうすればよいですか?

A: ソースノードの playbackRate を変更します。

Q: スピードを変更せずにピッチを変更できますか?

A: Web Audio API にはオーディオ コンテキストに PitchNode を含めることができますが、実装は困難です。これは、音声コミュニティに単純なピッチ シフト アルゴリズムがないためです。既知の手法では、特にピッチシフトが大きい場合にアーティファクトが作成されます。この問題に対処するには、次の 2 つのアプローチがあります。

  • 時間領域アルゴリズム。セグメントの反復エコー アーティファクトが発生します。
  • 周波数領域の手法。残響音のアーティファクトが発生します。

これらの手法を実行するためのネイティブ ノードはありませんが、JavaScriptAudioNode を使用して実行できます。このコード スニペットを参考にしてください。

Q: 任意のサンプルレートで AudioContext を作成するにはどうすればよいですか?

A: 現在、この機能はサポートされていませんが、対応を検討しています。こちらの機能リクエストをご覧ください。

ご不明な点がございましたら、web-audio タグを使用して StackOverflow でお気軽にご質問ください。