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

過去数か月の間に、WebKit の Web Audio API が、ウェブ上のゲームやオーディオ アプリケーション向けの魅力的なプラットフォームとして浮上してきました。デベロッパーがこの機能に慣れてくると、同じような質問が繰り返し寄せられるようです。このクイック アップデートでは、Web Audio API の利便性を高めるために、よくある質問の一部を取り上げています。

Q: 音が出ません。どうすればよいですか?

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

Q. 音声コンテキストはいくつ必要ですか?

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

Q: noteOn() で再生した AudioBufferSourceNode をもう一度再生しようとしましたが、noteOn() が何もしません。どうしたらよいでしょうか?

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

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

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

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

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

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

<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 を使用しているためです。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: 現在のところ、この機能はサポートされていませんが、現在調査中です。こちらの機能リクエストをご覧ください。

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