Chrome では、Web Audio API のサポートを継続的かつ密に改善してきました。Chrome 49(2016 年 2 月時点でベータ版で提供され、2016 年 3 月に Stable 版になる予定です)では、仕様を追跡するためにいくつかの機能が更新され、新しいノードが 1 つ追加されました。
decodeAudioData() が Promise を返すようになりました
AudioContext
の decodeAudioData() メソッドが Promise
を返すようになり、Promise ベースの非同期パターン処理が可能になりました。decodeAudioData()
メソッドは常に成功とエラー コールバック関数をパラメータとして受け取ります。
context.decodeAudioData( arraybufferData, onSuccess, onError);
代わりに標準の Promise メソッドを使用して、音声データをデコードする非同期の性質を処理できるようになりました。
context.decodeAudioData( arraybufferData ).then(
(buffer) => { /* store the buffer */ },
(reason) => { console.log("decode failed! " + reason) });
1 つの例では冗長に見えますが、Promise を使用すると、非同期プログラミングがより簡単で一貫性の高いものになります。互換性を確保するため、仕様に従って、成功およびエラーのコールバック関数は引き続きサポートされます。
OfflineAudioContext が suspend() と restore() をサポートするようになりました
一見すると、OfflineAudioContext に suspend() があると不思議に思えるかもしれません。結局のところ、オーディオ ハードウェアをスタンバイ モードにするため、suspend()
が AudioContext
に追加されました。これは、バッファにレンダリングするシナリオでは無意味に思えます(もちろん OfflineAudioContext
の場合です)。ただし、この機能のポイントは、メモリ使用量を最小限に抑えるために、一度に「スコア」の一部のみを構築できるようにすることです。レンダリングの途中で一時停止している間、追加のノードを作成できます。
たとえば、ベートーヴェンの「月光ソナタ」には 6,500 音ほどの音符が含まれています。
各「音」は、おそらく少なくともいくつかのオーディオ グラフノード(AudioBuffer ノードと ゲイン ノードなど)に分解されます。OfflineAudioContext
で 7 分半全体をバッファにレンダリングする場合、これらのノードを一度にすべて作成することはおすすめしません。代わりに、複数の時間セットで作成できます。
var context = new OfflineAudioContext(2, length, sampleRate);
scheduleNextBlock();
context.startRendering().then( (buffer) => { /* store the buffer */ } );
function scheduleNextBlock() {
// create any notes for the next blockSize number of seconds here
// ...
// make sure to tell the context to suspend again after this block;
context.suspend(context.currentTime + blockSize).then( scheduleNextBlock );
context.resume();
}
これにより、レンダリングの開始時に事前作成する必要があるノードの数を最小限に抑え、メモリの需要を削減できます。
IIRFilterNode
この仕様では、正確に指定された独自の infinite-impulse-response を作成したいオーディオ マニア向けのノード IIRFilterNode が追加されています。このフィルタは BiquadFilterNode を補完するものですが、フィルタのレスポンス パラメータを完全に指定できます(タイプ、周波数、Q などについて BiquadFilterNode
の使いやすい AudioParams
を指定することはできません)。IIRFilterNode
を使用すると、単一順序フィルタなど、これまで作成できなかったフィルタを正確に指定できます。ただし、IIRFilterNode を使用するには、IIR フィルタの仕組みに関する深い知識が必要です。また、BiquadFilterNodes のようにスケジュールすることもできません。
以前の変更
また、以前実施された改善点もいくつかあります。Chrome 48 では、BiquadFilter
ノードの自動化が音声レートで実行され始めました。このために API はまったく変更されていませんが、これはフィルタ スイープがより滑らかに聞こえることを意味します。また Chrome 48 では、接続先のノードを返すことで AudioNode.connect()
メソッドにチェーンを追加しました。これにより、次の例のように、ノードのチェーンを簡単に作成できます。
sourceNode.connect(gainNode).connect(filterNode).connect(context.destination);
これで終わりです。続けてください!