ウェブ音声の更新(Chrome 49)

Chris Wilson
Chris Wilson

Chrome では、Web Audio API のサポートを着実に改善してきました。Chrome 49(2016 年 2 月時点ではベータ版、2016 年 3 月に Stable 版になる予定)では、仕様を追跡するためにいくつかの機能を更新し、新しいノードを 1 つ追加しました。

decodeAudioData() が Promise を返すようになりました

AudioContextdecodeAudioData() メソッドが 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 を使用すると、非同期プログラミングがより簡単かつ一貫したものになります。互換性のため、仕様どおり、Success と Error のコールバック関数は引き続きサポートされます。

OfflineAudioContext で suspend() と resume() がサポートされるようになりました

一見すると、OfflineAudioContext に suspend() があることに違和感があるかもしれません。結局のところ、suspend() はオーディオ ハードウェアをスタンバイ モードにすることを可能にするために AudioContext に追加されました。これは、バッファにレンダリングしているシナリオでは無意味です(もちろん、これは OfflineAudioContext の目的です)。ただし、この機能のポイントは、メモリ使用量を最小限に抑えるために、一度に「スコア」の一部のみを構築できることです。レンダリングの途中で停止している間に、さらにノードを作成できます。

たとえば、ベートーベンの月光ソナタには約 6,500 個の音符が含まれています。各「音符」は、少なくとも 2 つの音声グラフノード(AudioBuffer ノードと Gain ノードなど)に分解されます。7 分半全体を OfflineAudioContext でバッファにレンダリングする場合、これらのノードをすべて一度に作成する必要はありません。代わりに、時間のチャンクで作成できます。

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

仕様に、正確に指定された独自の無限インパルス応答を作成したいオーディオ愛好家向けのノード(IIRFilterNode)が追加されました。このフィルタは BiquadFilterNode を補完しますが、タイプ、周波数、Q などの BiquadFilterNode の使いやすい AudioParams ではなく、フィルタ レスポンス パラメータを完全に指定できます。IIRFilterNode を使用すると、単一オーダー フィルタなど、以前は作成できなかったフィルタを正確に指定できます。ただし、IIRFilterNode を使用するには、IIR フィルタの仕組みに関する深い知識が必要です。また、BiquadFilterNode のようにスケジューリングもできません。

以前の変更内容

また、以前に行われたいくつかの改善についても説明します。Chrome 48 では、BiquadFilter ノードの自動化が音声レートで実行されるようになりました。この変更のために API はまったく変更されていませんが、フィルタ スイープの音がさらにスムーズになります。Chrome 48 では、接続先のノードを返すことで、AudioNode.connect() メソッドにチェーンを追加しました。これにより、次ののように、ノードのチェーンを簡単に作成できます。

sourceNode.connect(gainNode).connect(filterNode).connect(context.destination);

以上です。今後ともよろしくお願いいたします。