要約

この仕様はWebアプリケーションにおけるオーディオの処理および合成に関する高レベルの JavaScript API について記述します。 その基本的な枠組みとなっているのはオーディオのルーティンググラフであり、 多数のAudioNodeオブジェクトが互いに接続される事で最終的なオーディオ出力が定義されます。 実際の処理は基本的に下層にある実装 (典型的には最適化されたアセンブリ言語/C/C++コード)で行われますが、 JavaScriptによる直接的な処理と合成もサポートされています。

序文セクションではこの仕様の背後にある動機についても取り上げます。

このAPIは他のAPIやWebプラットフォームの要素、 特に(responseTyperesponse 属性を使った) XMLHttpRequest[XHR] と共に使われるように設計されています。 ゲームやインタラクティブなアプリケーションでは、canvas 2D [2dcontext] および WebGL [WEBGL]3D グラフィックスAPIと共に使われる事が予想されます。

この文書の位置付け

このセクションは、この文書の公開時における状況を記述したものです。 他の文書がこの文書に取って代わるかもしれません。 現在のW3Cの刊行物およびこの技術レポートの最新改訂版のリストは、W3C技術レポートhttp://www.w3.org/TR/のリストから見つけることができます。

この文書はAudio Working Groupによってワーキングドラフトとして発行されました。 この文書はW3Cリコメンデーションとなる事を意図しています。 もしこの文書に対するコメントがあれば、 public-audio@w3.org(subscribe, archives)に送ってください。 全てのコメントを歓迎します。

ワーキングドラフトとしての公開はW3Cメンバーによる承認を意味するものではありません。 これは草案文書であり、いつでも他の文書によって改訂、置き換えあるいは廃止される可能性があります。 この文書を作業中のもの以外として引用する事は不適切です。

この文書は2004年2月5日 W3C Patent Policyの基に運用されるグループによって作成されました。 W3Cはグループの成果物から作成された特許開示リストを管理しています。 また、このページは特許開示の方法についても提示しています。 特許について実際の知識を持ち、それが基本的な請求事項を含むと考える者は、 W3C Patent Policy 6節に従って情報を開示しなくてはなりません。

この文書は2015年9月1日 W3C Process Document によって管理されます。

目次

序文

これまでのWeb上のオーディオはかなり未発達なもので、ごく最近まで Flash や QuickTime のようなプラグインを通して配信しなくてはなりませんでした。 HTML5 での audio 要素の導入は、基本的なストリーミング・オーディオ再生を可能にする重要なものです。 しかし、より複雑なオーディオアプリケーションを扱うには、それだけではまだ充分に強力ではありません。 洗練されたWebベースのゲームやインタラクティブ・アプリケーションのためには別の解決策が必要とされます。 この仕様では、近年のデスクトップ・オーディオ制作アプリケーションに見られるミキシング、プロセシング、フィルタリング処理に加え、近年のゲームオーディオエンジンに見られるような機能も持たせる事を目標とします。

この API はさまざまな使用例 [webaudio-usecases] を考慮して設計されています。 理想的には全ての使用例が、 JavaScript から制御される最適化された C++ エンジンを使って無理なく実装でき、ブラウザで動作するようにサポートされなくてはなりません。 とは言っても、近年のデスクトップ・オーディオソフトウェアは極めて高度な機能を持ち、それらの一部はこのシステムを使ったとしても構築する事が困難か不可能と考えられます。 Apple 社の Logic Audio がそのようなアプリケーションの1つであり、外部 MIDI コントローラー、任意のプラグイン・オーディオエフェクトやシンセサイザー、高度に最適化されたオーディオファイルのディスクへの読み込み/書き出し、密に統合されたタイムストレッチなどなどをサポートしています。 それでもなお、ここで提案するシステムは、音楽に関するものを含めて、かなり複雑なゲームやインタラクティブ・アプリケーションの広い範囲を充分にサポートする事が可能です。 またそれは、 WebGL によってもたらされる、より高度なグラフィックスの機能をよく引き立たせる事が可能です。 このAPIはより高度な機能を後から追加できるように設計されています。

0.1 機能

この API は、これらの基本機能をサポートします:

0.1.1 モジュラールーティング

モジュラールーティングによって異なる AudioNode オブジェクト同士を任意に接続できます。 それぞれのノードは入力および出力を持っています。 ソースノードは入力は持たず、1つの出力を持ちます。 デスティネーションノードは1つの入力を持ち、出力は持っていません。この最も一般的な例が最終的なオーディオハードウェアに繋がるAudioDestinationNodeです。 フィルタなどの他のノードはソースとデスティネーションの間に配置することができます。 2つのオブジェクトが互いに接続している場合、低レベルのストリーム形式の詳細について開発者が煩わされる事なく、適正な処理が行われます。 例えばもしモノラルの音声ストリームがステレオの入力に接続されていても、左右のチャンネルに適正にミックスされます。

最も単純な例は、1つの音声ソースを出力に直接接続したものです。 すべての接続は単一のAudioDestinationNodeを持つAudioContext内部で行われます:

modular routing
1 モジュラールーティングの単純な例

この単純なルーティングを図示します。この例では単一の音を再生しています:

例 1
var context = new AudioContext();

function playSound() {
    var source = context.createBufferSource();
    source.buffer = dogBarkingBuffer;
    source.connect(context.destination);
    source.start(0);
}

これはもっと複雑な例で、3つのソースとコンボリューションリバーブが最終出力段にあるダイナミックコンプレッサーを介して送られます:

modular routing2
2 モジュラールーティングのより複雑な例
例 2
var context = 0;
var compressor = 0;
var reverb = 0;

var source1 = 0;
var source2 = 0;
var source3 = 0;

var lowpassFilter = 0;
var waveShaper = 0;
var panner = 0;

var dry1 = 0;
var dry2 = 0;
var dry3 = 0;

var wet1 = 0;
var wet2 = 0;
var wet3 = 0;

var masterDry = 0;
var masterWet = 0;

function setupRoutingGraph () {
    context = new AudioContext();

    // Create the effects nodes.
    lowpassFilter = context.createBiquadFilter();
    waveShaper = context.createWaveShaper();
    panner = context.createPanner();
    compressor = context.createDynamicsCompressor();
    reverb = context.createConvolver();

    // Create master wet and dry.
    masterDry = context.createGain();
    masterWet = context.createGain();

    // Connect final compressor to final destination.
    compressor.connect(context.destination);

    // Connect master dry and wet to compressor.
    masterDry.connect(compressor);
    masterWet.connect(compressor);

    // Connect reverb to master wet.
    reverb.connect(masterWet);

    // Create a few sources.
    source1 = context.createBufferSource();
    source2 = context.createBufferSource();
    source3 = context.createOscillator();

    source1.buffer = manTalkingBuffer;
    source2.buffer = footstepsBuffer;
    source3.frequency.value = 440;

    // Connect source1
    dry1 = context.createGain();
    wet1 = context.createGain();
    source1.connect(lowpassFilter);
    lowpassFilter.connect(dry1);
    lowpassFilter.connect(wet1);
    dry1.connect(masterDry);
    wet1.connect(reverb);

    // Connect source2
    dry2 = context.createGain();
    wet2 = context.createGain();
    source2.connect(waveShaper);
    waveShaper.connect(dry2);
    waveShaper.connect(wet2);
    dry2.connect(masterDry);
    wet2.connect(reverb);

    // Connect source3
    dry3 = context.createGain();
    wet3 = context.createGain();
    source3.connect(panner);
    panner.connect(dry3);
    panner.connect(wet3);
    dry3.connect(masterDry);
    wet3.connect(reverb);

    // Start the sources now.
    source1.start(0);
    source2.start(0);
    source3.start(0);
}

モジュラールーティングはまた AudioNode の出力を 別の AudioNode の動きを制御する AudioParam パラメータに接続する事もできます。この場合は、ノードからの出力は 入力信号ではなくモジュレーション信号として働きます。

modular routing3
3 モジュラールーティングによってオシレータの出力で別のオシレータの周波数を変調する
例 3
function setupRoutingGraph() {
  var context = new AudioContext();

  // Create the low frequency oscillator that supplies the modulation signal
  var lfo = context.createOscillator();
  lfo.frequency.value = 1.0;

  // Create the high frequency oscillator to be modulated
  var hfo = context.createOscillator();
  hfo.frequency.value = 440.0;

  // Create a gain node whose gain determines the amplitude of the modulation signal
  var modulationGain = context.createGain();
  modulationGain.gain.value = 50;

  // Configure the graph and start the oscillators
  lfo.connect(modulationGain);
  modulationGain.connect(hfo.detune);
  hfo.connect(context.destination);
  hfo.start(0);
  lfo.start(0);
}

0.2 API の概要

定義されているインターフェースは次の通りです:

また非推奨ですがまだ削除されておらず、置き換えの実装が予定されているいくつかの Web Audio API があります。

1. 準拠

この仕様内で参考情報と書かれているセクション、オーサリングガイドライン、図、例、注は非基準要件です。この仕様内のそれ以外の全ては基準要件となります。

キーワードMUSTREQUIREDSHALL は [RFC2119] に記述されているように解釈されます。

次の準拠クラスがこの仕様によって定義されています:

準拠した実装

この仕様の全てのMUST-、 REQUIRED-、 SHALL レベルの基準を満足する実装がされているユーザーエージェントが、準拠した実装と判断されます。

この仕様で定められたAPIの実装にECMAScriptを使用するユーザーエージェントは、Web IDL仕様 [WEBIDL]で定義されるECMAScriptバインディングの仕様と用語がこの仕様での使用と矛盾しない方法で実装しなくてはなりません。

2. オーディオ API

2.1 BaseAudioContext インターフェース

このインターフェースはAudioNodeオブジェクトのセットを表します。それは信号をAudioDestinationNodeに任意のルーティングする事を可能にします。 ノードはコンテキストから作成され、お互いに接続されます。

BaseAudioContextは直接的にはインスタンス化されず、代わりにAudioContext(リアルタイムレンダリングの場合)とOfflineAudioContext(オフラインレンダリングの場合)が拡張された具体的なインターフェースとなっています。

enum AudioContextState {
    "suspended",
    "running",
    "closed"
};
列挙値の説明
suspended このコンテキストは現在中断(コンテキストの時間は進まず、オーディオハードウェアはパワーダウン/解放)しています。
running オーディオは処理状態にあります。
closed このコンテキストは解放され、もうオーディオ処理に使用できません。全てのシステムオーディオリソースは解放されました。 新しいノードを作成しようとすると InvalidStateError が発生します。(AudioBufferは createBuffer or decodeAudioDataを通してまだ作成できるかも知れません)
enum AudioContextPlaybackCategory {
    "balanced",
    "interactive",
    "playback"
};
列挙値の説明
balanced オーディオ出力のレイテンシーと安定性/消費電力のバランスを取ります。
interactive オーディオ出力のレイテンシーをグリッジが発生しない最小値にする。これがデフォルトになります。
playback オーディオ出力のレイテンシーよりも再生の途切れを起こさない事を優先します。消費電力は最も低くなります。
dictionary AudioContextOptions {
             AudioContextPlaybackCategory playbackCategory = "interactive";
};

callback DecodeErrorCallback = void (DOMException error);

callback DecodeSuccessCallback = void (AudioBuffer decodedData);

[Constructor(optional AudioContextOptions contextOptions)] interface BaseAudioContext : EventTarget { readonly attribute AudioDestinationNode destination; readonly attribute float sampleRate; readonly attribute double currentTime; readonly attribute AudioListener listener; readonly attribute AudioContextState state; Promise<void> suspend (); Promise<void> resume (); Promise<void> close (); attribute EventHandler onstatechange; AudioBuffer createBuffer (unsigned long numberOfChannels, unsigned long length, float sampleRate); Promise<AudioBuffer> decodeAudioData (ArrayBuffer audioData, optional DecodeSuccessCallback successCallback, optional DecodeErrorCallback errorCallback); AudioBufferSourceNode createBufferSource (); Promise<AudioWorker> createAudioWorker (DOMString scriptURL); ScriptProcessorNode createScriptProcessor (optional unsigned long bufferSize = 0 , optional unsigned long numberOfInputChannels = 2 , optional unsigned long numberOfOutputChannels = 2 ); AnalyserNode createAnalyser (); GainNode createGain (); DelayNode createDelay (optional double maxDelayTime = 1.0 ); BiquadFilterNode createBiquadFilter (); IIRFilterNode createIIRFilter (sequence<double> feedforward, sequence<double> feedback); WaveShaperNode createWaveShaper (); PannerNode createPanner (); SpatialPannerNode createSpatialPanner (); StereoPannerNode createStereoPanner (); ConvolverNode createConvolver (); ChannelSplitterNode createChannelSplitter (optional unsigned long numberOfOutputs = 6 ); ChannelMergerNode createChannelMerger (optional unsigned long numberOfInputs = 6 ); DynamicsCompressorNode createDynamicsCompressor (); OscillatorNode createOscillator (); PeriodicWave createPeriodicWave (Float32Array real, Float32Array imag, optional PeriodicWaveConstraints constraints); };

2.1.1 属性

currentTime double 型, readonly

コンテキストのレンダリンググラフで最後に処理されたオーディオブロックの最後のサンプルフレームの次のサンプルの秒で表した時刻です。もしコンテキストのレンダリンググラフがまだオーディオブロックを処理していない場合 currentTime は0になります。

currentTimeの時間軸で0はグラフで処理される最初のブロックの最初のサンプルフレームに対応します。このシステムの経過時間はBaseAudioContextが生成するオーディオストリームの経過時間に対応し、それはシステム内の他の時計には同期しないかも知れません。(OfflineAudioContextでは、ストリームはどのデバイスも能動的に再生しないため、実時間とはまったく違う進み方になります)

Web Audio API の全てのスケジュールされた時刻は currentTime に対する相対値になります。

BaseAudioContextrunning 状態にある時、この属性は単調増加し、レンダリングスレッドにより128サンプルのブロックサイズに対応する均一な増分で更新されます。そのため動作中のコンテキストでは、 currentTime はシステムがオーディオブロックを処理するに従って徐々に増加し、常に次に処理されるオーディオブロックの先頭の時刻を表します。それはまた現在の状態に対する変更が効力を持つ最も早い時刻でもあります。

destination AudioDestinationNode 型, readonly

AudioDestinationNode は単一の入力を持ち、全てのオーディオの最終的な出口を表しています。 通常これは実際のオーディオハードウェアを表します。 動作中のすべての AudioNode は直接または間接的にこの destination に接続されます。

listener AudioListener 型, readonly

AudioListenerは3D 空間音響で使用されます。

onstatechange EventHandler

BaseAudioContext にAudioContext の状態が変化した時(例えば、対応する Promise がリゾルブされた時など)にディスパッチされるイベントの EventHandler を設定するために使用されるプロパティです。新たに作成された AudioContextは 常に "suspended" 状態から開始し、状態の変化イベントは異なる状態への遷移の度に発行されます。

sampleRate float 型, readonly

BaseAudioContext が扱うオーディオのサンプルレート(1秒あたりのサンプルフレーム数)です。 コンテキスト内のすべての AudioNode はこのレートで動作する事を想定しています。 これを想定するため、サンプレートコンバータや"可変速"処理はリアルタイム処理内ではサポートされません。

state AudioContextState 型, readonly

BaseAudioContext の現在の状態を表します。コンテキストの状態は、"suspended" から開始し、システムのリソースを確保してオーディオの処理を開始した時に "running" に遷移します (MUST)。OfflineAudioContext の場合は、 startRendering() が呼び出されるまで state は "suspended" のままで、呼び出されたのちに "running" に遷移し、オーディオ処理が完了すると "close" に遷移して oncomplete (訳注:イベント) が発行されます。

state が "suspended" の時、 resume() を呼び出すと "running" に遷移し、また close() を呼び出すと "closed" に遷移します。

state が "running" の時、 suspend() を呼び出すと "suspended" に遷移し、また close() を呼び出すと "closed" に遷移します。

state が "closed" の時、これ以上の状態の遷移はできません。

2.1.2 メソッド

close

オーディオコンテキストをクローズし、BaseAudioContext で使用されていたシステムの全てのリソースを解放します。 この呼び出しでは他からの参照が同様に開放されない限り BaseAudioContext が作成したオブジェクトは全て自動的には解放されません。しかし、これ以降にオーディオコンテキストが作成され、使用され、BaseAudioContextcurrentTime の進行を suspend し、処理を終了する事を妨げる可能性のあるシステムのオーディオリソースは強制的に開放されます。 Promise は、全てのオーディオコンテキストの作成をブロックするリソースが解放された時にリゾルブされます。もしこれが OfflineAudioContext に対して呼び出された場合、InvalidStateError の名前の DOMException で Promise はリジェクトされます。

パラメータなし
戻り値: Promise<void>
createAnalyser

AnalyserNode を作成します。

パラメータなし
戻り値: AnalyserNode

createAudioWorker
AudioWorker オブジェクトを作成し、対応するスクリプトを AudioWorkerGlobalScope にロードして返却した Promise をリゾルブします。
パラメータNull可省略可説明
scriptURLDOMString このパラメータはAudioWorkerノードファクトリとしてロードするスクリプトのURLを表します。 詳細は AudioWorker セクションを参照してください。
戻り値: Promise<AudioWorker>
createBiquadFilter
幾つかのタイプのフィルタに設定可能な2次フィルタを表す BiquadFilterNode を作成します。
パラメータなし
戻り値: BiquadFilterNode
createBuffer
与えられたサイズの AudioBuffer を作成します。バッファ内のデータは0(無音)で初期化されます。 もし、引数のどれかが負、0または範囲外の場合、NotSupportedError 例外を発生します(MUST)。
パラメータNull可省略可説明
numberOfChannelsunsigned long バッファが持つチャンネル数を指定します。 実装は少なくとも32チャンネルをサポートしなくてはなりません。
lengthunsigned long バッファのサイズをサンプルフレーム数で指定します。
sampleRatefloat バッファ内のリニアPCMオーディオデータのサンプルレートを秒あたりのサンプルフレーム数で表します。 実装は少なくとも8192から96000の範囲をサポートしなくてはなりません。
戻り値: AudioBuffer
createBufferSource
AudioBufferSourceNodeを作成します。
パラメータなし
createChannelMerger
チャンネル結合器を表す ChannelMergerNode を作成します。 パラメータの値が無効の場合、IndexSizeError 例外を発生します(MUST)。
パラメータNull可省略可説明
numberOfInputsunsigned long = 6 numberOfInputs は入力の数を指定します。値は32までサポートされなくてはなりません。 もし指定されない場合は6となります。
createChannelSplitter
チャンネル分割器を表す ChannelSplitterNode を作成します。 パラメータの値が無効の場合、IndexSizeError 例外を発生します(MUST)。
パラメータNull可省略可説明
numberOfOutputsunsigned long = 6 出力の数を指定します。32までサポートされなくてはなりません。 もし指定されない場合は6となります。
createConvolver
ConvolverNodeを作成します。
パラメータなし
戻り値: ConvolverNode
createDelay
遅延時間が可変な遅延機能を表す DelayNodeを作成します。 初期化時のデフォルト遅延時間は0秒です。
パラメータNull可省略可説明
maxDelayTimedouble = 1.0 maxDelayTime パラメータはオプションであり、その遅延機能の遅延時間の最大値を秒で指定します。 もし指定する場合は、その値は0よりも大きく3分よりも小さくなければなりません(MUST)。そうでない場合 NotSupportedError 例外を発生します(MUST)。
戻り値: DelayNode
createDynamicsCompressor
DynamicsCompressorNode を作成します。
パラメータなし
createGain
GainNode を作成します。
パラメータなし
戻り値: GainNode
createIIRFilter
一般的なIIRフィルターを表すIIRFilterNode を作成します。
パラメータNull可省略可説明
feedforwardsequence<double> IIR フィルターの伝達関数のフィードフォワード(分子)の係数の配列です。 この配列の最大の長さは20です。もし全ての値が0の場合、InvalidStateError 例外を発生しますMUST。配列の長さが0または20より大きい場合は NotSupportedError 例外を発生しますMUST
feedbacksequence<double> IIR フィルターの伝達関数のフィードバック(分母)の係数の配列です。 この配列の最大の長さは20です。もし配列の最初の要素が0の場合、InvalidStateError 例外を発生しますMUST。もし配列の長さが0または20より大きい場合は NotSupportedError 例外を発生しますMUST
戻り値: IIRFilterNode
createOscillator
OscillatorNode を作成します。
パラメータなし
戻り値: OscillatorNode
createPanner
このメソッドは廃止予定で、場合に応じて createSpatialPanner または createStereoPanner で置き換えられます。 PannerNodeを作成します。
パラメータなし
戻り値: PannerNode
createPeriodicWave
任意の倍音構成を表す PeriodicWave を作成します。 real および imag パラメータは Float32Array ([TYPED-ARRAYS] で説明される)型で0より大きい同じ長さでなくてはなりません。 そうでない場合、IndexSizeError 例外を発生します(MUST)。 全ての実装は少なくとも8192までの配列の長さをサポートしなくてはなりません。 これらのパラメータは任意の周期波形を表すフーリエ級数の係数の一部分を表します。 作成されたPeriodicWaveOscillatorNode と共に使用され、 デフォルトでは絶対値の最大が1となる正規化された時間領域の波形を表現します。 別の言い方をするとこれは OscillatorNode が発生する波形の最大ピークが0dBFSであるという事です。 これは都合よく Web Audio API で使用される最大振幅の信号に対応します。 PeriodicWave はデフォルトでは作成時に正規化されるため、real および imag パラメータは相対値を表します。 もし disableNormalization パラメータによってディセーブルされていた場合、正規化は行われず、時間領域の波形はフーリエ係数で与えられた振幅を持ちます。

PeriodicWave オブジェクトはこれらの配列をコピーして管理するため、real および imag パラメータとして使用した配列を createPeriodicWave() 呼び出し後に変更しても PeriodicWave オブジェクトには反映されません。

パラメータNull可省略可説明
realFloat32Array real パラメータはコサイン項(慣習的な言い方でA項)の配列を表します。 オーディオの用語では最初の要素(インデックス0)は周期波形の DC オフセットとなります。 2番目の要素(インデックス1)は基本周波数を表します。3番目の要素は最初の倍音を表し、それ以降も同様に続いてゆきます。 最初の要素は無視され、実装は内部的に0に設定しなくてはなりません。
imagFloat32Array imagパラメータはサイン項(慣習的な言い方でB項)の配列を表します。 最初の要素(インデックス0)はフーリエ級数には存在しないため、0でなくてはなりません(これは無視されます)。 2番目の要素(インデックス1)は基本周波数を表します。3番目の要素は最初の倍音を表し、それ以降も同様に続いてゆきます。
constraintsPeriodicWaveConstraints もし与えられていない場合は、波形は正規化されます。そうでない場合、波形は constraints に与えられた値に従って正規化されます。
戻り値: PeriodicWave
createScriptProcessor
このメソッドは廃止予定で、createAudioWorker で置き換えられます。 JavaScript を使ったオーディオデータ直接処理のための ScriptProcessorNode を作成します。 もし、bufferSize または numberOfInputChannels または numberOfOutputChannels が範囲外の場合、IndexSizeError 例外を発生します(MUST)。 numberOfInputChannelsnumberOfOutputChannels の両方が0となるのは不正となります。この場合、IndexSizeError 例外を発生します(MUST)。
パラメータNull可省略可説明
bufferSizeunsigned long = 0 bufferSizeパラメータはサンプルフレーム数でバッファのサイズを指定します。 もしそれが渡されない場合、または値が0である場合、実装はノードのライフタイムを通して一定な、動作環境に最適な2の累乗のバッファサイズを選択します。 それ以外の場合は明示的にバッファサイズを指定します。それは次の値のどれかでなければなりません: 256、512、1024、2048、4096、8192、16384。 この値は audioprocess イベントが発生する頻度とそれぞれの呼び出しでどれだけのサンプルフレームを処理する必要があるかを制御します。 bufferSize が小さい値ならば レイテンシー は低く(良く)なります。 オーディオが途切れ、グリッジが発生する事を避けるには大きな値が必要となります。 レイテンシーとオーディオ品質の間のバランスを取るためには、プログラマはこのバッファサイズを指定せず、実装に最適なバッファサイズを選択させる事が推奨されます。 もしこのパラメータの値が上に示した許された2の累乗の値でない場合、IndexSizeError 例外を発生します(MUST)。
numberOfInputChannelsunsigned long = 2 このパラメータはこのノードの入力チャンネル数を指定します。32チャンネルまでの値がサポートされなくてはなりません。
numberOfOutputChannelsunsigned long = 2 このパラメータはこのノードの出力チャンネル数を指定します。 32チャンネルまでの値がサポートされなくてはなりません。
createSpatialPanner
SpatialPannerNodeを作成します。
パラメータなし
createStereoPanner
StereoPannerNodeを作成します。
パラメータなし
戻り値: StereoPannerNode
createWaveShaper
非線形な歪み効果を表すWaveShaperNodeを作成します。
パラメータなし
戻り値: WaveShaperNode
decodeAudioData
ArrayBuffer 内にあるオーディオファイルのデータを非同期にデコードします。 ArrayBuffer は、例えば XMLHttpRequest で responseType に "arraybuffer" を指定した場合の response 属性としてロードされます。 オーディオファイルデータは audio または video 要素でサポートされるどのフォーマットでも構いません。 decodeAudioData に渡されるバッファは [mimesniff] で説明される手順で判定されるコンテントタイプを持ちます。

この関数の基本的なインターフェースの手段は戻り値の Promise ではありますが、歴史的な理由からコールバックのパラメータも提供されています。システムは Promise がリゾルブまたはリジェクト、またコールバック関数が呼ばれて完了する前に AudioContext がガベージコレクションされない事を保証しなくてはなりません。

次のステップが実行されなくてはなりません:

  1. promise を新しい Promise とします。
  2. もし、audioData が null または正常な arrayBuffer でない場合:
    1. errorNotSupportedError という名前の DOMException とします。
    2. promiseerror でリジェクトします。
    3. もし、errorCallback があれば、error を持って errorCallback を呼び出します。
    4. このアルゴリズムを終了します。
  3. これ以降 JavaScript からアクセスや変更ができないように audioData の ArrayBuffer を無力化します。
  4. デコード処理が別のスレッドで実行されるようにキューに登録します。
  5. promise を返却します。
  6. デコードスレッドで:
    1. エンコードされている audioData をリニア PCM にデコードを試みます。
    2. もしオーディオフォーマットが認識できない、サポートされていない、あるいはデータが破壊/不正/一貫していないという理由でデコードエラーが発生した場合、メインスレッドのイベントループで:
      1. error"EncodingError" という名前の DOMException とします。
      2. promiseerror を持ってリジェクトします。
      3. もし errorCallback があれば、error を持って errorCallback を呼び出します。
    3. それ以外の場合:
      1. リニア PCM で表現され、もし audioData のサンプルレートが AudioContext のサンプルレートと異なっていた場合はリサンプルされたオーディオデータをデコード結果として受け取ります。
      2. メインスレッドのイベントループで:
        1. buffer を最終的な結果(必要ならサンプルレート変換を行った後)を保持した AudioBuffer とします。
        2. promisebuffer を持ってリゾルブします。
        3. もし successCallback があれば、buffer を持って successCallback を呼び出します。
パラメータNull可省略可説明
audioDataArrayBuffer 圧縮されたオーディオデータを含む ArrayBuffer です
successCallbackDecodeSuccessCallback デコードが完了した時に呼び出されるコールバック関数です。コールバック関数の引数は1つでデコードされた PCM オーディオデータをあらわす AudioBuffer になります。
errorCallbackDecodeErrorCallback オーディオファイルをデコード中にエラーが起こった場合に呼び出されるコールバック関数です。
戻り値: Promise<AudioBuffer>
resume

サスペンド状態にある BaseAudioContextcurrentTime の進行を再開し、フレームバッファの内容を再度送り出します。 Promise はシステムが(必要なら)オーディオハードウェアへのアクセスを再度得て、ディスティネーションへのストリーミングを開始した時、あるいは、もしコンテキストが既に実行状態なら(副作用なく)即時にリゾルブされます。 Promise はもしコンテキストがクローズされている場合 リジェクトされます。もしコンテキストが現在サスペンド状態でない場合 Promise はリゾルブされます。

このメソッドの呼び出しの後、オーディオの最初のブロックがレンダリングされるまで currentTime は変化しない事に注意してください。

パラメータなし
戻り値: Promise<void>
suspend

BaseAudioContextcurrentTime の進行をサスペンドします。現在既にディスティネーションに送り出すために処理されているブロックの処理は許可され、システムはオーディオハードウェアの使用を解放します。これは一般的にアプリケーションが BaseAudioContext をしばらく使用しない事がわかっていて、オーディオハードウェアのパワーダウンを行いたい場合に有用です。 Promise はフレームバッファが空になった(ハードウェアに渡し終えた)時か、もしコンテキストが既にサスペンド状態にあれば(副作用なく)即時にリゾルブされます。 Promise はもしコンテキストがクローズされていればリジェクトされます。

システムがサスペンドされている間、 MediaStream は出力が無視されます---つまりメディアストリームのリアルタイム性によってデータが失われる事になります。 HTMLMediaElement も同様にシステムが resume されるまで出力が無視されます。 AudioWorker と ScriptProcessorNode は単純に onaudioprocess イベントが発行されなくなりますが、resume された時には復帰します。 AnalyserNode では窓関数の目的から、データは継続的に流れているものとみなされます - つまり resume() / suspend() は AnalyserNode のデータストリームに無音状態を作りません。

パラメータなし
戻り値: Promise<void>

2.1.3 コールバック DecodeSuccessCallback パラメータ

decodedData AudioBuffer
デコードされたオーディオデータを保持する AudioBuffer です。

2.1.4 コールバック DecodeErrorCallback パラメータ

error DOMException 型
デコード中に発生したエラーです。

2.1.5 ディクショナリ AudioContextOptions メンバー

playbackCategory AudioContextPlaybackCategory 型, デフォルトは "interactive"
オーディオ出力のレイテンシーと消費電力のバランスに影響する再生のタイプを識別します。

2.1.6 ライフタイム

AudioContext は一度作成された後、これ以上再生する音がなくなるまで、あるいはページを移動するまで再生を続けます。

2.1.7 内部検査やシリアライゼーションの基本機能の欠如

このセクションは参考情報です

Web Audio API は音源のスケジューリングに fire-and-forget アプローチを取っています。つまり、音源ノードは、 AudioContext のライフタイムの間の1つひとつの音に対応して作成され、明示的にグラフからの削除は行いません。これはシリアライゼーション API とは互換性がなく、そのためシリアライズ可能な固定的なノードのセットもありません。

更に、内部検査のための API を持つためにはスクリプトの中身のガベージコレクションの監視が必要になります。

2.2 AudioContext インターフェース

このインターフェースは、その AudioDestinationNode がデバイスへのリアルタイム出力によって直接ユーザーに信号が届くオーディオグラフを表します。多くの場合、1つのドキュメントにつき1つの AudioContext が使用されます。

interface AudioContext : BaseAudioContext {
    MediaElementAudioSourceNode     createMediaElementSource (HTMLMediaElement mediaElement);
    MediaStreamAudioSourceNode      createMediaStreamSource (MediaStream mediaStream);
    MediaStreamAudioDestinationNode createMediaStreamDestination ();
};

2.2.1 メソッド

createMediaElementSource
与えられた HTMLMediaElement の MediaElementAudioSourceNode を作成します。 このメソッドの呼び出しの結果、 HTMLMediaElement からのオーディオの再生は AudioContext の処理グラフにリルートされるようになります。
パラメータNull可省略可説明
mediaElementHTMLMediaElement リルートされるメディアエレメントです。
createMediaStreamDestination
MediaStreamAudioDestinationNode を作成します。
パラメータなし
createMediaStreamSource
パラメータNull可省略可説明
mediaStreamMediaStream 音源となるメディアストリームです。

2.3 OfflineAudioContext インターフェース

OfflineAudioContext はレンダリング/ミックスダウンで使用される特殊な AudioContext であり、(可能性としては)リアルタイムよりも高速に動作します。 それはオーディオハードウェアに出力しない代わりに可能な限り高速に動作して、 Promise にレンダリング結果を AudioBuffer として戻します。

OfflineAudioContext は AudioContext.CreateBuffer と同じ引数で作成されます。 もし引数のどれかが負の値、0、あるいは範囲外であった場合は NotSupportedException 例外を発生しますMUST

unsigned long numberOfChannels
バッファが幾つのチャンネルを持つかを指定します。サポートされるチャンネル数については createBufferを参照してください。
unsigned long length
バッファのサイズをサンプルフレーム数で指定します。
float sampleRate
バッファ内のリニア PCM のオーディオデータのサンプルレートを毎秒のサンプルフレーム数で記述します。 使用できるサンプルレートについては createBuffer を参照してください。
[Constructor(unsigned long numberOfChannels, unsigned long length, float sampleRate)]
interface OfflineAudioContext : BaseAudioContext {
    Promise<AudioBuffer> startRendering ();
    Promise<void>        resume ();
    Promise<void>        suspend (double suspendTime);
                    attribute EventHandler oncomplete;
};

2.3.1 属性

oncomplete EventHandler 型

OfflineAudioCompletionEvent 型のイベントハンドラーです。

2.3.2 メソッド

resume

サスペンド状態のオーディオコンテキストの進行を再開します。 OfflineAudioContext はオーディオハードウェアを必要としないため、 Promise は即時にリゾルブされます。もしコンテキストが現在サスペンド状態でない、あるいはレンダリングがまだ開始されていない場合、 Promise は InvalidStateError でリジェクトされます。

ライブ情報を扱う AudioContext とは違い、サスペンド状態の間コンテキストのオーディオストリームが進まないため、 currentTime の値は常にオーディオグラフによって次にレンダリングされるブロックの先頭時間を指します。

パラメータなし
戻り値: Promise<void>
startRendering

与えられた現在の接続とスケジュールされたオートメーションでオーディオのレンダリングを開始します。システムは Promise がリゾルブされコールバック関数が呼び出されるまで、あるいは suspend 関数が呼び出されるまで OfflineAudioContext がガベージコレクションされない事を保証します。

オーディオデータのレンダリング結果を得る基本的なメソッドは Promise の戻り値ですが、歴史的な理由によりこのインスタンスは complete という名前のイベントも発行します。

次のステップが実行されなくてはなりません:

  1. もし、 startRendering が既に呼ばれている場合、 Promise は InvalidStateError でリジェクトされます。
  2. promise を新しい Promise とします。
  3. 非同期に次のステップを実行します:
    1. このインスタンスのコンストラクタが呼ばれた時の numberOfChannels をチャンネル数、 length を長さ、 sampleRate をサンプルレートとした新しい AudioBufferbuffer とします。
    2. 現在の接続とスケジューリングで length のサンプルフレーム数のオーディオを buffer にレンダリング開始します。
    3. 必要があればレンダリングを行うブロック毎にチェックとサスペンドを行います。
    4. もしサスペンド状態のコンテキストが再開した場合、バッファへのレンダリングを再開します。
    5. レンダリングが完了した時、
      1. promisebuffer でリゾルブします。
      2. OfflineAudioCompletionEvent のインスタンスで complete という名前のイベントを発行するためにキューに入れ、その renderedBuffer プロパティに buffer をセットします。
  4. promise を戻します。
パラメータなし
戻り値: Promise<AudioBuffer>
suspend

オーディオコンテキストの時間の進行を指定の時刻にサスペンドする事をスケジューリングし、 Promise を返します。 これは一般的に OfflineAudioContext 上でオーディオグラフを同期的に操作するために役立ちます。

サスペンドの最大の精度はレンダリング処理の分割のサイズであり、指定されたサスペンド時刻は最も近い分割の境界に丸められる事に注意してください。このため、同じ分割フレーム内に複数のサスペンドをスケジューリングする事はできません。また、スケジューリングはコンテキストが高精度のサスペンドを保証しない実行を行っている間に行わなくてはなりません。

パラメータNull可省略可説明
suspendTimedouble

レンダリングのサスペンドをスケジュールする時刻。これはレンダリングの分割サイズの境界に丸められます。 もし丸められた結果のフレーム数が、

  1. 負の値
  2. 現在の時刻より小さいまたは同じ
  3. レンダリングのトータルの長さより大きいか同じ
  4. 他のサスペンドのスケジューリングと同じ時刻
の場合は、 Promise は InvalidStateError でリジェクトされます。
戻り値: Promise<void>
[Constructor]
interface AudioContext : BaseAudioContext {
};

2.3.3 OfflineAudioCompletionEvent インターフェース

これは OfflineAudioContext に対して歴史的な理由により、ディスパッチされる Event です。

interface OfflineAudioCompletionEvent : Event {
    readonly        attribute AudioBuffer renderedBuffer;
};
2.3.3.1 属性
renderedBuffer AudioBuffer 型, readonly

レンダリングされたオーディオデータを保持する AudioBuffer です。

2.4 AudioNode インターフェース

AudioNode は AudioContext の構成ブロックです。 このインターフェースはオーディオのソース、出力先、中間の処理モジュールを表しています。これらのモジュールは互いに接続されて、 音をオーディオハードウェアに出力するための処理グラフを形成します。 それぞれのノードは入力出力を持つ事ができます。 ソースノードは入力を持たず、単一の出力を持ちます。 AudioDestinationNode は 単一の入力を持ち、出力を持たず、オーディオハードウェアへの最終的な出力地点を表しています。 フィルターのような殆どの処理ノードは1つの入力と1つの出力を持ちます。 それぞれのタイプの AudioNode はどのようにオーディオを処理したり合成したりするかの詳細が異なっています。 しかし、一般的に AudioNode は(持っていれば)その入力を処理し、(持っていれば)その出力にオーディオ信号を送り出します。

それぞれの出力は1つ以上のチャンネルを持っています。正確なチャンネル数はそれぞれの AudioNode の詳細に依存します。

出力は1つ以上の AudioNode 入力に接続でき、つまりファンアウトがサポートされています。 入力は初期化時には接続されていません。しかし、1つ以上の AudioNode 出力から接続する事ができ、即ち、ファンインがサポートされています。 AudioNode の出力を AudioNode の入力に接続するため connect() メソッドが呼ばれた時、それをその入力への接続と呼びます。

AudioNode入力はその時々で特定のチャンネル数を持ちます。この数はその入力への接続によって変化します。 もし入力が接続を持っていない場合、チャンネル数は1で無音となります。

AudioNode入力について、その入力への接続のミックス(通常はアップミックス)を行います。 この詳細に関して参考情報としては 3. ミキサーゲイン構成 、基準としての詳細要件については 5. チャンネルのアップミックスとダウンミックス セクションを参照してください。

AudioNode の入力および内部の処理は、そのノードが出力を接続されているか、またそれらの出力が AudioContextAudioDestinationNode に到達しているかに関わらず、 AudioContext の時刻を踏まえて継続的に行われます。

パフォーマンス的な理由から実際の実装ではそれぞれの AudioNode は決まったブロックサイズのサンプルフレームをブロック単位に処理する事が必要になると思われます。 実装による振る舞いを統一するため、この値を明示的に定めます。ブロックサイズはサンプルレート44.1kHzにおいて約3msとなる128サンプルフレームとします。

AudioNode は、DOM [DOM] で記述される EventTarget です。 これは他の EventTarget がイベントを受け取るのと同じ方法でイベントを AudioNode にディスパッチする事が可能である事を意味します。

enum ChannelCountMode {
    "max",
    "clamped-max",
    "explicit"
};
列挙値の説明
max computedNumberOfChannels は全ての接続のチャンネル数の最大値として計算されます。 このモードでは channelCount は無視されます。
clamped-max "max" と同様ですが、 channelCount を上限とします。
explicit computedNumberOfChannels の値は channelCount によって指定された値そのものになります。
enum ChannelInterpretation {
    "speakers",
    "discrete"
};
列挙値の説明
speakers モノ/ステレオ/クワッド/5.1のためのアップ・ダウンミックス式を使用します。 チャンネル数がこれらのスピーカー基本レイアウトに一致しない場合、 "discrete" に戻します。
discrete アップミックスの場合、チャンネルを使い切るまで順に埋めて行き、余っているチャンネルには0を出力します。 ダウンミックスでは、可能な限りチャンネルを順に埋め、余ったチャンネルは捨てられます。
interface AudioNode : EventTarget {
    AudioNode connect (AudioNode destination, optional unsigned long output = 0
              , optional unsigned long input = 0
              );
    void      connect (AudioParam destination, optional unsigned long output = 0
              );
    void      disconnect ();
    void      disconnect (unsigned long output);
    void      disconnect (AudioNode destination);
    void      disconnect (AudioNode destination, unsigned long output);
    void      disconnect (AudioNode destination, unsigned long output, unsigned long input);
    void      disconnect (AudioParam destination);
    void      disconnect (AudioParam destination, unsigned long output);
    readonly        attribute AudioContext          context;
    readonly        attribute unsigned long         numberOfInputs;
    readonly        attribute unsigned long         numberOfOutputs;
                    attribute unsigned long         channelCount;
                    attribute ChannelCountMode      channelCountMode;
                    attribute ChannelInterpretation channelInterpretation;
};

2.4.1 属性

channelCount unsigned long

ノードへの入力の接続におけるアップミックスおよびダウンミックスで使用されるチャンネル数です。 値が別途定められている特定のノードを除いて、デフォルトは2です。 この属性は入力を持たないノードでは意味を持ちません。 もしこの値が0、あるいは実装のチャンネル数の最大値より大きい値にセットされた場合、実装は NotSupportedError 例外を発生します(MUST)。

この属性の詳細ついては5. チャンネルのアップミックスとダウンミックスセクションを参照してください。

channelCountMode ChannelCountMode

このノードの入力のアップミックスおよびダウンミックス時のチャンネル数の数え方を決定します。 この属性は入力を持たないノードでは意味を持ちません。

この属性の詳細ついては5. チャンネルのアップミックスとダウンミックスセクションを参照してください。

channelInterpretation ChannelInterpretation

このノードの入力への接続のアップミックスおよびダウンミックス時に各チャンネルをどのように扱うかを決定します。 この属性は入力を持たないノードでは意味を持ちません。

この属性の詳細ついては5. チャンネルのアップミックスとダウンミックスセクションを参照してください。

context AudioContext型, readonly
このAudioNodeを持つAudioContextです。
numberOfInputs unsigned long型, readonly
この AudioNode の入力の数です。 ソースノードではこれは0になります。この属性は多くの AudioNode のタイプで固定の値になりますが、 ChannelMergerNodeAudioWorkerNode のような幾つかの AudioNode では入力の数は可変です。
numberOfOutputs unsigned long型, readonly
この AudioNode から出る出力の数です。この属性は幾つかの AudioNode では固定の値ですが、 ChannelSplitterNodeAudioWorkerNode などでは可変になります。

2.4.2 メソッド

connect

あるノードの特定の出力から別のノードの特定の入力への接続は1つだけ存在できます。同じ端子間の複数回の接続は無視されます。例えば:

例 4
nodeA.connect(nodeB);
nodeA.connect(nodeB);

は次のものと同じ効果になります。

例 5
nodeA.connect(nodeB);
Null可省略可説明
destinationAudioNode destinationパラメータは接続先のAudioNodeです。もしdestinationが他のAudioContextによって作成されたAudioNodeの場合、InvalidAccessError 例外を発生します(MUST)。 つまり AudioNodes は複数の AudioContext 間で共有する事はできません。
outputunsigned long = 0 output パラメータは AudioNode のどの出力を接続するかを指定するインデックスです。 もしこのパラメータが範囲外の場合、 IndexSizeError 例外を発生します (MUST)。 connect() を複数回呼び出して AudioNode の出力から複数の入力に接続する事は可能です。つまり、"ファンアウト"がサポートされています。
inputunsigned long = 0 input パラメータは接続先の AudioNode のどの入力に接続するかを指定するインデックスです。もしこのパラメータが範囲外の場合、 IndexSizeError 例外を発生します (MUST)。 ある AudioNode から他の AudioNode循環を作るような接続を行う事も可能です: つまりある AudioNode から、最初の AudioNode に接続を行っている別の AudioNode に対して接続を行う事ができます。 これは循環の中に少なくとも1つの DelayNode がある場合にのみ可能で、そうでなければ NotSupportedError 例外を発生します (MUST)。
戻り値: AudioNode
connect
AudioNodeAudioParam に接続し、パラメータの値をオーディオレートの信号で制御します。

connect() を複数回呼び出す事で AudioNode の出力を複数の AudioParam に接続する事が可能です。即ち、"ファンアウト"がサポートされています。

connect() を複数回呼び出す事で、複数の AudioNode を1つの AudioParam に接続する事が可能です。即ち、"ファンイン"がサポートされています。

AudioParam はそれに接続されている AudioNode の出力からレンダリングされたオーディオデータを取り出し、それがモノでなければ、ダウンミックスによってモノに変換します。 そして接続されている各出力をミックスし、更に最終的にパラメータが持っているタイムラインの変化スケジュールを含む固有値( AudioParam に何も接続されていない状態での)とミックスします。

特定のノードの出力と特定の AudioParam の間の接続は1つのみ存在できます。 同じ終端点を持つ複数の接続は無視されます。例えば:

      nodeA.connect(param);
      nodeA.connect(param);
    
は次と同じ効果を持ちます
      nodeA.connect(param);

パラメータNull可省略可説明
destinationAudioParam destination パラメータは接続先の AudioParamです。 このメソッドは 接続先AudioParam オブジェクトを返しません。
outputunsigned long = 0 output パラメータは AudioNode のどの出力から接続するかを指定するインデックスです。 もし parameter が範囲外の場合、IndexSizeError 例外を発生します (MUST)。
戻り値: void
disconnect

AudioNode から出る全ての接続を切断します。

パラメータなし
戻り値: void
disconnect

AudioNode の1つの出力から他のAudioNodeまたはAudioParamオブジェクトへの接続を全て切断します。

パラメータNull可省略可説明
outputunsigned long このパラメータは接続を切る AudioNode の出力のインデックスです。 これは与えられた出力から出る全ての接続を切断します。 もしこのパラメータが範囲外の場合、IndexSizeError 例外を発生します (MUST)。
戻り値: void
disconnect

AudioNode の全ての出力から特定の接続先となる AudioNode に繋がる接続を切断します。

パラメータNull可省略可説明
destinationAudioNode destination パラメータは切断する AudioNode です。これは与えられた destination に対する全ての接続を切断します。 もしdestination に対する接続がない場合、InvalidAccessError を発生します (MUST)。
戻り値: void
disconnect

AudioNode の特定の出力から特定の AudioNode への接続を切断します。

パラメータNull可省略可説明
destinationAudioNode destination パラメータは切断する AudioNode です。もし、与えられた出力から destination への接続が存在しない場合、InvalidAccessError 例外を発生します (MUST )。
outputunsigned long output パラメータは接続を切る AudioNode の出力を表すインデックスです。もしこのパラメータが範囲外の場合は IndexSizeError 例外を発生します (MUST)。
戻り値: void
disconnect

AudioNode の特定の出力から 接続先 AudioNode の特定の入力への接続を切断します。

パラメータNull可省略可説明
destinationAudioNode destination パラメータは切断する AudioNode です。もし与えられた出力から destination の与えられた入力への接続が存在しない場合、InvalidAccessError 例外を発生します (MUST)。
outputunsigned long output パラメータは切断する AudioNode の出力のインデックスです。もしこのパラメータが範囲外の場合、IndexSizeError 例外を発生します (MUST)。
inputunsigned long input パラメータは切断する接続先 AudioNode の入力のインデックスです。もしこのパラメータが範囲外の場合、IndexSizeError 例外を発生します (MUST)。
戻り値: void
disconnect

特定の接続先 AudioParam に繋がる AudioNode の全ての出力を切断します。 この操作によって、この AudioNode からパラメータ値の計算への寄与は0となります。パラメータの固有値はこの操作に影響されません。

パラメータNull可省略可説明
destinationAudioParam destination パラメータは切断する AudioParam です。もし destination への接続が存在しない場合、InvalidAccessError 例外を発生します (MUST)。
戻り値: void
disconnect

AudioNodeの特定の出力から特定のAudioParamへの接続を切断します。 この操作によって、この AudioNode からパラメータ値の計算への寄与は0となります。パラメータの固有値はこの操作に影響されません。

パラメータNull可省略可説明
destinationAudioParam destination パラメータは切断される AudioParam です。もし destination への接続が存在しない場合、InvalidAccessError 例外を発生します (MUST)。
outputunsigned long output パラメータは切断される AudioNode の出力のインデックスです。もし、parameterが範囲外の場合、IndexSizeError 例外を発生します (MUST)。
戻り値: void

2.4.3 ライフタイム

このセクションは参考情報です。

実装では、必要のないリソース利用や未使用または終了しているノードが際限なくメモリを使うのを避ける為の何らかの方法を選ぶでしょう。 以降の説明は、一般的に期待されるノードのライフタイムの管理の仕方を案内するものです。

何かしら参照される限り、AudioNode は存在し続けるでしょう。参照には何種類かのタイプがあります。:

  1. 通常のJavaScript参照。通常のガベージコレクションのルールに従います。
  2. AudioBufferSourceNode と OscillatorNode再生中の参照。 再生している間これらのノードは、自分自身への再生中参照を維持します。
  3. 接続参照。別の AudioNode から接続されている場合に発生します。
  4. 余韻時間参照。AudioNode は何かしらの内部プロセスで未解放のステートになっている場合は、その間、自分自身を維持します。 例えば、ConvolverNode は無音の入力を受けた後でも再生し続ける余韻を持ちます。 (大きなコンサートホールで柏手を打つと、ホール中に響きわたる音が聞こえるのをイメージして下さい)。 いくつかの AudioNode は、この特性を持ちます。 各ノードの詳細を見てください。

環状に接続され、且つ直接または間接的に AudioContextAudioDestinationNode に接続されるすべての AudioNode はその AudioContext が存在している間は存在したままになります。

AudioNode の継続的な動作はそのノードへの暗黙的に参照が存在しているという事を意味し、たとえオーディオグラフから切断されていても、ノードは入力を処理し続け、内部状態を更新し続けます。 この処理はCPUと電力を消費し続けるため、開発者は注意深くリソースの使用について考慮しなくてはなりません。 特に、可能な時には明示的に切断されたノードを停止状態にする事でリソースの消費を最小化するのは良い考えです。

参照を全く持たなくなった時、AudioNode は削除されます。 しかしそれが削除される前に、他の AudioNode から自分への接続を切断します。 同様にこのノードから他のノードに対するすべての接続参照(3)を解放します。

上記の参照の種類に関わらず、ノードの AudioContext が削除された時には、もちろん AudioNode は削除されます。

2.5 AudioDestinationNode インターフェース

これはユーザーが聴く事になる最終的な音の出力地点を表す AudioNode です。 それは多くの場合、スピーカーが接続されているオーディオ出力デバイスと考えられます。 聴こえるべきすべてのレンダリングされた音は AudioContext のルーティンググラフの"終端点"であるこのノードに導かれます。 AudioDestinationNode は1つの AudioContext に付き、AudioContextdestination 属性を介して 1つだけ存在します。

      numberOfInputs  : 1
      numberOfOutputs : 0

      channelCount = 2;
      channelCountMode = "explicit";
      channelInterpretation = "speakers";
interface AudioDestinationNode : AudioNode {
    readonly        attribute unsigned long maxChannelCount;
};

2.5.1 属性

maxChannelCount unsigned long 型, readonly

channelCount 属性で設定できるチャンネル数の最大値です。 AudioDestinationNode (通常は)オーディオハードウェアの終端点を表し、マルチチャンネル対応のハードウェアならば2チャンネル以上の音を出力する事ができます。 maxChannelCount はハードウェアがサポートできるチャンネル数の最大値です。 もしこの値が 0 ならば channelCount は変更できない事を表します。 これは OfflineAudioContextAudioDestinationNode やハードウェアの基本実装がステレオ出力のみに対応している場合です。

通常の AudioContext の destination では、channelCount のデフォルト値は 2 であり、0 以外で maxChannelCount と同じか小さい値に設定する事ができます。 値が有効な範囲外の場合、IndexSizeError 例外を発生します (MUST)。 具体的な例をあげれば、もしオーディオハードウェアが8チャンネル出力をサポートしている場合、channelCount を 8 に設定でき、8 チャンネルの出力が得られます。

OfflineAudioContextAudioDestinationNode については、 channelCount は OfflineAudioContext が作成された時点で決定され、この値は変更できません。

2.6 AudioParam インターフェース

AudioParamAudioNode の例えば音量のような個別の機能をコントロールします。 パラメータは value 属性を使って特定の値に即時にセットする事ができます。 あるいは(AudioContextcurrentTime 属性の時間軸で) 非常に高い時間精度で値の変化のスケジュールを組む事ができ、エンベロープ、音量のフェード、LFO、フィルタスイープ、グレイン窓、などに応用する事ができます。 このような方法で任意のタイムラインベースのオートメーション曲線をすべての AudioParam に対して設定する事が可能です。 また更に、 AudioNode からの出力の音声信号を AudioParam に接続する事ができ、個別に持っているパラメータの固有値に加算する事ができます。

幾つかの合成や処理の AudioNode は、オーディオサンプル単位で反映されなくてはならない AudioParams 型の属性を持っています。 その他の AudioParams はサンプル単位の精度は重要ではなく、その値の変化はより粗く取り込まれます。 各 AudioParama-rate パラメータつまりサンプル単位で反映されるか、それ以外の k-rate パラメータかが指定されます。

実装はそれぞれの AudioNode について、128 サンプルフレーム毎のブロック単位の処理を行わなくてはなりません。

それぞれの 128 サンプルフレームのブロックに対して、 k-rate パラメータは最初のサンプルのタイミングで取り込まれ、その値は ブロック全体に対して使用されなくてはなりません。 a-rate パラメータはブロック内のサンプルフレーム毎に取り込まれなくてはなりません。

AudioParam は時間軸に沿ったイベントリストを保持し、その初期値は空になっています。 この時間は AudioContextcurrentTime 属性による時間軸を使用します。 イベントは時刻に対して値を割り付けるものです。 以降のメソッドはメソッド毎に固有のタイプのイベントをリストに新しく加える事でイベントリストを変更します。 それぞれのイベントは対応する時刻を持っており、リスト上で常に時刻順に保持されます。 これらのメソッドはオートメーションメソッドと呼ばれます:

これらのメソッドが呼ばれる時、次の規則が適用されます:

interface AudioParam {
                    attribute float value;
    readonly        attribute float defaultValue;
    AudioParam setValueAtTime (float value, double startTime);
    AudioParam linearRampToValueAtTime (float value, double endTime);
    AudioParam exponentialRampToValueAtTime (float value, double endTime);
    AudioParam setTargetAtTime (float target, double startTime, float timeConstant);
    AudioParam setValueCurveAtTime (Float32Array values, double startTime, double duration);
    AudioParam cancelScheduledValues (double startTime);
};

2.6.1 属性

defaultValue float 型, readonly
value 属性の初期値です。
value float

浮動小数のパラメータの値です。 この属性の初期値は defaultValue です。 もし value がオートメーションイベントが設定されている期間中に設定された場合、それは無視され、例外は発生しません。

この属性を設定した場合の効果は setValueAtTime() を現在の AudioContextcurrentTime と値で呼び出すのと同じです。 それ以降のこの属性の値へのアクセスは同じ値を返します。

2.6.2 メソッド

cancelScheduledValues

startTime と同じかそれ以降にスケジュールされているすべてのパラメータ変化をキャンセルします。 (与えられた時間よりも小さな startTime を指定した) アクティブな setTargetAtTime オートメーション もまたキャンセルされます。

パラメータNull可省略可説明
startTimedouble 開始時間が同じかそれ以降に設定されていたパラメータ変化のスケジュールをキャンセルする時刻です。 これは AudioContextcurrentTime と同じ時間軸の時刻を使用します。 もし startTime が負の値あるいは有限数でない場合 TypeError 例外を発生します (MUST)。
戻り値: AudioParam
exponentialRampToValueAtTime

前にスケジュールされているバラメータ値から指定された値まで、指数的に連続して値を変化させる事をスケジュールします。 フィルタの周波数や再生スピードなどのパラメータは人間の聴覚特性のため、指数的変化が適しています。

時間範囲 \(T_0 \leq t < T_1\) (ここで \(T_0\) は前のイベントの時刻で \(T_1\) はこのメソッドの endTime) パラメータです) に対して次のように計算されます:

              $$
                v(t) = V_0 \left(\frac{V_1}{V_0}\right)^\frac{t - T_0}{T_1 - T_0}
              $$

ここで \(V_0\) は時刻 \(T_0\) での値、 \(V_1\) はこのメソッドの value パラメータです。 もし \(V_0\) または \(V_1\) が真に正の値(訳注:0を含まない)でない場合はエラーとなります。

これはまた、0 に向かう指数カーブが不可能である事も示しています。 setTargetAtTime で適当な時間定数を選択する事で良い近似を得る事ができます。

もしこの ExponentialRampToValue イベント以降のイベントがない場合 \(t \geq T_1\), \(v(t) = V_1\) となります。

パラメータNull可省略可説明
valuefloat パラメータが指数変化により指定された時刻に到達する値です。 この値が 0 より小さいまたは 0、または前のイベントで指定された値が 0 より小さいまたは 0 の場合、NotSupportedError 例外を発生します (MUST)。
endTimedouble AudioContextcurrentTime 属性と同じ時間軸で、指数変化が終了する時刻です。 もし endTime が負の値または有限数でない場合 TypeError 例外を発生します (MUST)。
戻り値: AudioParam
linearRampToValueAtTime

前にスケジュールされているパラメータ値から指定された値まで、直線的に連続して値を変化させる事をスケジュールします。

時間範囲 \(T_0 \leq t < T_1\) (ここで \(T_0\) は前のイベントの時刻、 \(T_1\) はこのメソッドで指定された endTime です) の間の値は次のように計算されます:

              $$
                v(t) = V_0 + (V_1 - V_0) \frac{t - T_0}{T_1 - T_0}
              $$

ここで \(V_0\) は時刻 \(T_0\) での値、 \(V_1\) はこのメソッドで指定された value です。

もしこの LinearRampToValue イベント以降にイベントがない場合、 \(t \geq T_1\), \(v(t) = V_1\) となります。

パラメータNull可省略可説明
valuefloat 与えられた時刻にパラメータが直線変化で到達する値です。
endTimedouble AudioContextcurrentTime 属性と同じ時間軸で、オートメーション終了する時刻です。 もし endTime が負の値または有限数でない場合 TypeError 例外を発生します (MUST)。
戻り値: AudioParam
setTargetAtTime

指定の時間から、指定の時定数によって指数的に目標の値に漸近を開始します。 様々な使い方がありますが、これはADSRエンベロープの"ディケイ"および"リリース"を実装する際に役立ちます。 値は指定の時間に即、目標値になるのではなく徐々に目標値に向かって変化する事に注意してください。

時間範囲 : \(T_0 \leq t < T_1\) 、ここで \(T_0\) は startTime パラメータの時刻、 \(T_1\) はこのイベントに続くイベントの時刻 (あるいは次のイベントがない場合は \(\infty\) ) として:

              $$
                v(t) = V_1 + (V_0 - V_1)\, e^{-\left(\frac{t - T_0}{\tau}\right)}
              $$

ここで、 \(V_0\) は初期値 (\(T_0\) での .value属性の値)、\(V_1\) は target パラメータの値、そして \(\tau\) は timeConstant パラメータです。

パラメータNull可省略可説明
targetfloat パラメータが指定の時刻から変化を開始する目標値です。
startTimedouble AudioContextcurrentTime 属性と同じ時間軸で指数的漸近を開始する時刻です。 もし start が負の値または有限数でない場合は TypeError 例外を発生します (MUST)。
timeConstantfloat 目標値に漸近する一次フィルター (指数) の時定数の値です。 この値が大きいと変化はゆっくりになります。値は真に正の値(訳注: 0 を含まない)でなくてはなりません。そうでない場合 TypeError 例外を発生します (MUST)。

より正確には、timeConstant は一次の線形時不変系でステップ応答(0 から 1 への変化) に対して \(1 - 1/e\) (約 63.2%) となる時間を指します。

戻り値: AudioParam
setValueAtTime

指定の時刻になるとパラメータ値を変更するようにスケジュールします。

もしこの SetValue イベントの後にもうイベントがない場合、 \(t \geq T_0\) に対して \(v(t) = V\) ここで \(T_0\) は startTime 、そして \(V\) は value パラメータの値です。 別の言い方をすれば、値は定数のまま保持されます。

もしこの SetValue イベントの次のイベント ( 時刻は \(T_1\) ) が LinearRampToValue または ExponentialRampToValue でない場合、 \(T_0 \leq t < T_1\) に対して:

              $$
                v(t) = V
              $$

別の言い方をすれば、値に "ステップ" を作ってこの期間定数のまま保持されます。

もしこの SetValue イベントに続く次のイベントが LinearRampToValue または ExponentialRampToValueの場合、 linearRampToValueAtTime または exponentialRampToValueAtTime をそれぞれ参照してください。

パラメータNull可省略可説明
valuefloat 指定の時刻にパラメータが変化する値です。
startTimedouble AudioContextcurrentTime 属性と同じ時間軸で与えられた値に変化する時刻です。 もし startTime が負の値または有限数でない場合は TypeError 例外を発生します (MUST)。
戻り値: AudioParam
setValueCurveAtTime

指定の時刻と期間に対して、任意の値の配列を設定します。 値の個数は必要とされる期間に合うようにスケーリングされます。

\(T_0\) を startTime 、 \(T_D\) を duration 、 \(V\) を values 配列、 \(N\) を values 配列の長さとします。  期間 \(T_0 \le t < T_0 + T_D\) の間次のようになります

              $$
                \begin{align*} k &= \left\lfloor \frac{N - 1}{T_D}(t-T_0) \right\rfloor \\
                \end{align*}
              $$

そして、 \(v(t)\) は \(V[k]\) と \(V[k+1]\) の間で直線補間されます。

曲線の期間が終了した後、 (\(t \ge T_0 + T_D\)) に対して値は(もしあれば)別のオートメーションイベントまで、最後の曲線の値を保持します。

パラメータNull可省略可説明
valuesFloat32Array パラメータ値の曲線を表す Float32Array です。 これらの値は与えられた時刻から始まる期間に割り当てられます。 このメソッドが呼び出された時、オートメーションのために曲線の内部的なコピーが作成されます。 そのため、それ以降に渡した配列の中身を変更しても AudioParam に対する効果はありません。
startTimedouble AudioContextcurrentTime 属性と同じ時間軸の曲線の適用を開始する時刻です。 もし startTime が負の値または有限数でない場合 TypeError 例外を発生します (MUST)。
durationdouble ( time (訳注:startTime)以降の) 秒で表される期間の長さであり、 この期間、値は values パラメータに従って計算されます。
戻り値: AudioParam

2.6.3 値の計算

computedValue はオーディオDSPを制御する最終的な値であり、オーディオレンダリングスレッドがそれぞれのレンダリング時刻に計算します。 内部的には次のように計算されなくてはなりません:

  1. value 属性に直接設定されるか、あらかじめ、またはこの時刻に値の変化スケジュールが設定(オートメーションイベント)されていればこれらのイベントから固有の値が計算されます。 もし、オートメーションイベントがスケジュールされた後に value 属性が設定された場合、これらのイベントは削除されます。 value 属性を読みだした場合は常に現在の固有の値を返します。 もしオートメーションイベントが与えられた期間から削除された場合、 固有 の値は value 属性が直接設定されるか、その期間を対象にオートメーションイベントが追加されるまで、直前の値を保持したままになります。
  2. AudioParamAudioNode の出力が接続されている場合、その出力がモノでなければダウンミックスしてモノに変換し、他の同様に接続されている出力とミックスします。 もし AudioNode が接続されていない場合はこの値は0となり、 computedValue には影響を及ぼしません。
  3. computedValue固有の値と(2)で計算された値の和となります。

2.6.4 AudioParam オートメーションの例

AudioParam automation
図. 4 パラメータオートメーションの例
例 6

var curveLength = 44100;
var curve = new Float32Array(curveLength);
for (var i = 0; i < curveLength; ++i)
    curve[i] = Math.sin(Math.PI * i / curveLength);

var t0 = 0;
var t1 = 0.1;
var t2 = 0.2;
var t3 = 0.3;
var t4 = 0.325;
var t5 = 0.5;
var t6 = 0.6;
var t7 = 0.7;
var t8 = 1.0;
var timeConstant = 0.1;

param.setValueAtTime(0.2, t0);
param.setValueAtTime(0.3, t1);
param.setValueAtTime(0.4, t2);
param.linearRampToValueAtTime(1, t3);
param.linearRampToValueAtTime(0.8, t4);
param.setTargetAtTime(.5, t4, timeConstant);
// Compute where the setTargetAtTime will be at time t5 so we can make
// the following exponential start at the right point so there's no
// jump discontinuity.  From the spec, we have
//   v(t) = 0.5 + (0.8 - 0.5)*exp(-(t-t4)/timeConstant)
// Thus v(t5) = 0.5 + (0.8 - 0.5)*exp(-(t5-t4)/timeConstant)
param.setValueAtTime(0.5 + (0.8 - 0.5)*Math.exp(-(t5 - t4)/timeConstant), t5);
param.exponentialRampToValueAtTime(0.75, t6);
param.exponentialRampToValueAtTime(0.05, t7);
param.setValueCurveAtTime(curve, t7, t8 - t7);

2.7 GainNode インターフェース

オーディオ信号のゲインを変える事はオーディオアプリケーションでは基本的な処理です。 GainNodeミキサーの構成ブロックの1つとなります。 このインターフェースは1つの信号入力と1つの信号出力を持つ AudioNode です:

  numberOfInputs  : 1
  numberOfOutputs : 1

  channelCountMode = "max";
  channelInterpretation = "speakers";

GainNode の入力データの各チャンネルの各サンプルは gain AudioParamcomputedValue が乗じられます (MUST)。

interface GainNode : AudioNode {
    readonly        attribute AudioParam gain;
};

2.7.1 属性

gain AudioParam 型, readonly
適用されるゲインの量を表します。デフォルトの value は1です(ゲイン変更なし)。名目上の minValue は 0 ですが、位相反転のために負の値に設定する事もできます。 名目上の maxValue は1ですが (例外が発生する事なく) より大きな値を設定する事もできます。このパラメータは a-rate です。

2.8 DelayNode インターフェース

ディレイ機能はオーディオアプリケーションの基本的な構成要素です。このインターフェースは単一の入力と単一の出力を持つ AudioNode です。

    numberOfInputs  : 1
    numberOfOutputs : 1

    channelCountMode = "max";
    channelInterpretation = "speakers";

出力のチャンネル数は常に入力のチャンネル数と同じになります。

これは入力されるオーディオ信号を一定の量だけ遅延させます。 具体的には各時刻 t において、入力信号 input(t) に対して、遅延時間 delayTime(t)、出力信号 output(t) とすると 出力は output(t) = input(t - delayTime(t)) となります。 デフォルトの delayTime は0秒(遅延なし)です。

DelayNodeの入力のチャンネル数を変えた時 (つまり出力チャンネル数もまた変化します)、ノードからまだ出力されておらず内部状態にあるサンプルが残っているかも知れません。 全ての内部のディレイ機能のミキシングは単一のチャンネルレイアウトで動作しているため、 もしこのような変更前の異なるチャンネル数のサンプルを受け取った場合、 それらは新しく受け取られた入力と結合される前にアップミックスまたはダウンミックスされなくてはなりません。

interface DelayNode : AudioNode {
    readonly        attribute AudioParam delayTime;
};

2.8.1 属性

delayTime AudioParam 型, readonly

適用する遅延(単位は秒)の量を表すAudioParamオブジェクトです。 デフォルトは 0 (遅延なし) です。 最小の値は 0 で最大の値は AudioContextcreateDelay メソッドの引数、 maxDelayTime で決定されます。

もし DelayNode循環の一部になっている場合、delayTime 属性の最小値は 128 フレーム (1ブロック)にクランプされます。

このパラメータは a-rate です。

2.9 AudioBuffer インターフェース

このインターフェースはメモリ上に保持されるオーディオのリソース(ワンショットの音やその他の短いオーディオクリップ)を表します。 そのフォーマットは-1 ~ +1の名目上の範囲を持つ非インターリーブのIEEE 32ビット・リニアPCMです。 1つ以上のチャンネルを持つ事ができます。 典型的には、そのPCMデータは適度に(通常1分以内程度に)短いと見込まれます。 音楽の1曲分のような長時間の音に関しては audio 要素と MediaElementAudioSourceNode によるストリーミングを使うべきです。

AudioBuffer は1つ以上の AudioContext で使用される場合があり、また OfflineAudioContextAudioContext で共有する事もできます。

interface AudioBuffer {
    readonly        attribute float  sampleRate;
    readonly        attribute long   length;
    readonly        attribute double duration;
    readonly        attribute long   numberOfChannels;
    Float32Array getChannelData (unsigned long channel);
    void         copyFromChannel (Float32Array destination, unsigned long channelNumber, optional unsigned long startInChannel = 0
              );
    void         copyToChannel (Float32Array source, unsigned long channelNumber, optional unsigned long startInChannel = 0
              );
};

2.9.1 属性 

duration double 型, readonly
PCM オーディオデータの秒で表現された長さです。
length long 型, readonly
PCM オーディオデータのサンプルフレーム数で表現された長さです。
numberOfChannels long 型, readonly
オーディオのチャンネル数です。
sampleRate float 型, readonly
PCM オーディオデータの秒あたりのサンプル数で表現されたサンプルレートです。

2.9.2 メソッド

copyFromChannel
copyFromChannel メソッドは AudioBuffer の指定されたチャンネルから destination で示される配列にサンプルをコピーします。
パラメータNull可省略可説明
destinationFloat32Array チャンネルデータをコピーする先の配列です。
channelNumberunsigned long データをコピーするチャンネルのインデックスです。 もし channelNumberAudioBuffer のチャンネル数よりも大きいまたは等しい場合、IndexSizeError 例外を発生します (MUST)。
startInChannelunsigned long = 0 オプションのオフセットで、コピーをどこから行うかを指定します。もし startInChannelAudioBufferlength より大きい場合、IndexSizeError 例外を発生します (MUST)。
戻り値: void
copyToChannel
copyToChannel メソッドは source で示される配列から AudioBuffer の指定されたチャンネルにサンプルをコピーします。
パラメータNull可省略可説明
sourceFloat32Array チャンネルデータをコピーする元の配列です。
channelNumberunsigned long データをコピーする先のチャンネルのインデックスです。もし、 channelNumberAudioBuffer のチャンネル数よりも大きいまたは等しい場合、IndexSizeError 例外を発生します (MUST)。
startInChannelunsigned long = 0 オプションのオフセットで、コピーをどこへ行うかを指定します。もし startInChannelAudioBufferlength より大きい場合、IndexSizeError 例外を発生します (MUST)。
戻り値: void
getChannelData
指定のチャンネルの PCM オーディオデータが格納された Float32Array を返します。
パラメータNull可省略可説明
channelunsigned long このパラメータはデータを取得するチャンネルのインデックスです。 インデックス値0は最初のチャンネルを表します。 このインデックスは numberOfChannels より小さくなくてはならず(MUST)、そうでない場合 IndexSizeError 例外を発生します(MUST)。
戻り値: Float32Array

copyToChannel および copyFromChannel メソッドは より大きな配列に対する view である Float32Array を渡す事で配列の一部だけを埋める事ができます。 AudioBuffer のチャンネルから一塊として処理できるデータを読み出す場合、getChannelData を呼び出して結果の配列にアクセスするよりも 不必要なメモリー割り当てとコピーを避けられるため、copyFromChannel を使用するべきです。

APIの実装が AudioBuffer の内容が必要になった時、AudioBuffer の内容の取得」の内部処理が起動されます。 この処理は呼び出し元に変更不能なチャンネルデータを返します。

AudioBufferAudioBuffer の内容の取得」処理は次のステップで実行されます:

  1. もし AudioBufferArrayBuffer のどれかが無力化されている場合はこれらのステップを中止し、長さ 0 のチャンネルデータを呼び出し元に返します。
  2. この AudioBuffer であらかじめ getChannelData によって返されている全ての ArrayBuffer を無力化します。
  3. それらの ArrayBuffer の下層のデータバッファを保持して、呼び出し元(訳注:API の実装側)に参照を返します。
  4. 次回の getChannelData の呼び出しでは、 データのコピーを持っている ArrayBufferAudioBuffer に割り当てて返します。
AudioBuffer の内容の取得」処理は以下の場合に呼び出されます:

これは copyToChannelAudioNodeAudioBuffer の内容を取得して現在使用状態にある AudioBuffer の内容を変更できない事を意味します。AudioNode は以前に取得したデータを使い続けます。

2.10 AudioBufferSourceNode インターフェース

このインターフェースは AudioBuffer によってメモリ上に保持されているオーディオデータからのオーディオソースを表します。 これはオーディオデータの再生に高度なスケジューリングの柔軟性が要求される場合、例えば完全なリズムを刻むように再生する、ような場合に役立ちます。 もしネットワークからあるいはディスクからのデータをサンプル精度で再生する必要がある場合、実装する人は再生のために AudioWorker を使用しなくてはなりません。

start() メソッドはいつ再生されるかをスケジュールするために使用されます。 start() メソッドを複数回呼び出す事はできません。 再生は(もし loop 属性が指定されていなければ)バッファのオーディオデータがすべて再生されると自動的に、 あるいは stop() メソッドが呼び出されて指定された時刻になると停止します。

  numberOfInputs  : 0
  numberOfOutputs : 1

出力のチャンネル数は常に .buffer 属性に指定された AudioBuffer のチャンネル数と同じになります。 もし .buffer が NULL の場合、チャンネルは無音の1チャンネルとなります。

interface AudioBufferSourceNode : AudioNode {
                    attribute AudioBuffer? buffer;
    readonly        attribute AudioParam   playbackRate;
    readonly        attribute AudioParam   detune;
                    attribute boolean      loop;
                    attribute double       loopStart;
                    attribute double       loopEnd;
    void start (optional double when = 0
              , optional double offset = 0
              , optional double duration);
    void stop (optional double when = 0
              );
                    attribute EventHandler onended;
};

2.10.1 属性

buffer AudioBuffer 型, nullable
再生されるオーディオのリソースを指定します。この属性は1回のみ設定できます。そうでない場合は InvalidStateError 例外を発生します (MUST)。
detune AudioParam 型, readonly
オーディオストリームをレンダリングするスピードを変調する追加のパラメータです。 このデフォルト値は 0 です。名目上の範囲は [-1200; 1200] になります。 このパラメータは k-rate です。
loop boolean
オーディオデータをループ再生する事を指定します。デフォルト値は false です。 もし loop が再生の途中で動的に変更された場合、新しい値は次のオーディオ処理ブロックで効果が表れます。
loopEnd double
loop 属性が true の場合、ループの終了位置を秒で表すオプションの値です。 この値はループの設定にのみ使用されます: ループを構成するサンプルフレームは loopStart から loopEnd-(1.0/sampleRate)となります。 デフォルト値は 0 で、通常は 0 からバッファの長さの任意の値に設定されます。 loopEnd が 0 より小さい場合ループは 0 で終了します。 もし、loopEnd がバッファの長さよりも大きい場合、ループはバッファの最後で終了します。 この属性は、バッファのサンプルレートと乗算され、最も近い整数値に丸められる事でバッファ中の正確なサンプルフレームのオフセットに変換されます。そのため動作は playbackRate パラメータの値に影響されません。
loopStart double
loop 属性が true の場合、ループの開始位置を秒で表すオプションの値です。 デフォルト値は 0 で、通常は 0 からバッファの長さの任意の値に設定されます。 もし loopStart が 0 より小さい場合、ループは 0 から開始します。 もし loopEnd がバッファの長さよりも大きい場合、ループはバッファの最後から開始します。 この属性は、バッファのサンプルレートと乗算され、最も近い整数値に丸められる事でバッファ中の正確なサンプルフレームのオフセットに変換されます。 そのため動作は playbackRate パラメータの値に影響されません。
onended EventHandler
AudioBufferSourceNode ノードにディスパッチされる ended イベントに対する ( HTML[HTML]で記述されている) EventHandlerを設定するための属性です。 AudioBufferSourceNode がバッファの再生を終えた時、(HTML [HTML]で記述されている) イベントタイプ Event がイベントハンドラにディスパッチされます。
playbackRate AudioParam 型, readonly
オーディオストリームの再生速度です。デフォルトの value は 1 です。このパラメータはk-rateです。

2.10.2 メソッド

start
指定の時刻に音の再生開始をスケジュールします。 start は1回のみ呼びだす事ができ、呼び出すのは stop が呼ばれる前でなくてはなりません。 そうでない場合、InvalidStateError 例外を発生します (MUST)。
パラメータNull可省略可説明
whendouble = 0 when パラメータは、再生の開始時刻を(秒で)指定します。 これは AudioContextcurrentTime 属性と同じ時間軸の時刻を使用します。 もしこの値に 0 、あるいは currentTime よりも小さな値を渡した場合、音は即時に再生されます。 もし when が負の値の場合、TypeError 例外を発生します (MUST)。
offsetdouble = 0 offset パラメータはバッファ中の再生開始位置を(秒で)指定します。 もしこの値に 0 が渡された場合、再生はバッファの先頭から開始されます。 もし offset が負の値の場合 TypeError 例外を発生します (MUST)。 もし offsetloopEnd より大きい場合、再生は loopEnd から始まり (そして即時に loopStart にループし) ます。 このパラメータはバッファのサンプルレートと乗算され、最も近い整数値に丸められる事でバッファ中の正確なサンプルフレームのオフセットに変換されます。 そのため動作は playbackRate パラメータの値に影響されません。
durationdouble duration パラメータは再生される部分の長さを(秒で)指定します。 もしこの値が渡されなかった場合、再生の長さは AudioBuffer 全体の長さから offset を引いたものになります。 つまり、offsetduration も指定されなかった場合、暗黙的に duration は AudioBuffer 全体の長さとなります。 もし duration が負の値の場合、TypeError 例外を発生します (MUST)。
戻り値: void
stop
指定の時刻に再生停止をスケジュールします。
パラメータNull可省略可説明
whendouble = 0 when パラメータは、再生の停止時刻を(秒で)指定します。 これは AudioContextcurrentTime 属性と同じ時間軸の時刻を使用します。 もしこの値に 0 、あるいは currentTime よりも小さな値を渡した場合、音は即時に停止されます。 もし when が負の値の場合、TypeError 例外を発生します (MUST)。 もし stop が一度呼ばれた後に再度呼ばれた場合、呼び出しの前に既にバッファが停止しているのでなければ、最後の呼び出しのみが適用されて以前の呼び出しで設定された停止時刻は適用されません。 もしバッファが既に停止している時に更に stop を呼び出しても効果はありません。もしスケジュールされている開始時刻より前に停止時刻に到達した場合、再生は開始されません。
戻り値: void

playbackRate および detune はどちらも k-rate パラメータであり、共に computedPlaybackRate の計算に使用されます。

  computedPlaybackRate(t) = playbackRate(t) * pow(2, detune(t) / 1200)

computedPlaybackRate はこの AudioBufferSourceNodeAudioBuffer が再生されるべき速度になります (MUST)。

これは入力データを 1 / computedPlaybackRate の率でリサンプリングし、音高と速度を変化させるように実装しなくてはなりません (MUST)。

2.10.3 ループ再生

もし start() が呼ばれた時に loop 属性が true であれば、再生は stop() が呼ばれて停止時刻になるまで無限に継続します。 これを "ループ" モードと呼びます。 再生は常に start()offset 引数で指定されたバッファ中の位置から開始され、ループモード中、 actualLoopEnd のバッファ位置 (あるいはバッファの終端位置) まで再生され、 actualLoopStart のバッファ位置に戻る事が繰り返されます。

ループモードでは実際のループ位置は loopStart および loopStart 属性から次のように計算されます:

if ((loopStart || loopEnd) && loopStart >= 0 && loopEnd > 0 && loopStart < loopEnd) {
    actualLoopStart = loopStart;
    actualLoopEnd = min(loopEnd, buffer.duration);
} else {
    actualLoopStart = 0;
    actualLoopEnd = buffer.duration;
}

loopStart および loopEnd のデフォルト値はどちらも 0 である事に注意が必要です。これはループがバッファの先頭から始まり、バッファの終端位置で終わる事を意味します。

低レベルの実装の詳細では、特定のサンプルレート (通常は AudioContext のサンプルレートと同じですが) の AudioBuffer では、 ループの時間 (秒) がサンプルレートに従って適切なサンプルフレームの位置に変換されなくてはならない事に注意が必要です。

start()stop() メソッドを使用して再生の開始と停止をスケジュールした時、結果的に開始または停止の時間は AudioContext のサンプルレートでの最も近いサンプルフレームの時刻に丸めなくてはなりません (MUST)。 それはつまり、サブフレームでのスケジューリングは不可能である事を意味します。

2.11 MediaElementAudioSourceNode インターフェース

このインターフェースは audio または video 要素からの音声ソースを表します。

  numberOfInputs  : 0
  numberOfOutputs : 1

出力のチャンネル数は HTMLMediaElement で参照されるメディアのチャンネル数に対応します。 そのため、メディア要素の .src 属性を変更する事によって、このノードの出力チャンネル数が変化します。 もし .src 属性が設定されていない場合、出力は 1 チャンネルの無音となります。

interface MediaElementAudioSourceNode : AudioNode {
};

MediaElementAudioSourceNodeHTMLMediaElement からAudioContextcreateMediaElementSource() メソッドを使用して作成されます。

出力は1つでチャンネル数は createMediaElementSource() の引数として渡された HTMLMediaElement のオーディオのチャンネル数と同じになります。 もしその HTMLMediaElement がオーディオを持っていない場合、1となります。

HTMLMediaElementMediaElementAudioSourceNode が作成された後、オーディオが直接、音として再生されなくなる代わりに MediaElementAudioSourceNode からルーティンググラフを通して再生されるようになる事を除けば、MediaElementAudioSourceNodeを使わない場合と全く同じように振る舞わなくてはなりません。 つまり、ポーズ、シーク、ボリューム、 src 属性の変更、その他 HTMLMediaElement としての見掛けは MediaElementAudioSourceNode を使用していない場合と同様に通常どおり働かなくてはなりません。

例 7
var mediaElement = document.getElementById('mediaElementID');
var sourceNode = context.createMediaElementSource(mediaElement);
sourceNode.connect(filterNode);

2.11.1 MediaElementAudioSourceNode と クロスオリジン・リソース に関するセキュリティ

HTMLMediaElement はクロスオリジン・リソースの再生が可能です。 Web Audio はリソースの内容の検査が、 (例えば、 MediaElementAudioSourceNodeScriptProcessorNode を使ってサンプルを読む事で) 可能なので、もしある origin からのスクリプトが別の origin からのリソースの内容を検査する事で情報の漏洩が起こり得ます。

これを防ぐため、 MediaElementAudioSourceNode は、もしその HTMLMediaElement がフェッチアルゴリズムの実行により CORS-cross-origin とラベルが付けられている場合、通常の HTMLMediaElement の出力の代わりに無音を出力しなくてはなりません (MUST)。

2.12 AudioWorker インターフェース

AudioWorker オブジェクトは Javascript でオーディオを処理するワーカー"スレッド"のメインスレッドでの表現です。 この AudioWorker オブジェクトは同じタイプの複数のオーディオノードを作成するのに使用されるファクトリになっています。 つまりこれによりコード、プログラムデータ、グローバルな状態をノードをまたいで共有する事が簡単にできます。 AudioWorker はその AudioWorker で処理される個別のノードのメインスレッドでの表現である AudioWorkerNode のインスタンスを作成するために使用されます。

これらのメインスレッドオブジェクトはオーディオスレッドでのコンテキストの処理をインスタンス化します。 全ての AudioWorkerNode のオーディオ処理はオーディオ処理スレッド内で実行されます。 これは特に注意すべき幾つかの副作用を持っています: オーディオワーカーのスレッドをブロックすると音のグリッジが発生し、(グリッジが起こる可能性を下げるために)もしオーディオ処理スレッドの優先度を上げるなら(ユーザーが供給するスクリプトコードのスレッド優先度の上昇の連鎖を避けるため)通常のスレッドの優先度を格下げしなくてはなりません。

オーディオワーカースクリプトの内部からは、オーディオワーカーのファクトリはノードのコンテキストの情報を表す AudioWorkerGlobalScope オブジェクトとして、ファクトリで作成された個別のノードは AudioWorkerNodeProcessor として見えます。

加えて、同じ AudioWorker で作成された全ての AudioWorkerNodeAudioWorkerGlobalScope を共有します。つまりこれにより、それらのノードはコンテキストを共有し、ノードをまたいでデータの共有(例えば、1つの共有データベースの実体をロードして各ノードで使用する、あるいはコンテキストを共有してオシレータの同期を実装するなど)ができます。

interface AudioWorker : Worker {
    void            terminate ();
    void            postMessage (any message, optional sequence<Transferable> transfer);
    readonly        attribute AudioWorkerParamDescriptor[] parameters;
                    attribute EventHandler                 onmessage;
                    attribute EventHandler                 onloaded;
    AudioWorkerNode createNode (int numberOfInputs, int numberOfOutputs);
    AudioParam      addParameter (DOMString name, float defaultValue);
    void            removeParameter (DOMString name);
};

2.12.1 属性

onloaded EventHandler
onloaded ハンドラーはスクリプトの読み込みに成功した後に呼び出され、AudioWorkerGlobalScope を初期化するためにそのグローバルスコープのコードが実行されます。
onmessage EventHandler
onmessage ハンドラーは AudioWorkerGlobalScope がメインスレッドにメッセージをポストした時に常に呼び出されます。
parameters array of AudioWorkerParamDescriptor型, readonly
この配列はこの AudioWorker で作成されたノードの現在の各パラメータのディスクリプタを保持しています。 これにより、AudioWorker のユーザーは簡単に AudioParam の名前とデフォルト値に対する繰り返し処理を行う事ができます。

2.12.2 メソッド

addParameter

この AudioWorker によって作成される(既に存在するあるいは今後作成される)全ての AudioWorkerNode に名前に対応したリードオンリーの AudioParam を付加し、 以降のこれらのノードの AudioProcessEvent 上に現れる parameters オブジェクトに名前に対応したリードオンリーの Float32Array を付加します。 AudioParam は即時にそのスケジューリングメソッドが呼び出されたり、 .value に値を設定されたり、あるいは AudioNode から接続されたりするかも知れません。

name パラメータはそのリードオンリーの AudioParam を AudioWorkerNode に追加する際に使用され、また、以降の AudioProcessEvent 上の parameters オブジェクトでのリードオンリー Float32Array の名前として使用されます。

defaultValue パラメータはその AudioParam の value 属性のデフォルト値です。そのため、ワーカースクリプトでは(もしパラメータの書き換えや接続によって値が変わらなければ) Float32Array のデフォルトの値として現れます。

パラメータNull可省略可説明
nameDOMString
defaultValuefloat
戻り値: AudioParam
createNode
オーディオワーカー内でノードのインスタンスを作成します。
パラメータNull可省略可説明
numberOfInputsint
numberOfOutputsint
戻り値: AudioWorkerNode
postMessage
postMessage は [Workers] で定義されているアルゴリズムと同様に、AudioWorkerGlobalScope にメッセージを送るために呼ばれます。
パラメータNull可省略可説明
messageany
transfersequence<Transferable>
戻り値: void
removeParameter

この AudioWorker とその AudioWorkerGlobalScope に結びついた全ての AudioWorkerNode から、それまでに追加された name の名前を持つパラメータを削除します。 またこれは名前の付いたリードオンリーの AudioParamAudioWorkerNode から削除し、さらにAudioProcessEventparameters メンバーからその名前の付いたリードオンリーの Float32Array を 削除します。 この AudioWorker にその名前のパラメーターが存在しない場合、NotFoundError 例外を発生します。

name は削除するパラメータを指定します。

パラメータNull可省略可説明
nameDOMString
戻り値: void
terminate
terminate() メソッドが呼び出された時、 AudioWorkerGlobalScope に関連するオーディオワーカー内の全ての AudioProcessEvent のディスパッチを停止しなくてはなりません。 これはまた全ての関連する AudioWorkerNode の処理を停止し、ワーカーのコンテキストも破棄します。実際的な言い方をすれば、これは AudioWorker から作成された全てのノード自体を切断し、全ての意味のある動作を停止させます。
パラメータなし
戻り値: void

AudioWorkerNode オブジェクトは addParameter メソッドによって追加されたそれぞれの名前に対応したリードオンリーの AudioParam オブジェクトを持っている事に注意してください。これは動的に行われるため、IDL 表現には含まれていません。

AudioWorker インターフェースは Worker から継承されるため、オーディオワーカースクリプトとの通信のために Worker のインターフェースを実装しなくてはなりません。

2.12.3 AudioWorkerNode インターフェース

このインターフェースはオーディオを直接生成、処理、分析する Worker スレッドに対して作用する AudioNode を表します。 ユーザーは AudioWorkerGlobalScope 内に保持される分離されたオーディオ処理のワーカースクリプトを作成し、メインUIスレッドではなくオーディオ処理スレッド内で実行されます。 AudioWorkerNode はメイン処理スレッドのノードグラフ内では処理ノードとして表されます。つまり、AudioWorkerGlobalScope はユーザーのオーディオ処理スクリプトを動作させるコンテキストを表します。

Web Audio の実装は通常オーディオ処理スレッドの優先度をノーマルよりも高くするのが普通である事に注意してください。(ユーザースクリプトはノーマルよりも高い優先度で動作させる事ができないため) AudioWokerNode の利用はオーディオ処理スレッドの優先度を格下げする場合があります。

    numberOfInputs  : variable
    numberOfOutputs : variable

    channelCount = numberOfInputChannels;
    channelCountMode = "explicit";
    channelInterpretation = "speakers";

createAudioWorkerNode()(訳注:createNode()の間違いと思われます) の呼び出しの際に指定された入力と出力のチャンネルの数が初期状態の入出力のチャンネル数(および入出力それぞれに対応して AudioWorkerGlobalScope 内に存在する AudioProcess イベントハンドラーに渡されるAudioBufferのチャンネル数) を決定します)。 numberOfInputChannelsnumberOfOutputChannels の両方が0になるのは不正となります。

使用例:

    var bitcrusherFactory = context.createAudioWorker( "bitcrusher.js" );
    var bitcrusherNode = bitcrusherFactory.createNode();
interface AudioWorkerNode : AudioNode {
    void postMessage (any message, optional sequence<Transferable> transfer);
                    attribute EventHandler onmessage;
};
2.12.3.1 属性
onmessage EventHandler
onmessage ハンドラーは AudioWorkerNodeProcessor がメインスレッドに対してノードメッセージを送り返した際に常に呼び出されます。
2.12.3.2 メソッド
postMessage
postMessage は AudioWorkerNodeProcessor に対して the Worker specification で定義されたアルゴリズムでメッセージを送るために呼び出されます。 これは AudioWorkerGlobalScope に影響を与えるため、AudioWorker 自身で postMessage() を呼び出すのとは異なる事に注意してください。
パラメータNull可省略可説明
messageany
transfersequence<Transferable>
戻り値: void

AudioWorkerNode オブジェクトはまた、AudioWorker の addParameter メソッドによって追加された名前付きパラメータ毎に対応したリードオンリーの AudioParam オブジェクトを持っている事に注意してください。これは動的に行われるため、IDL には表現されていません。

2.12.4 AudioWorkerParamDescriptor インターフェース

このインターフェースは AudioWorkerNodeのAudioParam -- 端的にはその名前とデフォルト値を表します。これは (AudioParamのインスタンスを保持していない) AudioWorkerGlobalScope から AudioParam に対する反復処理を行いやすくします。

interface AudioWorkerParamDescriptor {
    readonly        attribute DOMString name;
    readonly        attribute float     defaultValue;
};
2.12.4.1 属性
defaultValue of type float, readonly
AudioParam のデフォルト値です。
name DOMString型, readonly
AudioParamの名前です。

2.12.5 AudioWorkerGlobalScope インターフェース

このインターフェースは DedicatedWorkerGlobalScope の派生オブジェクトでオーディオ処理スクリプトが実行されるコンテキストを表します -- そしてそれはオーディオノードの複数のインスタンスで共有され、ワーカースレッド内の JavaScript を用いてオーディオの直接的な合成、処理、分析ができるように設計されています。 これはノードが例えばコンポリューションノードのように大量の共有データを持つ場合に役立ちます。

-

AudioWorkerGlobalScope は このワーカーで作成されたノードのオーディオフレームの処理に同期してディスパッチされる audioprocess イベントを管理します。 - audioprocess イベントは 少なくとも1つの入力あるいは1つの接続された出力を持つノードにのみディスパッチされます。 TODO : これは本当? (訳注:このあたりはまだ完全な文書にはなっていないようです)

interface AudioWorkerGlobalScope : DedicatedWorkerGlobalScope {
    readonly        attribute float                        sampleRate;
    AudioParam addParameter (DOMString name, float defaultValue);
    void       removeParameter (DOMString name);
                    attribute EventHandler                 onaudioprocess;
                    attribute EventHandler                 onnodecreate;
    readonly        attribute AudioWorkerParamDescriptor[] parameters;
};
2.12.5.1 属性
onaudioprocess EventHandler
関連するノードが (少なくとも1つの入力または出力が) 接続されている間、オーディオ処理のために AudioWorkerGlobalScope にディスパッチされる audioprocess イベントに対応する ([HTML]で説明される) EventHandler を設定するために使用されるプロパティです。
onnodecreate EventHandler
AudioWorkerNode が新しく作成された時に AudioWorkerGlobalScope にディスパッチされる nodecreate イベントのための ([HTML]で説明されている) EventHandler を設定するために使用されるプロパティです。 これは AudioNodeProcessor オブジェクトのノードレベルの初期化を行う事を可能にします。 AudioWorkerNodeCreationEvent がイベントハンドラーにディスパッチされます。
parameters array of AudioWorkerParamDescriptor型, readonly
この配列はこの AudioWorkerGlobalScope 内で作成されたノード上の現在の各パラメータのディスクリプターを保持しています。 これによりオーディオワーカーの実装は簡単に AudioParam の名前とデフォルト値の反復操作を行う事ができます。
sampleRate float型, readonly
ホストとなる AudioContext のサンプルレートです。 (Worker 内のスコープではユーザーは AudioContext に直接のアクセスはできません)
2.12.5.2 メソッド
addParameter

このファクトリによって作成される(既に存在するあるいは今後作成される)全ての AudioWorkerNode に名前に応じたリードオンリーの AudioParam を付加し、 また以降のこれらのノードの AudioProcessEvent 上の parameters オブジェクトに名前に応じたリードオンリーの Float32Array を付加します。

オーディオワーカーに対してメインスレッドまたはワーカースクリプトのどちらからでも AudioParam が追加(あるいは削除)できる事は意図的なものです。 これは瞬時にワーカーベースのノードとそのプロトタイプの作成する事を可能にするだけでなく、 AudioParam の構成も単一のスクリプトに含んだワーカー全体のパッケージ化も可能にします。 ワーカースクリプトがノードを構成できるように AudioWorkerNode の oninitialized が呼び出された後でのみノードが使用される事が推奨されます。

name パラメータは AudioWorkerNode に追加されるリードオンリーの AudioParam の名前として、また以降の AudioProcessEvent でアクセスできる parameters オブジェクト上に現れるリードオンリーの Float32Array の名前として使用される。

defaultValue パラメータは AudioParam の value 属性のデフォルト値であり、また (もし他のパラメータ変更あるいは接続の影響がなければ) ワーカースクリプトの Float32Array にデフォルト値として表れます

パラメータNull可省略可説明
nameDOMString
defaultValuefloat
戻り値: AudioParam
removeParameter

このファクトリで作成されたノードから以前に追加された name の名前を持つパラメータを削除します。 またこれはこの名前を持つリードオンリーの AudioParamAudioWorkerNode から削除し、さらに以降のオーディオ処理イベントでこの名前を持つリードオンリーの Float32Array も AudioProcessEventparameters のメンバーから削除します。 このノードにその名前のパラメーターが存在しない場合、NotFoundError 例外を発生します(MUST)。

nameは削除するパラメータを特定します。

パラメータNull可省略可説明
nameDOMString
戻り値: void

2.12.6 AudioWorkerNodeProcessor インターフェース

このインターフェースをサポートするオブジェクトは AudioWorkerGlobalScope 内でインスタンス化された個別のノードを表します。 これは個々のノードのデータを管理するために設計されています。 複数のオーディオノードのインスタンス間で共有されるコンテキストは AudioWorkerGlobalScope からアクセス可能です。 このオブジェクトは個々のノードを表し、データストレージまたはメインスレッドとの通信に使用できます。

interface AudioWorkerNodeProcessor : EventTarget {
    void postMessage (any message, optional sequence<Transferable> transfer);
                    attribute EventHandler onmessage;
};
2.12.6.1 属性
onmessage EventHandler
onmessage ハンドラーは AudioWorkerNode がノードメッセージをオーディオスレッドに送り返す度に呼び出されます。
2.12.6.2 メソッド
postMessage
postMesasge は the Worker specification で定義されるアルゴリズムを使って AudioWorkerNode にメッセージを送るために呼び出されます。 これは AudioWorker 自身で PostMesage() を呼び出すのとは異なり、AudioWorkerGlobalScope にディスパッチされる事に注意してください。
パラメータNull可省略可説明
messageany
transfersequence<Transferable>
戻り値: void

2.12.7 オーディオワーカーのサンプル

このセクションは参考情報です

2.12.7.1 ビットクラッシャーノード

ビットクラッシュはオーディオストリームの音質を下げる機構です -- (整数ベースオーディオの低ビット深度をシミュレートする)値のクオンタイズと(低サンプルレートをシミュレートする)時間方向のクオンタイズの両方を使用します。 この例は AudioWorker 内での AudioParam (この例では a-rateとして処理します)の使い方を示します。

Main file javascript
var bitcrusherFactory = null;
audioContext.createAudioWorker("bitcrusher_worker.js").then( function(factory)
    {  // cache 'factory' in case you want to create more nodes!
      bitcrusherFactory = factory;
      var bitcrusherNode = factory.createNode();
      bitcrusherNode.bits.setValueAtTime(8,0);
      bitcrusherNode.connect(output);
      input.connect(bitcrusherNode);
    }
  );
bitcrusher_worker.js
            // Custom parameter - number of bits to crush down to - default 8
this.addParameter( "bits", 8 );

// Custom parameter - frequency reduction, 0-1, default 0.5
this.addParameter( "frequencyReduction", 0.5 );

onnodecreate=function(e) {
  e.node.phaser = 0;
  e.node.lastDataValue = 0;
}

onaudioprocess= function (e) {
  for (var channel=0; channel<e.inputs[0].length; channel++) {
    var inputBuffer = e.inputs[0][channel];
    var outputBuffer = e.outputs[0][channel];
    var bufferLength = inputBuffer.length;
    var bitsArray = e.parameters.bits;
    var frequencyReductionArray = e.parameters.frequencyReduction;

    for (var i=0; i<bufferLength; i++) {
      var bits = bitsArray ? bitsArray[i] : 8;
      var frequencyReduction = frequencyReductionArray ? frequencyReductionArray[i] : 0.5;

      var step = Math.pow(1/2, bits);
      e.node.phaser += frequencyReduction;
      if (e.node.phaser >= 1.0) {
          e.node.phaser -= 1.0;
          e.node.lastDataValue = step * Math.floor(inputBuffer[i] / step + 0.5);
      }
      outputBuffer[i] = e.node.lastDataValue;
    }
  }
};
2.12.7.2 TODO: このサンプルを直す事。ボリュームメーターとクリップデテクター

もう一つのよくある例はクリップ検出とボリュームメーターです。 この例は Workerとの間で (AudioParam スケジューリングを必要としない) 基本的なパラメータの通信とメインスレッドに対してデータを送り返すやり方を示しています。このノードは出力を使用していません。

Main file javascript
function setupNodeMessaging(node) {
  // This handles communication back from the volume meter
  node.onmessage = function (event) {
    if (event.data instanceof Object ) {
      if (event.data.hasOwnProperty("clip")
        this.clip = event.data.clip;
      if (event.data.hasOwnProperty("volume")
        this.volume = event.data.volume;
    }
  }

  // Set up some default configuration parameters
  node.postMessage(
    { "smoothing": 0.9,   // Smoothing parameter
      "clipLevel": 0.9,   // Level to consider "clipping"
      "clipLag": 750,     // How long to keep "clipping" lit up after clip (ms)
      "updating": 100      // How frequently to update volume and clip param (ms)
    });

  // Set up volume and clip attributes.  These will be updated by our onmessage.
  node.volume = 0;
  node.clip = false;
}

var vuNode = null;

audioContext.createAudioWorker("vu_meter_worker.js").then( function(factory)
    {  // cache 'factory' in case you want to create more nodes!
      vuFactory = factory;
      vuNode = factory.createNode([1], []); // we don't need an output, and let's force to mono
      setupNodeMessaging(vuNode);
    }
  );

window.requestAnimationFrame( function(timestamp) {
  if (vuNode) {
  // Draw a bar based on vuNode.volume and vuNode.clip
  }
});
vu_meter_worker.js
// Custom parameter - number of bits to crush down to - default 8
this.addParameter( "bits", 8 );

// Custom parameter - frequency reduction, 0-1, default 0.5
this.addParameter( "frequencyReduction", 0.5 );

onnodecreate=function(e) {
  e.node.timeToNextUpdate = 0.1 * sampleRate;
  e.node.smoothing = 0.5;
  e.node.clipLevel = 0.95;
  e.node.clipLag = 1;
  e.node.updatingInterval = 150;
  // This just handles setting attribute values
  e.node.onmessage = function ( event ) {
    if (event.data instanceof Object ) {
      if (event.data.hasOwnProperty("smoothing")
        this.smoothing = event.data.smoothing;
      if (event.data.hasOwnProperty("clipLevel")
        this.clipLevel = event.data.clipLevel;
      if (event.data.hasOwnProperty("clipLag")
        this.clipLag = event.data.clipLag / 1000;  // convert to seconds
      if (event.data.hasOwnProperty("updating")    // convert to samples
        this.updatingInterval = event.data.updating * sampleRate / 1000 ;
    }
  };
}

onaudioprocess = function ( event ) {
  var buf = event.inputs[0][0];  // Node forces mono
  var bufLength = buf.length;
  var sum = 0;
  var x;

  // Do a root-mean-square on the samples: sum up the squares...
  for (var i=0; i<bufLength; i++) {
    x = buf[i];
    if (Math.abs(x)>=event.node.clipLevel) {
      event.node.clipping = true;
      event.node.unsentClip = true;  // Make sure, for every clip, we send a message.
      event.node.lastClip = event.playbackTime + (i/sampleRate);
    }
    sum += x * x;
  }

  // ... then take the square root of the sum.
  var rms =  Math.sqrt(sum / bufLength);

  // Now smooth this out with the smoothing factor applied
  // to the previous sample - take the max here because we
  // want "fast attack, slow release."
  event.node.volume = Math.max(rms, event.node.volume*event.node.smoothing);
  if (event.node.clipping && (!event.node.unsentClip) && (event.playbackTime > (this.lastClip + clipLag)))
    event.node.clipping = false;

  // How long has it been since our last update?
  event.node.timeToNextUpdate -= event.node.last;
  if (event.node.timeToNextUpdate<0) {
    event.node.timeToNextUpdate = event.node.updatingInterval;
    event.node.postMessage(
      { "volume": event.node.volume,
        "clip": event.node.clipping });
    event.node.unsentClip = false;
  }
};
2.12.7.3 ChannelMergerの再実装

このワーカーは複数の入力を1つの出力チャンネルにまとめる例を示しています。

Main file javascript
            var mergerNode = audioContext.createAudioWorker("merger_worker.js", [1,1,1,1,1,1], [6] );
var mergerFactory = null;

audioContext.createAudioWorker("merger_worker.js").then( function(factory)
    {  // cache 'factory' in case you want to create more nodes!
      mergerFactory = factory;
      var merger6channelNode = factory.createNode( [1,1,1,1,1,1], [6] );
      // connect inputs and outputs here
    }
  );
merger_worker.js
onaudioprocess= function (e) {
  for (var input=0; input<e,node.inputs.length; input++)
    e.node.outputs[0][input].set(e.node.inputs[input][0]);
};

2.13 ScriptProcessorNode インターフェース - 廃止予定

このセクションは参考情報です

このインターフェースはJavaScriptによってオーディオを直接、合成、加工、分析する事ができる AudioNode です。 このノードタイプは廃止予定で、AudioWorkerNode で置き換えられます -- この文章は実装がこのノードタイプを削除するまでの参考として置いてあります。

    numberOfInputs  : 1
    numberOfOutputs : 1

    channelCount = numberOfInputChannels;
    channelCountMode = "explicit";
    channelInterpretation = "speakers";

channelCountMode は "explicit" からの変更はできず、channelCount は変更する事ができません。 どちらかを変更しようとすると InvalidStateError 例外を発生します (MUST)。

ScriptProcessorNodebufferSize として次の値のどれかで作成されます: 256、512、1024、2048、4096、8192、16384。 この値は audioprocess イベントがディスパッチされる周期とそれぞれの呼び出しで処理が必要なサンプルフレームの数を制御します。 audioprocess イベントは ScriptProcessorNode が少なくとも1つの入力か1つの出力が接続されている場合にのみディスパッチされます。 bufferSize が小さいと、latency は低く(良く)なります。 オーディオの途切れや グリッジ を避けるには大きい値が必要になります。 createScriptProcessor に渡される bufferSize 引数がない、または 0 の場合、実装によって自動的に選択されます。

numberOfInputChannelsnumberOfOutputChannels は入力と出力のチャンネル数を決定します。 numberOfInputChannelsnumberOfOutputChannels の両方が 0 になるのは不正になります。

    var node = context.createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels);
interface ScriptProcessorNode : AudioNode {
                    attribute EventHandler onaudioprocess;
    readonly        attribute long         bufferSize;
};

2.13.1 属性

bufferSize long 型, readonly
onaudioprocess が呼ばれる毎に処理が必要なバッファのサイズ(サンプルフレーム数)です。 使用可能な値は (256、 512、 1024、 2048、 4096、 8192、 16384) です。
onaudioprocess EventHandler
ScriptProcessorNode ノードにディスパッチされる audioprocess イベントに対する (HTML [HTML] で説明される) EventHandler です。 AudioProcessingEvent 型のイベントがイベントハンドラーにディスパッチされます。

2.14 AudioWorkerNodeCreationEvent インターフェース

これは新しいノードオブジェクトが作成された時に AudioWorkerGlobalScope オブジェクトにディスパッチされる Eventオブジェクトです。 これにより、 AudioWorkerは ノード・ローカルな (例えばディレイを割り当てたり、ローカル変数を初期化する等の) データの初期化ができます。

interface AudioWorkerNodeCreationEvent : Event {
    readonly        attribute AudioWorkerNodeProcessor node;
    readonly        attribute Array                    inputs;
    readonly        attribute Array                    outputs;
};

2.14.1 属性

inputs Array 型, readonly
入力の channelCount の配列です。
node AudioWorkerNodeProcessor 型, readonly
新しく作成されたノードです。全てのノードローカルなデータストレージ (例えば、ディレイノードのバッファ等) はこのオブジェクト上に作成されなくてはなりません。
outputs Array 型, readonly
出力の channelCount の配列です。

2.15 AudioProcessEvent インターフェース

これは処理を実行するために AudioWorkerGlobalScope オブジェクトにディスパッチされる Event オブジェクトです。

イベントハンドラーは(もしあれば) inputBuffers 属性からオーディオデータにアクセスし、入力からのオーディオを処理します。 処理結果の (あるいは入力を使わずに合成された) オーディオデータは outputBuffers に格納されます。

interface AudioProcessEvent : Event {
    readonly        attribute double                   playbackTime;
    readonly        attribute AudioWorkerNodeProcessor node;
    readonly        attribute Float32Array[][]         inputs;
    readonly        attribute Float32Array[][]         outputs;
    readonly        attribute object                   parameters;
};

2.15.1 属性

inputs array of array of Float32Array 型, readonly

リードオンリーの Float32Array の配列の配列です。トップレベルの配列は入力をまとめたものです。 それぞれの入力は複数のチャンネルを持っている場合があります。それぞれのチャンネルは Float32Array のサンプルデータを保持しています。 チャンネル配列の初期サイズは createAudioWorkerNode() メソッドでその入力に指定されたチャンネル数で決定されます。 しかしながら、 onprocess ハンドラーは動的に入力のチャンネル数を変更できます。あるいは ブロック長 (128) の Float32Array を追加したり、配列を (Array.lenth を減らしたり Array.pop() や Array.slice() を使用して) 減少させる事もできます。 処理システムはメモリーの動きを最小化するためにイベントオブジェクト、配列、 Float32Array を再利用します。

入力の配列の並べ替えを行っても以降のイベントでのチャンネルとの関係として認識されません。

node AudioWorkerNodeProcessor 型, readonly
この処理イベントがディスパッチされるノードです。全てのノードローカルなデータストレージ (例えばディレイノードのバッファ等) はこのオブジェクト上で維持されなくてはなりません。
outputs array of array of Float32Array 型, readonly

リードオンリーの Float32Array の配列の配列です。トップレベルの配列は出力をまとめたものです。 それぞれの出力は複数のチャンネルを持っている場合があります。それぞれのチャンネルは Float32Array のサンプルデータを保持しています。 チャンネル配列の初期サイズは createAudioWorkerNode() メソッドでその出力に指定されたチャンネル数で決定されます。 しかしながら、 onprocess ハンドラーは動的に入力のチャンネル数を変更できます。あるいは ブロック長 (128) の Float32Array を追加したり、配列を (Array.lenth を減らしたり Array.pop() や Array.slice() を使用して) 減少させる事もできます。 処理システムはメモリーの動きを最小化するためにイベントオブジェクト、配列、 Float32Array を再利用します。

出力の配列の並べ替えを行っても以降のイベントでのチャンネルとの関係として認識されません。

parameters object 型, readonly
addParameter で追加されたそれぞれのパラメータに対応して、名前に対応づけられたリードオンリーの Float32Array を持つ属性を表すオブジェクトです。 これは動的に処理されるため IDL には表現されません。 Float32Array の長さは inputBuffer の長さに対応します。 この Float32Array の内容は時間に対応した各点での AudioParam の値として使用されます。この Float32Array はオーディオエンジンによって再利用される事が期待されます。
playbackTime double 型, readonly
このイベントで処理されるオーディオのブロックの開始時刻です。 定義としては、これはコントロールスレッド側で読み取れる最も最近の BaseAudioContextcurrentTime 属性と同じです。

2.16 AudioProcessingEvent インターフェース - 廃止予定

このセクションは参考情報です

これは ScriptProcessorNode ノードにディスパッチされる Event オブジェクトです。これは ScriptProcessorNode が削除される時に削除され、代替となる AudioWorkerAudioProcessEventを使用します。

イベントハンドラは (もしあれば) 入力からのオーディオを inputBuffer 属性からデータにアクセスして処理します。 処理結果 (あるいは入力がなければ合成した) オーディオデータは outputBuffer に出力します。

interface AudioProcessingEvent : Event {
    readonly        attribute double      playbackTime;
    readonly        attribute AudioBuffer inputBuffer;
    readonly        attribute AudioBuffer outputBuffer;
};

2.16.1 属性

inputBuffer AudioBuffer 型, readonly
入力データを含む AudioBuffer です。 これは createScriptProcessor() メソッドの numberOfInputChannels と同じチャンネル数を持ちます。 この AudioBuffer は onaudioprocess 関数のスコープ中でのみ有効です。 その値はスコープの外では意味を持ちません。
outputBuffer AudioBuffer 型, readonly
出力するオーディオデータを書き込むための AudioBuffer です。 これは createScriptProcessor() メソッドの numberOfOutputChannels と同じチャンネル数を持ちます。 onaudioprocess 関数スコープ中のスクリプトコードはこの AufioBuffer 中のチャンネルデータが表す Float32Array 配列に 書き込む事が期待されます。 このスコープ外での、この AudioBuffer に対するスクリプトによる変更は何も効果を持ちません。
playbackTime double 型, readonly
AudioContextcurrentTime と同じ時間軸で表された、そのオーディオが再生される時刻です。

2.17 PannerNode インターフェース

このインターフェースは入力されるオーディオストリームの3D空間での 定位 / 空間音響を処理するためのノードを表します。 空間音響は AudioContextAudioListener (listener 属性) に関連して処理されます。

    numberOfInputs  : 1
    numberOfOutputs : 1

    channelCount = 2;
    channelCountMode = "clamped-max";
    channelInterpretation = "speakers";

このノードの入力はモノ (1 チャンネル) またはステレオ (2 チャンネル) となり、増やす事はできません。 より少ない、または多いチャンネル数のノードからの接続は適宜アップミックスまたはダウンミックスされますが、もし、 channelCount を 2 以上に設定しようとしたり channelCountMode を "max" に設定しようとすると NotSupportedError 例外を発生します (MUST)。

このノードの出力はステレオ (2 チャンネル) にハードコードされており、変える事はできません。

PanningModelType 列挙値は 3D 空間でのオーディオの定位のアルゴリズムを決定します。 デフォルトは "equalpower"です。

enum PanningModelType {
    "equalpower",
    "HRTF"
};
列挙値の説明
equalpower 単純で効率的な空間音響アルゴリズムで、等価パワーによるパンニングを行います。
HRTF 高品質な空間音響アルゴリズムで、人体を使ったインパルスレスポンス測定からのコンボリューション処理を使用します。 このパンニング方法はステレオ出力にレンダリングされます。

DistanceModelType 列挙値は 音源がリスナーから離れていった時、音量を減衰させるためにどのアルゴリズムを使用するかを決定します。 デフォルトは "inverse" です。

次のそれぞれの距離モデルの説明で、 \(d\) はリスナーとパンナーの距離、 \(d_{ref}\) は refDistance 属性の値、 \(d_{max}\) は maxDistance 属性の値、 \(f\) は rolloffFactor の値です。

enum DistanceModelType {
    "linear",
    "inverse",
    "exponential"
};
列挙値の説明
linear

distanceGainを次のように計算する直線距離モデルです:

            $$
              1 - f\frac{\max(\min(d, d_{max}), d_{ref}) - d_{ref}}{d_{max} - d_{ref}}
            $$

ここで \(d\) は \([d_{ref},\, d_{max}]\) の範囲に制限されます。

inverse

distanceGain を次のように計算する逆数距離モデルです:

              $$
                \frac{d_{ref}}{d_{ref} + f (\max(d, d_{ref}) - d_{ref})}
              $$

ここで \(d\) は\([d_{ref},\,\infty)\)の範囲に制限されます。

exponential

distanceGain を次のように計算する指数距離モデルです:

              $$
                \left(\frac{\max(d, d_{ref})}{d_{ref}}\right)^{-f}
              $$

ここで \(d\) は \([d_{ref},\,\infty)\) の範囲に制限されます。

interface PannerNode : AudioNode {
                    attribute PanningModelType  panningModel;
    void setPosition (float x, float y, float z);
    void setOrientation (float x, float y, float z);
    void setVelocity (float x, float y, float z);
                    attribute DistanceModelType distanceModel;
                    attribute float             refDistance;
                    attribute float             maxDistance;
                    attribute float             rolloffFactor;
                    attribute float             coneInnerAngle;
                    attribute float             coneOuterAngle;
                    attribute float             coneOuterGain;
};

2.17.1 属性

coneInnerAngle float
音源の指向性パラメータで、度で表す角度です。この角度の内部では音量減衰が生じません。 デフォルトの値は 360 で、値は 360 の剰余で扱われます。
coneOuterAngle float
音源の指向性パラメータで度で表す角度です。 この角度の外側では音量の減衰率が定数値の coneOuterGain となります。 デフォルトの値は360で、値は 360 の剰余で扱われます。
coneOuterGain float
音源の指向性パラメータで、角度が coneOuterAngle の外側の場合の減衰率です。 デフォルトの値は0です。 これは (dBでなく) リニア値で [0, 1] の範囲になります。 もしこのパラメータがこの範囲外の場合、 InvalidStateError 例外を発生します (MUST)。
distanceModel DistanceModelType
この PannerNode で使用される距離モデルを指定します。 デフォルトは "inverse" です。
maxDistance float
音源とリスナー間の最大距離で、これ以上音源とリスナー間が離れても音量が減衰しません。 デフォルトの値は10000です。
panningModel PanningModelType
この PannerNode で使用されるバンニングモデルを指定します。 デフォルトは "equalpower" です。
refDistance float
音源がリスナーから離れていった時の音量減衰の基準となる距離です。 デフォルトの値は 1 です。
rolloffFactor float
音源がリスナーが離れていった時の音量減衰の速さを表します。 デフォルトの値は 1 です。

2.17.2 メソッド

setOrientation

3D 空間のデカルト座標系で音源の向いている方向を表します。 音がどれくらいの指向性 ( cone 属性で制御されます) を持っているかによって音が リスナーからはずれると小さくなったり全く聴こえなくなったりします。

x, y, z パラメータは 3D 空間内での方向を表します。

デフォルトの値は (1, 0, 0) です。

パラメータNull可省略可説明
xfloat
yfloat
zfloat
戻り値: void
setPosition

listener 属性に相対する音源の位置を設定します。 3D のデカルト座標系が使用されます。

x, y, z パラメータは 3D 空間中の座標を表します

デフォルトの値は (1, 0, 0) です。

パラメータNull可省略可説明
xfloat
yfloat
zfloat
戻り値: void
setVelocity

音源の速度ベクトルを設定します。 このベクトルは 3D 空間内での移動する方向と速度の両方を制御します。 この速度とリスナーの速度の相対値によってどれくらいのドップラー効果 (ピッチの変化) が適用されるかが決定します。 このベクトルの単位はメートル / 秒で、位置や方向ベクトルで使われる単位とは独立しています。

x, y, z パラメータは移動の方向と大きさを表すベクトルです。

デフォルトの値は (0, 0, 0) です。

パラメータNull可省略可説明
xfloat
yfloat
zfloat
戻り値: void

2.17.3 チャンネル制限

このセクションは参考情報です。

StereoPannerNode に対するチャンネル制限PannerNodeにも適用されます。

2.18 AudioListener インターフェース

このインターフェースは廃止予定です。 これは SpatialListener で置き替えられます。このインターフェースはオーディオシーンを聴く人の位置と方向を表します。 全ての PannerNode オブジェクトは BaseAudioContextlistener との相対関係により空間処理されます。 空間処理の詳細については 空間配置 / バンニング セクション を参照してください。

interface AudioListener {
    void setPosition (float x, float y, float z);
    void setOrientation (float x, float y, float z, float xUp, float yUp, float zUp);
};

2.18.1 メソッド

setOrientation

3D デカルト座標空間でリスナーが向いている方向を表します。 front ベクトルと up ベクトルの両方が与えられます。 簡単のため人間について言えば、front ベクトルはその人の鼻が向いている方向を表します。 up ベクトルはその人の頭頂向いている方向です。 これらは線形独立 (互いに直角) の関係になります。 これらの値がどのように解釈されるかの基準としての要件は空間配置 / バンニング セクションを参照してください。

x, y, z パラメータは 3D 空間中の front 方向ベクトルであり、デフォルトの値は (0, 0, -1) です。

xUp, yUp, zUp パラメータは 3D 空間中の up 方向ベクトルであり、デフォルトの値は (0, 1, 0) です。

パラメータNull可省略可説明
xfloat
yfloat
zfloat
xUpfloat
yUpfloat
zUpfloat
戻り値: void
setPosition

3D デカルト座標空間でのリスナーの位置を設定します。 PannerNode オブジェクトはこの位置と個別の音源との相対的な位置を空間音響のために使用します。

x, y, z パラメータは 3D 空間内の座標を表します。

デフォルトの値は (0, 0, 0) です。

パラメータNull可省略可説明
xfloat
yfloat
zfloat
戻り値: void

2.19 SpatialPannerNode インターフェース

このインターフェースは入力されるオーディオストリームを 3D 空間内に定位させる処理を行うノードを表します。空間定位は AudioContextSpatialListener (listener 属性)との関係で行われます。

この空間定位の音響効果は、SpatialPanner が直接 destination ノードに接続されていないとうまく動作しない事を明らかにしなくてはなりません。つまり、以降に続く(SpatialPannerの後ろでdestinationより手前の) 処理は効果を妨害する可能性があります。

    numberOfInputs  : 1
    numberOfOutputs : 1
    channelCount = 2;
    channelCountMode = "clamped-max";
    channelInterpretation = "speakers";

このノードへの入力はモノ (1チャンネル) またはステレオ (2チャンネル) のどちらかで、増やす事はできません。より多くのチャンネルを持つノードからの接続は適宜アップミックスまたはダウンミックスされますが、channelCount を2以上、あるいは channelCountMode を "max" に設定しようとすると NotSupportedError 例外を発生します (MUST)。 このノードの出力はステレオ (2チャンネル) であり今のところ構成を変える事はできません。

PanningModelType 列挙値はオーディオを 3D 空間内に配置するために使用する空間定位のアルゴリズムを決定します。デフォルトは"equal-power"です。

enum PanningModelType {
    "equalpower",
    "HRTF"
};
列挙値の説明
equalpower equal-powerバンニングで使用されるシンプルで効率的な空間配置アルゴリズムです。
HRTF より高品位の空間配置アルゴリズムで人体のインパルスレスポンスの測定からのコンボリューションを使用します。この定位方法はステレオ出力をレンダリングします。

DistanceModelType 列挙値は音源がリスナーから離れた時に音量の減少させる際、どのアルゴリズムを使用するかを決定します。デフォルトは "inverse" です。

enum DistanceModelType {
    "linear",
    "inverse",
    "exponential"
};
列挙値の説明
linear distanceGain を次のように計算する直線距離モデルです:
            1 - rolloffFactor * (distance - refDistance) / (maxDistance - refDistance)
inverse distanceGain を次のように計算する逆数距離モデルです:
            refDistance / (refDistance + rolloffFactor * (distance - refDistance))
exponential distanceGain を次のように計算する指数距離モデルです:
pow(distance / refDistance, -rolloffFactor)
interface SpatialPannerNode : AudioNode {
                    attribute PanningModelType  panningModel;
    readonly        attribute AudioParam        positionX;
    readonly        attribute AudioParam        positionY;
    readonly        attribute AudioParam        positionZ;
    readonly        attribute AudioParam        orientationX;
    readonly        attribute AudioParam        orientationY;
    readonly        attribute AudioParam        orientationZ;
                    attribute DistanceModelType distanceModel;
                    attribute float             refDistance;
                    attribute float             maxDistance;
                    attribute float             rolloffFactor;
                    attribute float             coneInnerAngle;
                    attribute float             coneOuterAngle;
                    attribute float             coneOuterGain;
};

2.19.1 属性

coneInnerAngle float
音源の指向性パラメータで、度で表す角度です。この角度の内部では音量減衰が生じません。 デフォルトの値は360です。
coneOuterAngle float
音源の指向性パラメータで、度で表す角度です。この角度の外側では音量の減衰率が定数値の coneOuterGain となります。 デフォルトの値は360です。
coneOuterGain float 型
音源の指向性パラメータで、角度が coneOuterAngle よりも外側の場合の音量の減衰率です。 デフォルトの値は0です。
distanceModel DistanceModelType
この PannerNode(訳注:SpatialPannerNode) で使用される距離モデルを指定します。デフォルトは "inverse" です。
maxDistance float
音源とリスナーの最大距離で、これ以上これ以上音源とリスナー間が離れても音量が減衰しません。 デフォルトの値は10000です。
orientationX AudioParam 型, readonly
orientationX、 orientationY、 orientationZパラメータは 3D 空間内での方向を表します。
orientationY AudioParam 型, readonly
3D 空間のデカルト座標で音源が向いている方向ベクトルの y 成分を表します。デフォルトは 0 です。このパラメータは a-rate です。
orientationZ AudioParam 型, readonly
3D 空間のデカルト座標で音源が向いている方向ベクトルの Z 成分を表します。デフォルトは 0 です。このパラメータは a-rate です。
panningModel PanningModelType
この PannerNode(訳注:SpatialPannerNode) で使用される定位モデルを指定します。デフォルトは "equal-power" です。
positionX AudioParam 型, readonly
3D 空間のデカルト座標で音源の位置のx座標を指定します。デフォルトは 0 です。このパラメータは a-rate です。
positionY AudioParam 型, readonly
3D 空間のデカルト座標で音源の位置の y 座標を指定します。デフォルトは 0 です。このパラメータは a-rate です。
positionZ AudioParam 型, readonly
3D 空間のデカルト座標で音源の位置の z 座標を指定します。デフォルトは 0 です。このパラメータは a-rate です。
refDistance float
音源がリスナーから離れていった時の音量減衰のリファレンスとなる基準距離です。 デフォルトの値は 1 です。
rolloffFactor float
音源がリスナーが離れていった時の音量減衰の速さを表します。 デフォルトの値は1です。

2.20 SpatialListener インターフェース

このインターフェースは人がオーディオシーンを聴く位置と方向を表します。 全ての SpatialPannerNode オブジェクトは AudioContextspatialListenerとの関係で空間音響処理を行います。 空間音響についての詳細は 空間音響/定位 セクション を参照してください。

interface SpatialListener {
    readonly        attribute AudioParam positionX;
    readonly        attribute AudioParam positionY;
    readonly        attribute AudioParam positionZ;
    readonly        attribute AudioParam forwardX;
    readonly        attribute AudioParam forwardY;
    readonly        attribute AudioParam forwardZ;
    readonly        attribute AudioParam upX;
    readonly        attribute AudioParam upY;
    readonly        attribute AudioParam upZ;
};

2.20.1 属性

forwardX AudioParam 型, readonly
forwardX, forwardY, forwardZ パラメータは 3D 空間内のベクトルを表します。 forward ベクトルと up ベクトルはリスナーの方向を決定します。 簡単に人間についての言葉で言えば、forward ベクトルは人の鼻が指している方向です。 up ベクトルは人の頭頂が指している方向になります。 これらの値は(お互いに直角であり)線形独立と期待され、そうでなければ予期できない結果をもたらします。 これらの値をどのように解釈するかの基準要件については、空間音響セクションを参照してください。
forwardY AudioParam 型, readonly
3D デカルト空間でリスナーが向いている方向の y 成分を表します。デフォルトは 0 です。このパラメータは a-rate です。
forwardZ AudioParam 型, readonly
3D デカルト空間でリスナーが向いている方向の z 成分を表します。デフォルトは 0 です。このパラメータは a-rate です。
positionX AudioParam 型, readonly
3D デカルト空間でリスナーの位置の x 座標を表します。SpatialPannerNode オブジェクトはこの位置と個々の音源の相対的な位置関係を空間音響処理に使用します。 デフォルト値は 0 です。このパラメータは a-rate です。
positionY AudioParam 型, readonly
3D デカルト空間でリスナーの位置の y 座標を表します。デフォルト値は 0 です。このパラメータは a-rate です。
positionZ AudioParam 型, readonly
3D デカルト空間でリスナーの位置の z 座標を表します。デフォルト値は 0 です。このパラメータは a-rate です。
upX AudioParam 型, readonly
upX, upY, upZ パラメータは 3D 空間でのリスナーの "up" 方向を指示する方向ベクトルを表します。 この値がどのように解釈されるかの基準要件については、空間音響セクションを参照してください。
upY span class="idlAttrType">AudioParam 型, readonly
3D デカルト空間でリスナーの up 方向の y 成分を表します。デフォルト値は 0 です。このパラメータは a-rate です。
upZ AudioParam 型, readonly
3D デカルト空間でリスナーの up 方向の z 成分を表します。デフォルト値は 0 です。このパラメータは a-rate です。

2.21 StereoPannerNode インターフェース

入力されるオーディオストリームに対してローコストなイコールパワー・バンニングアルゴリズムによりステレオでの定位処理を行うノードを表します。このバンニング効果はステレオストリームでの定位を行う方法として一般的なものです。

    numberOfInputs  : 1
    numberOfOutputs : 1

    channelCount = 2;
    channelCountMode = "clamped-max";
    channelInterpretation = "speakers";

このノードの入力はステレオ(2チャンネル)であり増やす事はできません。より少ない、あるいは多いチャンネル数のノードから接続された場合は適宜チャンネル・アップミックスまたはダウン・ミックスされますが、もしchannelCountを2より大きな値に設定しようとする、あるいはchannelCountMode"max"に設定しようとすると NotSupportedError 例外を発生します。

このノードの出力はステレオ(2チャンネル)にハードコードされており、構成を変える事はできません。

interface StereoPannerNode : AudioNode {
    readonly        attribute AudioParam pan;
};

2.21.1 属性

pan AudioParam型, readonly
出力されるステレオイメージ中での入力信号の位置を指定します。-1ならば完全な左、+1ならば完全な右になります。デフォルト値は0で、範囲は-1から+1となります。このパラメータは a-rateです。

2.21.2 チャンネルの制限

このセクションは参考情報です。

処理について上記のような制約があるため、StereoPannerNodeの処理は2チャンネルまでのオーディオのミキシングと2チャンネルのオーディオの生成に限られています。 (訳注:それ以上のチャンネル数を扱いたい場合) ChannelSplitterNodeを使用し、GainNodeなどによるサブグラフでの中間的な処理を行ってChannelMergerNodeを通して再度結合するような処理によって任意のバンニング/ミキシングを実現する事は可能です。

2.22 ConvolverNode インターフェース

このインターフェースはインパルスレスポンスによって線形コンボリューションエフェクトを 適用する処理ノードを表すインターフェースです。

    numberOfInputs  : 1
    numberOfOutputs : 1

    channelCount = 2;
    channelCountMode = "clamped-max";
    channelInterpretation = "speakers";

このノードの入力はモノ (1 チャンネル) またはステレオ (2 チャンネル) であり増やす事はできません。 より少ないチャンネル数または多いチャンネル数のノードからの接続は、適宜アップミックスまたはダウンミックスされますが、channelCount を 2 以上の値、あるいは channelCountMode を "max" に設定しようとすると NotSupportedError 例外を発生します (MUST)。

interface ConvolverNode : AudioNode {
                    attribute AudioBuffer? buffer;
                    attribute boolean      normalize;
};

2.22.1 属性

buffer AudioBuffer 型, nullable
ConvolverNode で使用される(マルチチャンネルの場合もある)インパルスレスポンスを保持する モノ、ステレオ、または4チャンネルのAudioBufferです。 AudioBuffer は 1、2、または 4チャンネルでなくてはならずそうでない場合は NotSupportedError 例外を発生します (MUST)。 この AudioBufferAudioContext と同じサンプルレートでなくてはなりません。 そうでない場合は NotSupportedError 例外を発生します (MUST)。 この属性が設定される際に、buffernormalize 属性によってこのインパルスレスポンスが与えられた正規化の後、ConvolverNodeの構成に使われます。 この属性の初期値はnullです。
normalize boolean

buffer 属性がセットされた時に等価パワーで正規化してインパルスレスポンスをスケーリングされるかどうかを制御します。 このデフォルトの値は true で、様々なインパルスレスポンスをロードした時にコンボルバーからの出力レベルを均一化するようになっています。 もし normalizefalse に設定された場合、インパルスレスポンスの前処理/スケーリングなしでコンボリューションが行われます。 この値を変更した場合、次回に buffer 属性をセットするまで効果は現れません。

もし buffer 属性が設定された時に normalize 属性が false の場合 ConvolverNodebuffer 内のインパルスレスポンスをそのまま使用して線形コンボリューションを行います。

そうでなく、buffer 属性を設定した時に normalize 属性が true であれば、ConvolverNode は次のアルゴリズムによって、 まず buffer 内のデータのスケールドRMS-パワー解析を行い、normalizationScale を計算します:


function calculateNormalizationScale(buffer)
{
    var GainCalibration = 0.00125;
    var GainCalibrationSampleRate = 44100;
    var MinPower = 0.000125;

    // Normalize by RMS power.
    var numberOfChannels = buffer.numberOfChannels;
    var length = buffer.length;

    var power = 0;

    for (var i = 0; i < numberOfChannels; i++) {
        var channelPower = 0;
        var channelData = buffer.getChannelData(i);

        for (var j = 0; j < length; j++) {
            var sample = channelData[j];
            channelPower += sample * sample;
        }

        power += channelPower;
    }

    power = Math.sqrt(power / (numberOfChannels * length));

    // Protect against accidental overload.
    if (!isFinite(power) || isNaN(power) || power < MinPower)
        power = MinPower;

    var scale = 1 / power;

    // Calibrate to make perceived volume same as unprocessed.
    scale *= GainCalibration;

    // Scale depends on sample-rate.
    if (buffer.sampleRate)
        scale *= GainCalibrationSampleRate / buffer.sampleRate;

    // True-stereo compensation.
    if (numberOfChannels == 4)
        scale *= 0.5;

    return scale;
}
      

処理の間 ConvolverNode はこの計算された normalizationScale 値を 最終出力を得るために入力と( buffer で表される)インパルスレスポンスを処理した線形コンボリューションの結果と掛け合わせます。 あるいは、例えば入力に事前に normalizationScale をかけ合わせたり、normalizationScale を掛け合わせたバージョンのインパルスレスポンスを作るなど、 何らかの数学的に等価な演算が使用されるかも知れません。

2.22.2 入力、インパルスレスポンス、出力のチャンネル構成

実装は 1 または 2 チャンネルの入力に対する様々なリバーブエフェクトを実現するために次のような ConvolverNode のインパルスレスポンスのチャンネル構成をサポートしなくてはなりません (MUST)。

図示されている最初の図は一般的なケースで、音源が N 個の入力チャンネル、インパルスレスポンスは K 個のチャンネル、再生システムは M 個の出力チャンネルを持っています。 ConvolverNode は 1 または 2 チャンネルの入力に限られていますので、全てのケースについて対処できるわけではありません。

単一チャンネルのコンポリューションはモノラルオーディオ入力に対してモノラルインパルスレスポンスを使用してモノラル出力を得ます。 残りの図はモノラルおよびステレオ再生で N と M は 1 または 2、 K は 1 または 2 または 4 の場合です。 開発者がより複雑で任意のマトリックスを必要とするなら ChannelSplitterNode と 複数の単一チャンネルの ConvolverNode および ChannelMergerNode を使用して構成する事もできます。

reverb matrixing
図. 5 ConvolverNode を使用する際にサポートされる入出力チャンネル数

2.23 AnalyserNode インターフェース

このインターフェースはリアルタイムの周波数および時間領域の分析を可能にするノードを表します。 オーディオストリームは加工されずに入力から出力に渡されます。

    numberOfInputs  : 1
        numberOfOutputs : 1    この出力は接続されずに放置される事もある事に注意してください。

        channelCount = 1;
        channelCountMode = "max";
        channelInterpretation = "speakers";

interface AnalyserNode : AudioNode {
    void getFloatFrequencyData (Float32Array array);
    void getByteFrequencyData (Uint8Array array);
    void getFloatTimeDomainData (Float32Array array);
    void getByteTimeDomainData (Uint8Array array);
                    attribute unsigned long fftSize;
    readonly        attribute unsigned long frequencyBinCount;
                    attribute float         minDecibels;
                    attribute float         maxDecibels;
                    attribute float         smoothingTimeConstant;
};

2.23.1 属性

fftSize of type unsigned long
周波数領域の分析に使用するFFTのサイズです。これは32から32768までの2の累乗でなくてはならず、そうでなければ、IndexSizeError例外を発生します (MUST)。 デフォルトの値は2048です。大きなFFTサイズは計算量が増加する事に注意してください。
frequencyBinCount unsigned long型, readonly
FFTサイズの1/2の値です。
maxDecibels float
maxDecibels は FFT 解析データを unsigned byte 値へ変換するスケーリングの際の最大パワー値です。 デフォルトの値は -30 です。 もしこの属性の値が minDecibels より小さいか同じ値に設定された場合、IndexSizeError 例外を発生します (MUST)。
minDecibels float
minDecibelsは FFT 解析データを unsigned byte値へ変換するスケーリングの際の最少パワー値です。 デフォルトの値は -100 です。 もしこの属性の値が maxDecibels よりも大きいか同じに設定された場合、IndexSizeError 例外  を発生します (MUST)。
smoothingTimeConstant float
0 -> 1 の範囲の値で、0ならば最後の解析フレームに対して時間平均が取られない事を表します。 デフォルトの値は0.8です。 もしこの属性の値が0より小さいか1より大きい値が設定された場合、IndexSizeError 例外を発生します(MUST)。

2.23.2 メソッド

getByteFrequencyData

現在の周波数データを渡された unsigned byte 配列にコピーします。 もし配列が frequencyBinCount よりも小さい場合、余った要素は捨てられます。もし配列が frequencyBinCount よりも大きい場合、余剰の要素は無視されます。

unsigned byte 配列に格納される値は次のように計算されます。 FFT 窓関数とスムージングで説明されているように \(Y[k]\) を現在の周波数データとします。 バイトの値は、

                  $$
                    b[k] = \frac{255}{\mbox{dB}_{max} - \mbox{dB}_{min}}
                     \left(Y[k] - \mbox{dB}_{min}\right)
                  $$

ここで、\(\mbox{dB}_{min}\) は minDecibels、\(\mbox{dB}_{max}\)は maxDecibels です。 もし、\(b[k]\) が 0 から 255 の範囲外の場合、\(b[k]\) はこの範囲内にクリップされます。

パラメータNull可省略可説明
arrayUint8Array このパラメータは周波数領域の分析データをコピーする場所を示します。
戻り値: void
getByteTimeDomainData

現在のダウンミックスされた時間領域(波形)データを渡された unsigned byte 配列にコピーします。 もし、配列が fftSize よりも小さい場合、余った要素は捨てられます。 もし配列が fftSize よりも多くの要素を持つ場合、余剰の要素は無視されます。

unsigned byte 配列に格納される値は次のように計算されます。 \(x[k]\) を時間領域データとします。バイトの値、\(b[k]\) は、

              $$
                b[k] = 128(1 + x[k]).
              $$

もし \(b[k]\) が 0 から 255 の範囲外の場合、\(b[k]\) は範囲内にクリップされます。

パラメータNull可省略可説明
arrayUint8Array このパラメータは時間領域のサンプルデータをコピーする場所を示します。
戻り値: void
getFloatFrequencyData

現在の周波数データ を渡された浮動小数配列にコピーします。 もし配列が frequencyBinCount よりも小さい場合、余った要素は捨てられます。もし配列が frequencyBinCount よりも大きい場合、余剰の要素は無視されます。

周波数データの単位はdBです。

パラメータNull可省略可説明
arrayFloat32Array このパラメータは周波数領域の分析データをコピーする場所を示します。
戻り値: void
getFloatTimeDomainData

現在のダウンミックスされた時間領域(波形)データを渡された浮動小数配列にコピーします。もし配列が fftSize よりも小さい場合、余った要素は捨てられます。もし配列が fftSize よりも大きい場合、余剰の要素は無視されます。

パラメータNull可省略可説明
arrayFloat32Array このパラメータは時間領域のサンプルデータをコピーする場所を示します。
戻り値: void

2.23.3 FFT 窓関数と時間的スムージング

現在の周波数データが計算された時、次の処理が行われます:
  1. 時間領域の入力の全てのチャンネルをモノにダウンミックスします
  2. 時間領域の入力データにブラックマン窓を適用します
  3. 窓関数を通した時間領域の入力データからイマジナリとリアルの周波数データを得るため、フーリエ変換を適用します
  4. 周波数領域データに時間的スムージングの処理を行います
  5. dBへの変換を行います.

次の式では \(N\) をこの AnalyserNode.fftSize 属性とします

ブラックマン窓の適用は時間領域の入力に対して次の処理を行います。 \(n = 0, \ldots, N - 1\) に対する \(x[n]\) は時間領域のデータです。

          $$
          \begin{align*}
            \alpha &= \mbox{0.16} \\ a_0 &= \frac{1-\alpha}{2} \\
             a_1   &= \frac{1}{2} \\
             a_2   &= \frac{\alpha}{2} \\
             w[n] &= a_0 - a_1 \cos\frac{2\pi n}{N} + a_2 \cos\frac{4\pi n}{N}, \mbox{ for } n = 0, \ldots, N - 1
           \end{align*}
           $$

窓関数を通した信号 \(\hat{x}[n]\) は

            $$
              \hat{x}[n] = x[n] w[n], \mbox{ for } n = 0, \ldots, N - 1
            $$

フーリエ変換の適用 は次のようなフーリエ変換の計算から成ります。 \(X[k]\) は周波数領域の複素数データで \(\hat{x}[n]\) は上で計算された窓関数を通した時間領域のデータです。そして、

            $$
              X[k] = \sum_{n = 0}^{N - 1} \hat{x}[n] e^{\frac{-2\pi i k n}{N}}
            $$

ただし \(k = 0, \dots, N/2-1\)

周波数データの時間軸のスムージング は次のように処理されます:

そしてスムージングされた値、\(\hat{X}[k]\) は次の式で計算されます

            $$
              \hat{X}[k] = \tau\, \hat{X}_{-1}[k] + (1 - \tau)\, |X[k]|
            $$

ただし \(k = 0, \ldots, N - 1\)

dBへの変換は次の処理で行われます。 \(\hat{X}[k]\) を時間的スムージングで計算された値として:

          $$
            Y[k] = 20\log_{10}\hat{X}[k]
          $$

ただし \(k = 0, \ldots, N-1\)

この配列、\(Y[k]\) は getFloatFrequencyData によって出力の配列にコピーされます。 getByteFrequencyData に対しては、\(Y[k]\) は minDecibelsmaxDecibelsの範囲内にクリップされ、 minDecibels が 0、maxDecibels が 255 になるようにスケーリングされます。

2.24 ChannelSplitterNode インターフェース

ChannelSplitterNode は高度なアプリケーションで、 ChannelMergerNode と組み合わせて使われます。

    numberOfInputs  : 1
    numberOfOutputs : Variable N (defaults to 6) // number of "active" (non-silent) outputs is determined by number of channels in the input

    channelCountMode = "max";
    channelInterpretation = "speakers";

このインターフェースはルーティンググラフ中のオーディオストリームの個別のチャンネルにアクセスする AudioNode を表しています。 これは1つの入力と入力のオーディオストリームのチャンネル数と同じ数の"アクティブ"な出力を持ちます。 例えば、ステレオの入力ストリームが ChannelSplitterNode に接続された場合、アクティブな出力は 2 (1つは左チャンネルから、もう1つは右チャンネルから) になります。 常に合計 N 個の出力 ( AudioContext createChannelSplitter()numberOfOutputs パラメータで決まります) があり、 この値が渡されない場合のデフォルトの数は 6 になります。 "アクティブ"でないどの出力も無音を出力し、通常はどこにも接続されません。

例:

channel splitter
Fig. 6 チャンネルスプリッターの構成図

この例ではスプリッターはチャンネルの(例えば左チャンネル、右チャンネルなどの)識別はせず、単純に入力チャンネルの順序に従って出力チャンネルを分割する事に注意してください。

ChannelSplitterNode を使うアプリケーションの1つは個別のチャンネルのゲインの制御を必要とする "マトリックス・ミキシング" を行うものです。

interface ChannelSplitterNode : AudioNode {
};

2.25 ChannelMergerNode インターフェース

ChannelMergerNode は高度なアプリケーションで、ChannelSplitterNode と組み合わせて使われます。

  numberOfInputs  : Variable N (default to 6)
  numberOfOutputs : 1

  channelCount = 1;
  channelCountMode = "explicit";
  channelInterpretation = "speakers";

このインターフェースは複数のオーディオストリームからチャンネルを結合して1つのオーディオストリームにする AudioNode を表します。 これは可変数の入力 (デフォルトは 6 ) の入力を持ちますが、全ての入力を接続する必要はありません。 出力は 1 つでそのオーディオストリームは、接続された入力の数のチャンネル数を持ちます。

複数の入力を1つの出力にまとめる時、それぞれの入力は指定のミキシングルールによって1チャンネル(モノ)にダウンミックスされます。 接続されていない入力も1チャンネルの無音としてカウントされて出力されます。 入力ストリームを変える事は出力のチャンネルの順序に影響しません。

ChannelMergerNodechannelCount および channelCountMode を変更する事はできません。変更しようとした場合、InvalidState 例外を発生します (MUST)。

例:

例えば、デフォルトの ChannelMergerNode に 2 つのステレオ入力を接続した時、1 番目と 2 番目の入力はそれぞれモノラルにダウンミックスされます。 出力は 6 チャンネルのストリームで最初の 2 チャンネルが 2 つの (ダウンミックスされた) 入力に割り当てられ、残りのチャンネルは無音になります。

また、ChannelMergerNode は複数のオーディオストリームを例えば 5.1 サラウンドシステムのような決まった順序のマルチチャンネルスピーカー配列に合わせて並べるのに使用する事ができます。 マージャーは(左、右等のような)チャンネルの識別を行わず、単純に入力された順序でチャンネルを組み合わせます。

channel merger
図. 7 チャンネルマージャーの構成図
interface ChannelMergerNode : AudioNode {
};

2.26 DynamicsCompressorNode インターフェース

DynamicsCompressorNode はダイナミクス・コンプレッション効果を実装した AudioNode です。

ダイナミック・コンプレッションは音楽制作やゲーム・オーディオで非常に良く使用されるものです。 これは信号の音量が大きな部分を抑え、音量が小さな部分を持ち上げます。 全体として、より大きく、豊かで隙間のない音を作る事ができます。 これは特に、多くの個別サウンドを同時に再生するゲームと音楽アプリケーションで、全体の信号レベルを制御してスピーカーへの出力のクリッピング(歪み)を避けるために重要です。

    numberOfInputs  : 1
    numberOfOutputs : 1

    channelCount = 2;
    channelCountMode = "explicit";
    channelInterpretation = "speakers";
interface DynamicsCompressorNode : AudioNode {
    readonly        attribute AudioParam threshold;
    readonly        attribute AudioParam knee;
    readonly        attribute AudioParam ratio;
    readonly        attribute float      reduction;
    readonly        attribute AudioParam attack;
    readonly        attribute AudioParam release;
};

2.26.1 属性

attack AudioParam 型, readonly
ゲインを 10dB 減衰させるために必要な時間 (秒) です。 これは名目上 0 から 1 の範囲を持ち、デフォルトの value は 0.003 です。
knee AudioParam 型, readonly
threadhold を超えた部分の範囲を表すデシベル値で、この範囲ではカーブが "ratio" まで滑らかに変化します。 このデフォルトの value は 0 から 40 の範囲中、 30 になっています。
ratio AudioParam 型, readonly
出力が 1dB 変化するための入力の dB の変化量です。 このデフォルトの value は、 1 から 20 の範囲中 12 になっています。
reduction float 型, readonly
メーターの表示のために使用するリードオンリーのデシベル値で、信号に対するコンプレッサーの動作による、現在のゲインの減衰量を表します。 もし信号が供給されていない場合この値は 0 (ゲイン減衰なし)になります。
release AudioParam 型, readonly
ゲインを 10dB 増加させるために必要な時間 (秒) です。 これは名目上 0 から 1 の範囲を持ち、デフォルトの value は 0.250 です。
threshold AudioParam 型, readonly
これを超えた時にコンプレッション動作を開始するデシベル値です。 デフォルトの value は -100 から 0 の範囲中、 -24 になっています。

2.27 BiquadFilterNode インターフェース

BiquadFilterNode は非常に一般的な低次フィルタを実装した AudioNode です。

低次フィルタは基本的なトーンコントロール(バス、ミドル、トレブル)やグラフィックイコライザーやより高度なフィルタを構成するブロックです。 複数の BiquadFilterNode フィルタを組み合わせてより複雑なフィルタを作る事もできます。 フィルタのパラメータの frequency などを時間と共に変化させてフィルタスイープやその他の効果を得る事もできます。 それぞれの BiquadFilterNode は下のIDLで紹介する一般的なフィルタの型のうちの1つに設定する事ができます。 デフォルトのフィルタの型は "lowpass" です。

frequencydetune はどちらも a-rate パラメータで computedFrequency の値を決定するために一緒に使用されます:

  computedFrequency(t) = frequency(t) * pow(2, detune(t) / 1200)
    numberOfInputs  : 1
    numberOfOutputs : 1

    channelCountMode = "max";
    channelInterpretation = "speakers";

出力のチャンネル数は常に入力のチャンネル数と同じになります。

enum BiquadFilterType {
    "lowpass",
    "highpass",
    "bandpass",
    "lowshelf",
    "highshelf",
    "peaking",
    "notch",
    "allpass"
};
列挙値の説明
lowpass

ローパスフィルタは カットオフ周波数より低い周波数をそのまま通し、カットオフよりも高い周波数を減衰させます。これは標準的な2次の レゾナントローパスフィルタの実装で、 12dB/オクターブ のロールオフを持ちます。

frequency
カットオフ周波数です。
Q
カットオフ周波数にどれだけピークを付けて共振させるかを制御します。 大きな値はより強く共振させます。 このフィルタタイプではこの値は伝統的な従来の Q ではなく、デシベルで表される共振の値である事に注意してください。
gain
このフィルタのタイプでは使用しません。
highpass

ハイパスフィルタはローパスフィルタの反対の機能を持ちます。 カットオフ周波数よりも高い周波数をそのまま通し、カットオフよりも低い周波数を減衰させます。 これは標準的な2次レゾナントハイパスフィルタの実装で、 12dB/オクターブ のロールオフを持ちます。

frequency
これより低い周波数を減衰させるカットオフ周波数です。
Q
カットオフ周波数にどれだけピークを付けて共振させるかを制御します。 大きな値はより強く共振させます。 このフィルタタイプではこの値は伝統的な従来の Q ではなく、デシベルで表される共振の値である事に注意してください。
gain
このフィルタのタイプでは使用しません。
bandpass

バンドパスフィルタはある範囲の周波数をそのまま通し、この周波数範囲より上または下の周波数を減衰させます。 これは2次のバンドパスフィルタを実装しています。

frequency
周波数範囲の中心周波数です。
Q
周波数範囲の幅を制御します。この幅は Q の値が増加すると狭くなります。
gain
このフィルタのタイプでは使用しません。
lowshelf

ローシェルフフィルタは全ての周波数を通しますが、低い周波数だけを増幅(または減衰)させます。 これは2次のローシェルフフィルタを実装しています。

frequency
増幅(または減衰)させる上限の周波数です。
Q
このフィルタのタイプでは使用しません。
gain
dB で表した増幅率です。もしこの値が負ならばその周波数は減衰されます。
highshelf

ハイシェルフフィルタはローシェルフフィルタとは反対に、すべての周波数を通しますが高い周波数だけを増幅します。 これは2次のハイシェルフフィルタを実装しています。

frequency
増幅(または減衰)させる下限の周波数です。
Q
このフィルタのタイプでは使用しません。
gain
dB で表した増幅率です。もしこの値が負ならばその周波数は減衰されます。
peaking

ピーキングフィルタは全ての周波数を通しますが、ある周波数の範囲だけが増幅(または減衰)されます。

frequency
増幅される中心の周波数です。
Q
増幅される周波数の幅を制御します。値が大きいと幅は狭くなります。
gain
dB で表した増幅率です。もしこの値が負ならばその周波数は減衰されます。
notch

ノッチフィルタ (バンドストップまたはバンドリジェクション・フィルタとも呼ばれます) は、バンドパスフィルタの逆の機能です。 ある周波数を除く全ての周波数を通します。

frequency
ノッチを適用する中心の周波数です。
Q
減衰させる周波数の幅を制御します。大きな値は幅が狭い事を意味します。
gain
このフィルタのタイプでは使用しません。
allpass

オールパスフィルタは全ての周波数を通しますが、周波数の変化に対して位相が変化します。 これは2次のオールパスフィルタを実装しています。

frequency
位相変化が発生する中心の周波数です。別の見方では群遅延が最大になる周波数です。
Q
中心周波数での位相変化がどれくらい急峻であるかを制御します。値が大きいと、より急峻な位相変化で大きな群遅延である事を意味します。
gain
このフィルタのタイプでは使用しません。

BiquadFilterNode の属性は全て a-rateAudioParam です。

interface BiquadFilterNode : AudioNode {
                    attribute BiquadFilterType type;
    readonly        attribute AudioParam       frequency;
    readonly        attribute AudioParam       detune;
    readonly        attribute AudioParam       Q;
    readonly        attribute AudioParam       gain;
    void getFrequencyResponse (Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse);
};

2.27.1 属性

Q AudioParam 型, readonly
Q ファクターはデフォルト値は 1 で名目上の範囲は 0.0001 から 1000 です。
detune AudioParam 型, readonly
デチューン値は周波数に対してセントで表され、デフォルト値は 0 です。
frequency AudioParam 型, readonly
BiquadFilterNode が働く周波数で Hz で表されます。デフォルト値は 350Hz で、名目上の範囲は 10Hz から ナイキスト周波数の半分になります。
gain AudioParam 型, readonly
gain はデフォルト値は 0 で、名目上の範囲は -40 から 40 です。
type BiquadFilterType
この BiquadFilterNode のタイプです。これ以外のパラメータの正確な意味は type の値に依存します。

2.27.2 メソッド

getFrequencyResponse

現在のフィルタパラメータの設定から指定の周波数に対する応答特性を計算します。 3 つのパラメータは同じ長さの Float32Array でなくてはなりません (MUST)。そうでない場合は InvalidAccessError 例外を発生します (MUST)。

周波数応答は、現在の処理ブロックに対応した AudioParam によって計算されて返されなくてはなりません (MUST)。

パラメータNull可省略可説明
frequencyHzFloat32Array

このパラメータは応答特性を計算する周波数の配列を指定します。

magResponseFloat32Array

パラメータはリニア振幅特性の値を受け取る配列を指定します。

もし frequencyHz パラメータが [0; sampleRate/2] の範囲にない場合 (ここで sampleRateAudioContextsampleRate 属性の値です)、対応する magResponse 配列の同じインデックスには NaN が格納されなくてはなりません (MUST)。

phaseResponseFloat32Array

パラメータはラジアン単位の位相特性を受け取る配列を指定します。

もし frequencyHz パラメータが [0; sampleRate/2] の範囲にない場合 (ここで sampleRateAudioContextsampleRate 属性の値です)、対応する phaseResponse 配列の同じインデックスには NaN が格納されなくてはなりません (MUST)。

戻り値: void

2.27.3 フィルター特性

BiquadFilterNode を実装する方法には複数あり、それぞれ非常に異なる特性を持っています。このセクションの式は、「準拠した実装」が実装すべきフィルターについて記述しています (MUST)。これらの式はAudio EQ Cookbookで見られる式を基にしています。

BiquadFilterNode の実装によるフィルターの伝達関数は:

  $$
  H(z) = \frac{\frac{b_0}{a_0} + \frac{b_1}{a_0}z^{-1} + \frac{b_2}{a_0}z^{-2}}
              {1+\frac{a_1}{a_0}z^{-1}+\frac{a_2}{a_0}z^{-2}}
  $$

フィルターの初期状態は 0 です。

上記の伝達関数内の係数はそれぞれのノードタイプによって異なります。 BiquadFilterNodeAudioParamcomputedValue に基づいて次の中間変数が計算のために必要になります。
  • \(F_s\) をこの AudioContextsampleRate の値とします。
  • \(f_0\) を computedFrequency の値とします。
  • \(G\) を gain AudioParam の値とします。
  • \(Q\) をQ AudioParam の値とします。
  • これらより
    $$
    \begin{align*}
      A        &= 10^{\frac{G}{40}} \\
      \omega_0 &= 2\pi\frac{f_0}{F_s} \\
      \alpha_Q &= \frac{\sin\omega_0}{2Q} \\
      \alpha_B &= \frac{\sin\omega_0}{2} \sqrt{\frac{4-\sqrt{16-\frac{16}{G^2}}}{2}} \\
      S        &= 1 \\
      \alpha_S &= \frac{\sin\omega_0}{2}\sqrt{\left(A+\frac{1}{A}\right)\left(\frac{1}{S}-1\right)+2}
    \end{align*}
    $$
    
    
各フィルタータイプに対応する 6 つの係数 (\(b_0, b_1, b_2, a_0, a_1, a_2\)) は:
lowpass
                $$
                  \begin{align*}
                    b_0 &= \frac{1 - \cos\omega_0}{2} \\
                    b_1 &= 1 - \cos\omega_0 \\
                    b_2 &= \frac{1 - \cos\omega_0}{2} \\
                    a_0 &= 1 + \alpha_B \\
                    a_1 &= -2 \cos\omega_0 \\
                    a_2 &= 1 - \alpha_B
                  \end{align*}
                $$

highpass
                  $$
                    \begin{align*}
                      b_0 &= \frac{1 + \cos\omega_0}{2} \\
                      b_1 &= -(1 + \cos\omega_0) \\
                      b_2 &= \frac{1 + \cos\omega_0}{2} \\
                      a_0 &= 1 + \alpha_B \\
                      a_1 &= -2 \cos\omega_0 \\
                      a_2 &= 1 - \alpha_B
                    \end{align*}
                  $$

bandpass
              $$
                \begin{align*}
                  b_0 &= \alpha_Q \\
                  b_1 &= 0 \\
                  b_2 &= -\alpha_Q \\
                  a_0 &= 1 + \alpha_Q \\
                  a_1 &= -2 \cos\omega_0 \\
                  a_2 &= 1 - \alpha_Q
                \end{align*}
              $$

notch
                $$
                  \begin{align*}
                    b_0 &= 1 \\
                    b_1 &= -2\cos\omega_0 \\
                    b_2 &= 1 \\
                    a_0 &= 1 + \alpha_Q \\
                    a_1 &= -2 \cos\omega_0 \\
                    a_2 &= 1 - \alpha_Q
                  \end{align*}
                $$

allpass
                $$
                  \begin{align*}
                    b_0 &= 1 - \alpha_Q \\
                    b_1 &= -2\cos\omega_0 \\
                    b_2 &= 1 + \alpha_Q \\
                    a_0 &= 1 + \alpha_Q \\
                    a_1 &= -2 \cos\omega_0 \\
                    a_2 &= 1 - \alpha_Q
                  \end{align*}
                $$

peaking
                $$
                  \begin{align*}
                    b_0 &= 1 + \alpha_Q\, A \\
                    b_1 &= -2\cos\omega_0 \\
                    b_2 &= 1 - \alpha_Q\,A \\
                    a_0 &= 1 + \frac{\alpha_Q}{A} \\
                    a_1 &= -2 \cos\omega_0 \\
                    a_2 &= 1 - \frac{\alpha_Q}{A}
                  \end{align*}
                $$

lowshelf
                $$
                  \begin{align*}
                    b_0 &= A \left[ (A+1) - (A-1) \cos\omega_0 + 2 \alpha_S \sqrt{A})\right] \\
                    b_1 &= 2 A \left[ (A-1) - (A+1) \cos\omega_0 )\right] \\
                    b_2 &= A \left[ (A+1) - (A-1) \cos\omega_0 - 2 \alpha_S \sqrt{A}) \right] \\
                    a_0 &= (A+1) + (A-1) \cos\omega_0 + 2 \alpha_S \sqrt{A} \\
                    a_1 &= -2 \left[ (A-1) + (A+1) \cos\omega_0\right] \\
                    a_2 &= (A+1) + (A-1) \cos\omega_0 - 2 \alpha_S \sqrt{A})
                  \end{align*}
                $$

highshelf
                $$
                  \begin{align*}
                    b_0 &= A\left[ (A+1) + (A-1)\cos\omega_0 + 2\alpha_S\sqrt{A} )\right] \\
                    b_1 &= -2A\left[ (A-1) + (A+1)\cos\omega_0 )\right] \\
                    b_2 &= A\left[ (A+1) + (A-1)\cos\omega_0 - 2\alpha_S\sqrt{A} )\right] \\
                    a_0 &= (A+1) - (A-1)\cos\omega_0 + 2\alpha_S\sqrt{A} \\
                    a_1 &= 2\left[ (A-1) - (A+1)\cos\omega_0\right] \\
                    a_2 &= (A+1) - (A-1)\cos\omega_0 - 2\alpha_S\sqrt{A}
                  \end{align*}
                $$

2.28 IIRFilterNode インターフェース

IIRFilterNode は汎用の IIR フィルターを実装した AudioNodeです。 一般的には高次のフィルターについては次のような理由で BiquadFilterNode を利用するのが最善です。

しかしながら奇数次フィルターは作成できないため、もしそのようなフィルターが必要でオートメーションが不要ならば IIR フィルターが適切かもしれません。

一度作成された後、 IIR フィルターの係数は変更する事ができません。

    numberOfInputs  : 1
    numberOfOutputs : 1

    channelCountMode = "max";
    channelInterpretation = "speakers";

出力のチャンネル数は常に入力のチャンネル数と同じになります。

interface IIRFilterNode : AudioNode {
    void getFrequencyResponse (Float32Array frequencyHz, Float32Array magResponse, Float32Array phaseResponse);
};

2.28.1 メソッド

getFrequencyResponse

与えられた現在のフィルターの設定で、指定の周波数における周波数応答を計算します。

ParameterTypeNullable省略可Description
frequencyHzFloat32Array このパラメータは応答を計算する周波数の配列を指定します。
magResponseFloat32Array このパラメータはリニア振幅応答の出力結果を受け取る配列を指定します。 もしこの配列が frequencyHz よりも小さい場合、NotSupportedError 例外を発生します (MUST)。
phaseResponseFloat32Array このパラメータはラジアンでの位相応答の出力結果を受け取る配列を指定します。 もしこの配列が frequencyHz よりも小さい場合、NotSupportedError 例外を発生します (MUST)。
戻り値: void

2.28.2 Filter 定義

createIIRFilterで指定される feedforward 係数を\(b_m\)、 feedback を\(a_n\)とします。 すると一般的な IIR フィルターの 伝達関数は次のように与えられます

            $$
              H(z) = \frac{\sum_{m=0}^{M} b_m z^{-m}}{\sum_{n=0}^{N} a_n z^{-n}}
            $$

ここで、\(M + 1\) は \(b\) 配列の長さで、 \(N + 1\) は \(a\) 配列の長さです。 係数 \(a_0\) は 0 にはできません。 少なくとも1つの \(b_m\) が非0 でなくてはなりません。

同じように、時間領域の式については:

            $$
              \sum_{k=0}^{N} a_k y(n-k) = \sum_{k=0}^{M} b_k x(n-k)
            $$

フィルターの初期状態は全て 0 になっています。

2.29 WaveShaperNode インターフェース

WaveShaperNode は非線形の歪み効果を実装したAudioNode です。

非線形ウェーブシェイピング歪みは微妙な非線形ウォーミングやはっきりしたディストーションの両方のエフェクトで一般的に使用されています。 任意の非線形シェイピング曲線を指定する事ができます

    numberOfInputs  : 1
    numberOfOutputs : 1

    channelCountMode = "max";
    channelInterpretation = "speakers";

出力のチャンネル数は常に入力のチャンネル数に同じです。

列挙値の説明
none オーバーサンプリングを行いません
2x 2 倍オーバーサンプリングを行います
4x 4 倍オーバーサンプリングを行います
enum OverSampleType {
    "none",
    "2x",
    "4x"
};

interface WaveShaperNode : AudioNode { attribute Float32Array? curve; attribute OverSampleType oversample; };

2.29.1 属性

curve Float32Array 型, nullable

ウェーブシェイピング・エフェクトで使用されるシェイピング曲線です。 入力信号は名目上 [-1 ; +1] の範囲になります。 この範囲内のそれぞれの入力サンプルはシェイピング曲線にインデックスされ、信号レベル0が配列の要素が奇数個の場合は中央の値、そうでなく要素が偶数個の場合はもっとも中心に近い2つの値が補間された値になります。 -1よりも小さい全てのサンプルは曲線配列の最初の値に対応します。 +1よりも大きい全てのサンプルは曲線配列の最後の値に対応します。

実装は曲線の配列の隣接した値から直線補間を行わなくてはなりません。 curve 属性の初期値はnullで、これは WaveShaperNode は入力を変更せずにそのまま出力する事を意味します。

曲線の値は [-1; 1] の範囲に広がっています。 これは curve の値が偶数個の場合は信号 0 に対応する値を持っていない事を意味し、curve が奇数個の値の場合は信号 0 に対応する値を持っている事を意味します。

もしこの属性が長さが 2 より小さい Float32Array に設定されると InvalidStateError 例外を発生します (MUST)。

この属性が設定された時、WaveShaperNode によって曲線の内部的なコピーが作成されます。 それ以降の属性の設定に使用した配列の変更は効果が反映されません: 曲線を変更するには属性を再度設定する必要があります。

oversample OverSampleType

シェイピング曲線に(行うならば)どのようなオーバーサンプリングを行うかを指定します。 デフォルト値は "none" で、曲線は直接入力サンプルに適用される事を意味します。 値、"2x" または "4x" は幾らかのエイリアシングを避けて処理の品質を向上させ、"4x" が最も良い品質となります。 アプリケーションによっては非常に高精度なシェイピング曲線を得るためにオーバーサンプリングを使用しない方が良い場合もあります。

"2x" または "4x" の値は次のステップを実行しなくてはならない事を意味します:

  1. 入力のサンプルを AudioContext のサンプルレートの 2x または 4x にアップサンプリングします。そのため、それぞれの処理ブロックは 128 サンプルから 256 (2x の場合) または 512 (4x の場合) サンプルになります。
  2. シェイピング曲線を適用します。
  3. 結果を AudioContext のサンプルレートにダウンサンプリングして戻します。つまり処理された 256 (または 512)のサンプルから 最終的な結果の 128 サンプルを生成します。

正確なアップサンプリングおよびダウンサンプリングフィルターは定められておらず、(低エイリアシング等の)音の品質、低レイテンシー、パフォーマンス等をチューニングする事もできます。

2.30 OscillatorNode インターフェース

OscillatorNode は周期的な波形を発生するオーディオソースを表しています。 これは一般的に使われる幾つかの波形に設定する事ができます。 更にこれは PeriodicWave オブジェクトを使って任意の周期波形に設定する事が可能です。

オシレータは音の合成において一般的な基本構成ブロックです。 OscillatorNode は start() メソッドで指定された時刻に音の発生を開始します。

数学的に言えば、連続した時間の周期波形は周波数領域で考えた場合、非常に高い (あるいは無限に高い) 周波数情報を持つ事ができます。 この波形があるサンプルレートの離散時間のデジタルオーディオ信号としてサンプリングされる場合、波形をデジタル化する前にナイキスト周波数 (サンプリング周波数の半分) よりも高い高周波数成分の除去 (フィルタで取り除く事) を考慮しなくてはなりません。 これを行わない場合、 (ナイキスト周波数よりも) 高い周波数のエイリアスがナイキスト周波数よりも低い周波数に鏡像として折り返されます。 多くの場合、これは音として聴こえる好ましくないノイズを引き起こします。 これはオーディオ DSP における基本的で良く知られている原理です。

このエイリアスを避けるため、実装に使う事のできる幾つかの実践的な手段があります。 しかしこれらの手段によらず、理想的な離散時間のデジタルオーディオ信号は数学的には完全に定義されます。 ( CPU の負荷という意味で) 実装のコスト対、理想への忠実性というトレードオフが実装上の問題になります。

実装はこの理想を達成するためにいくらかの考慮をする事が期待されますが、ローエンド・ハードウェアでは低品質ローコストな手段を考慮する事も合理的です。

.frequency と .detune はどちらも a-rate パラメータで、 computedFrequency の値を決定するために一緒に使われます:

  computedFrequency(t) = frequency(t) * pow(2, detune(t) / 1200)

OscillatorNode の各時刻での瞬間的な位相は computedFrequency を時間で積分したものになります。

  numberOfInputs  : 0
  numberOfOutputs : 1 (mono output)
enum OscillatorType {
    "sine",
    "square",
    "sawtooth",
    "triangle",
    "custom"
};
列挙値の説明
sine サイン波
square デューティ比 0.5 の矩形波
sawtooth 鋸歯状波
triangle 三角波
custom カスタム周期波形
interface OscillatorNode : AudioNode {
                    attribute OscillatorType type;
    readonly        attribute AudioParam     frequency;
    readonly        attribute AudioParam     detune;
    void start (optional double when = 0);
    void stop (optional double when = 0);
    void setPeriodicWave (PeriodicWave periodicWave);
                    attribute EventHandler   onended;
};

2.30.1 属性

detune AudioParam 型, readonly
(セントで表される) デチューン値で、これは frequency を与えられた量だけオフセットします。 デフォルトの value は 0 です。 このパラメータは a-rate です。
frequency AudioParam 型, readonly
(Hz:ヘルツで表される) 周期波形の周波数で、そのデフォルトの value は 440 です。このパラメータは a-rate です。
onended EventHandler
OscillatorNode にディスパッチされる ended イベントに対する ( HTML[HTML]で記述される) EventHandler を設定するために使われる属性です。 OscillatorNode が再生を終了した時 (例えば停止時刻に到達した時)、 (HTML[HTML]で記述される) イベントタイプ Event が イベントハンドラにディスパッチされます。
type OscillatorType
周期波形の形状です。 "custom" 以外の波形の定数値は直接設定する事ができます。(訳注: "custom" を直接設定しようとすると)そうすると InvalidStateError 例外を発生します (MUST)。 カスタム波形を設定するには setPeriodicWave() メソッドを使用する事ができ、それによってこの属性は "custom" に設定されます。 デフォルト値は "sine" です。属性が設定された時、オシレータの位相は保存されなくてはなりません (MUST)。

2.30.2 メソッド

setPeriodicWave
PeriodicWave で与えられる任意のカスタム周期波形を設定します。
パラメータNull可省略可説明
periodicWavePeriodicWave
戻り値: void
start
AudioBufferSourceNode で定義されている when と同じです。(訳注:少し文章がおかしいですが、メソッドの機能自体もAudioBufferSourceNodeと同じです)
パラメータNull可省略可説明
whendouble = 0
戻り値: void
stop
AudioBufferSourceNode で定義されているものと同じです。
パラメータNull可省略可説明
whendouble = 0
戻り値: void

2.30.3 基本波形の位相

様々なオシレータのタイプのための理想的な数学的波形をここで定義します。 概要としては全ての波形は時間 0 の時に正の傾きを持つ奇関数として数学的に定義されます。 実際にオシレータで生成される波形はエイリアシングの影響を避けるため少し異なったものになります。

"sine"
サイン波のオシレータ波形は:
                $$
                  x(t) = \sin t
                $$.

"square"
矩形波のオシレータ波形は:
                $$
                  x(t) = \begin{cases}
                         1 & \mbox{for } 0≤ t < \pi \\
                         -1 & \mbox{for } -\pi < t < 0.
                         \end{cases}
                $$

"sawtooth"
鋸歯状波オシレータの波形は上昇波形です:
                $$
                  x(t) = \frac{t}{\pi} \mbox{ for } -\pi < t ≤ \pi;
                $$

"triangle"
三角波オシレータの波形は:
                $$
                  x(t) = \begin{cases}
                           \frac{2}{\pi} t & \mbox{for } 0 ≤ t ≤ \frac{\pi}{2} \\
                           1-\frac{2}{\pi} (t-\frac{\pi}{2}) & \mbox{for }
                           \frac{\pi}{2} < t ≤ \pi.
                         \end{cases}
                $$

波形は周期 \(2\pi\) の奇関数である事を使用して、これを全ての \(t\) に拡張します。

2.31 PeriodicWave インターフェース

PeriodicWave は OscillatorNode で使用される任意の周期波形を表します。 詳細は createPeriodicWave() 、 および setPeriodicWave() を参照してください。

interface PeriodicWave {
};

2.31.1 PeriodicWaveConstraints

PeriodicWaveConstraints ディクショナリは波形が正規化されるかどうかを指定するために使用されます。
dictionary PeriodicWaveConstraints {
             boolean disableNormalization = false;
};
2.31.1.1 ディクショナリ PeriodicWaveConstraints メンバー
disableNormalization boolean 型, デフォルト値は false
周期波形が正規化されるかどうかを制御します。もし true ならば波形は正規化されません。そうでなければ波形は正規化されます。

2.31.2 波形の生成

createPriodicWave() メソッドは PeriodicWave のフーリエ係数を指定する2つの配列を引数とします。 \(a\) と \(b\) を長さ \(L\) のリアルとイマジナリの配列とします。 そして時間領域の基本的な波形、 \(x(t)\) は次のように計算されます:

            $$
              x(t) = \sum_{k=1}^{L-1} \left(a[k]\cos2\pi k t + b[k]\sin2\pi k t\right)
            $$

これが基本的な (正規化されていない) 波形になります。

2.31.3 波形の正規化

デフォルトでは前のセクションで定義された波形は正規化され、最大値が 1 になります。 正規化は次のように行われます。

まず以下を求めます。

          $$
            \tilde{x}(n) = \sum_{k=1}^{L-1} \left(a[k]\cos\frac{2\pi k n}{N} + b[k]\sin\frac{2\pi k n}{N}\right)
          $$

ここで、 \(N\) は2の累乗です。(注: \(\tilde{x}(n)\) は便宜上逆 FFT を使用して計算されています) 固定値の正規化係数 \(f\) は次のように計算されます:

            $$
              f = \max_{n = 0, \ldots, N - 1} |\tilde{x}(n)|
            $$

結果、実際の正規化された波形 \(\hat{x}(n)\) は

            $$
              \hat{x}(n) = \frac{\tilde{x}(n)}{f}
            $$

固定値の正規化係数は全ての生成された波形に適用しなくてはなりません。

2.31.4 オシレータ係数

組み込み済みのオシレータタイプは PeriodicWave オブジェクトを使用して作られます。 完全性のため、それぞれの組み込みオシレータタイプのための PeriodicWave の係数をここに定めます。

次の記述において、 \(a\) は createPeriodicWave() で使用するリアル係数の配列で \(b\) はイマジナリ係数の配列です。 全てのケースで波形は奇関数のため、全ての \(n\) に対して \(a[n] = 0\) となります。 また、全てのケースで \(b[0] = 0\) です。そのため、 \(n \ge 1\) の \(b[n]\) だけが以下に規定されています。

"sine"
                  $$
                    b[n] = \begin{cases}
                             1 & \mbox{for } n = 1 \\
                             0 & \mbox{otherwise}
                           \end{cases}
                  $$

"square"
                  $$
                    b[n] = \frac{2}{n\pi}\left[1 - (-1)^n\right]
                  $$

"sawtooth"
                $$
                  b[n] = (-1)^{n+1} \dfrac{2}{n\pi}
                $$

"triangle"
                  $$
                    b[n] = \frac{8\sin\dfrac{n\pi}{2}}{(\pi n)^2}
                  $$

2.32 MediaStreamAudioSourceNode インターフェース

このインターフェースは MediaStream からのオーディオソースを表します。 MediaStream からの最初の AudioMediaStreamTrack がオーディオソースとして使用されます。 これらのインターフェースは [mediacapture-streams] に記述されています。

    numberOfInputs  : 0
    numberOfOutputs : 1

出力のチャンネル数は、AudioMediaStreamTrack のチャンネル数に対応します。 もし有効なオーディオトラックがない場合、1 チャンネルの無音が出力されます。

interface MediaStreamAudioSourceNode : AudioNode {
};

2.33 MediaStreamAudioDestinationNode インターフェース

このインターフェースは 1 つの AudioMediaStreamTrack を持つ MediaStream を表すオーディオの出力地点となります。 この MediaStream はノードが作成された時点で作られ、 stream 属性を通じてアクセスする事ができます。 このストリームは getUserMedia() によって得られた MediaStream と同様の方法で使う事ができ、 例えば、 RTCPeerConnection ([webrtc]で記述されています) の addStream() メソッドを使って、リモート・ピアに送る事ができます。

    numberOfInputs  : 1
    numberOfOutputs : 0

    channelCount = 2;
    channelCountMode = "explicit";
    channelInterpretation = "speakers";

入力のチャンネル数はデフォルトで 2 (ステレオ)です。 入力への全ての接続は入力チャンネル数にアップミックス/ダウンミックスされます。

interface MediaStreamAudioDestinationNode : AudioNode {
    readonly        attribute MediaStream stream;
};

2.33.1 属性

stream MediaStream 型, readonly
ノード自身と同じチャンネル数の 1 つの AudioMediaStreamTrack を持つ MediaStream です。

3. ミキサーゲイン構成

このセクションは参考情報です。

背景

オーディオ処理グラフについて考える時に重要な事の1つが、各ポイントにおけるゲイン(音量)をどのように調整するかです。 例えば、標準的なミキサー卓モデルの場合、それぞれの入力バスは、プリゲイン、ポストゲイン、センドゲインを持っています。 サブミックスとマスター出力バスもまたゲインコントロールを持っています。 ここで述べるゲインコントロールは他のアーキテクチャーと同じように標準的なミキサー卓に使用する事ができます。

3.1 サミング入力

AudioNode の入力は複数の出力からの接続を受け付ける能力を持っています。 入力はそれぞれの出力を他と足し合わせる、ユニティ・ゲインのサミング接続として振舞います(訳注:複数の信号をそのまま足し合わせる事を指します)。:

unity gain summing junction
図. 8 ソース 1 とソース 2 がディスティネーションの入力で足し合わされて出力される図

各出力のチャンネルレイアウトが一致しない場合は、ミキシング規則に従ってミックス(通常はアップミックス)が行われます。

オーディオグラフ中のダイナミックレンジを最大化するため AudioNode の入力または出力にクリッピングは適用されません。

3.2 ゲインコントロール

多くの場合、それぞれの出力信号のゲインを制御できる事が重要です。 GainNode によってこのコントロールが可能です:

mixer architecture new
図. 9 それぞれのボイスに音量制御を付加した図

ユニティ・ゲイン・サミング接続と GainNode という2つの概念を使う事で、簡単な、あるいは複雑なミキシングのシナリオを構成する事が可能です。

3.3 例: センドバス付ミキサー

複数のセンドとサブミックスを含むルーティングのシナリオでは、ミキサーへのそれぞれの接続について音量または "ゲイン" のわかりやすい制御が必要です。 基本的なレコーディングスタジオに置かれている電子機器の一番単純なものでさえ、そのようなルーティング・トポロジーは非常に一般的に使われます。

これは 2 つのセンド・ミキサーと 1 つののメインミキサーの例です。 可能ではありますが、単純化のため、プリゲインコントロールとインサート・エフェクトは図示していません。:

mixer gain structure
図. 10 センドバス付きミキサーの全体図

この図では省略した書き方を使っています。 "send 1"、"send 2"、"main bus" は実際には AudioNode に入力されますがここではサミングバスとして書かれており、交点にある g2_1、g3_1、などが、あるミキサー上のあるソースの "ゲイン" または音量を表します。 このゲインをコントロールするために GainNode が使われます。:

上の図を JavaScript で構築したものがこれになります:

例 8
var context = 0;
var compressor = 0;
var reverb = 0;
var delay = 0;
var s1 = 0;
var s2 = 0;

var source1 = 0;
var source2 = 0;
var g1_1 = 0;
var g2_1 = 0;
var g3_1 = 0;
var g1_2 = 0;
var g2_2 = 0;
var g3_2 = 0;

// Setup routing graph
function setupRoutingGraph() {
    context = new AudioContext();

    compressor = context.createDynamicsCompressor();

    // Send1 effect
    reverb = context.createConvolver();
    // Convolver impulse response may be set here or later

    // Send2 effect
    delay = context.createDelay();

    // Connect final compressor to final destination
    compressor.connect(context.destination);

    // Connect sends 1 & 2 through effects to main mixer
    s1 = context.createGain();
    reverb.connect(s1);
    s1.connect(compressor);

    s2 = context.createGain();
    delay.connect(s2);
    s2.connect(compressor);

    // Create a couple of sources
    source1 = context.createBufferSource();
    source2 = context.createBufferSource();
    source1.buffer = manTalkingBuffer;
    source2.buffer = footstepsBuffer;

    // Connect source1
    g1_1 = context.createGain();
    g2_1 = context.createGain();
    g3_1 = context.createGain();
    source1.connect(g1_1);
    source1.connect(g2_1);
    source1.connect(g3_1);
    g1_1.connect(compressor);
    g2_1.connect(reverb);
    g3_1.connect(delay);

    // Connect source2
    g1_2 = context.createGain();
    g2_2 = context.createGain();
    g3_2 = context.createGain();
    source2.connect(g1_2);
    source2.connect(g2_2);
    source2.connect(g3_2);
    g1_2.connect(compressor);
    g2_2.connect(reverb);
    g3_2.connect(delay);

    // We now have explicit control over all the volumes g1_1, g2_1, ..., s1, s2
    g2_1.gain.value = 0.2;  // For example, set source1 reverb gain

    // Because g2_1.gain is an "AudioParam",
    // an automation curve could also be attached to it.
    // A "mixing board" UI could be created in canvas or WebGL controlling these gains.
}

4. 動的ライフタイム

4.1 背景

このセクションは参考情報です。 基準情報としての要求事項については AudioContextのライフタイム および AudioNodeのライムタイム を参照してください。

静的なルーティング設定の構築が可能である事に加えて、動的に割り当てられて限られたライフタイムを持つ「ボイス」に対して特別なエフェクトのルーティングを行う事が可能である必要があります。 この議論のためにこれらの短期間だけ存在する音を "ノート" と呼びます。 多くのオーディオアプリケーションがこのノートという考え方を組み込んでおり、例として、ドラムマシン、シーケンサー、多くのワンショットの音がゲームプレイに従ってトリガーされる3Dゲームがあります。

従来のソフトウェアシンセサイザーでは、ノートは使用可能なリソースのプールから動的に割り当てられ、解放されます。 ノートは MIDI ノートオン・メッセージを受信すると割り当てられます。 それはそのノートが発音を終了するか、(もしループ再生でなければ)サンプルデータの終わりに達した時に解放されます。 それは、エンベロープで値が 0 のサスティンフェーズに達したり、 MIDI ノートオフ・メッセージによってエンベロープのリリースフェーズに達したりする事で発生します。 MIDI ノートオフの場合には、そのノートは即時ではなく、リリースエンベロープが終了した時点で解放されます。 どの時間においても、多数のノートが再生中であり、常に新しいノートがルーティンググラフに追加され、古いノートが解放されながらそのノートの組は常に変化しています。

オーディオシステムはそれぞれの "ノート" イベントに対して、ルーティンググラフの一部分の切り落としを自動的に行います。 1 つの "ノート" は1つの AudioBufferSourceNode で表され、それは直接、他の処理ノードに接続さする事ができます。 ノートが再生を終了した時、コンテキストは自動的にその AudioBufferSourceNode への参照を解放します。 それによって、そのノードが接続されていた先の全てのノードへの参照が解放され、という風に続きます。 そのノードは自動的にグラフから切断され、全ての参照が無くなった時点で破棄されます。 グラフ内の、長時間存在して動的なボイスから共有されるノードは明示的に管理する事ができます。 複雑なように聞こえますが、これらは全て、特にJavaScriptでハンドリングする必要なく、自動的に行われます。

4.2

dynamic allocation
図. 11 グラフの一部が先にリリースされる図

ローパスフィルタ、パンナー、 2 番目のゲインノードがワンショットの音から直接接続されています。 そのため再生が終わった時、コンテキストは自動的にそれら (点線内の全て) を解放します。 もし JavaScript からワンショットの音とそれに接続されているノードへの参照がもう無ければ、それらはすぐにグラフから外され破棄されます。 ストリーミングのソースはグローバルな参照を持っており、それが明示的に切断されるまで接続されたままで残ります。 JavaScript ではどうなるのかをここに示します:

例 9
var context = 0;
var compressor = 0;
var gainNode1 = 0;
var streamingAudioSource = 0;

// Initial setup of the "long-lived" part of the routing graph
function setupAudioContext() {
    context = new AudioContext();

    compressor = context.createDynamicsCompressor();
    gainNode1 = context.createGain();

    // Create a streaming audio source.
    var audioElement = document.getElementById('audioTagID');
    streamingAudioSource = context.createMediaElementSource(audioElement);
    streamingAudioSource.connect(gainNode1);

    gainNode1.connect(compressor);
    compressor.connect(context.destination);
}

// Later in response to some user action (typically mouse or key event)
// a one-shot sound can be played.
function playSound() {
    var oneShotSound = context.createBufferSource();
    oneShotSound.buffer = dogBarkingBuffer;

    // Create a filter, panner, and gain node.
    var lowpass = context.createBiquadFilter();
    var panner = context.createPanner();
    var gainNode2 = context.createGain();

    // Make connections
    oneShotSound.connect(lowpass);
    lowpass.connect(panner);
    panner.connect(gainNode2);
    gainNode2.connect(compressor);

    // Play 0.75 seconds from now (to play immediately pass in 0)
    oneShotSound.start(context.currentTime + 0.75);
}

5. チャンネルのアップミックスとダウンミックス

このセクションは基準情報です。

3. ミキサーゲイン構成 では、 AudioNode の入力が 1 つ以上の AudioNode の出力からどのように 接続されるかを記述しています。 これらの出力からの接続のそれぞれは、0 以外の特定のチャンネル数を持っています。 入力はそれら全ての接続のチャンネルを組み合わせるためのミキシング規則を持っています。 単純な例としては、もし入力がモノラル出力とステレオ出力から接続されている場合、そのモノラル接続は通常、ステレオにアップミックスされ、ステレオ接続と加算されます。 しかしもちろん、全ての AudioNode の全ての入力について、その正確なミキシング規則を定義する事が重要です。 全ての入力に対するデフォルトのミキシング規則は、特に非常に良く使われるモノラルとステレオのストリームに対しては、あまり詳細について煩わされる事なく "ちゃんと動作する" ように選ばれます。 しかし、高度な使用例、特にマルチチャンネルの場合にはその規則は変更する事が可能です。

幾つかの用語の定義として、アップミックスは、小さなチャンネル数のストリームを受け取り、 大きなチャンネル数のストリームに変換する処理を指します。 ダウンミックスは、大きなチャンネル数のストリームを受け取り、 小さなチャンネル数のストリームに変換する処理を指します。

AudioNode の入力は全ての出力からの接続をどのようにミックスするかを決定するために、3 つの基本的な情報を使用します。 この処理の一部として、任意の時刻における、入力の実際のチャンネル数を表す内部的な値、 computedNumberOfChannels を計算します:

チャンネルのアップミックス、ダウンミックス規則に関わる AudioNode の属性は に定義されています。 以下はそのそれぞれが何を意味しているかの、より正確な仕様です。

AudioNode のそれぞれの入力の実装は次のようにしなくてはなりません:

  1. computedNumberOfChannels を計算します。
  2. 入力への接続のそれぞれについて:
    • 接続を channelInterpretation に従って computedNumberOfChannels にアップミックスまたはダウンミックスします。
    • (他の接続からの) ミックスされたストリームとミックスします。 これは各接続の対応するそれぞれのチャンネルを素直にミックスします。

5.1 スピーカーチャンネル配置

channelInterpretation が "speakers" の場合、特定のチャンネル配置に対してのアップミックスおよびダウンミックスが定義されます。

モノ (1 チャンネル)、ステレオ (2 チャンネル)、クワッド (4 チャンネル) そして 5.1 (6 チャンネル) がサポートされなくてはなりません (MUST)。それ以外のチャンネル配置についてはこの仕様で将来サポートされるかもしれません。

5.2 チャンネルの順序

    Mono
      0: M: mono

    Stereo
      0: L: left
      1: R: right

  Quad
      0: L:  left
      1: R:  right
      2: SL: surround left
      3: SR: surround right

    5.1
      0: L:   left
      1: R:   right
      2: C:   center
      3: LFE: subwoofer
      4: SL:  surround left
      5: SR:  surround right

5.3 アップミックスのスピーカー配置

Mono up-mix:

    1 -> 2 : up-mix from mono to stereo
        output.L = input;
        output.R = input;

    1 -> 4 : up-mix from mono to quad
        output.L = input;
        output.R = input;
        output.SL = 0;
        output.SR = 0;

    1 -> 5.1 : up-mix from mono to 5.1
        output.L = 0;
        output.R = 0;
        output.C = input; // put in center channel
        output.LFE = 0;
        output.SL = 0;
        output.SR = 0;

Stereo up-mix:

    2 -> 4 : up-mix from stereo to quad
        output.L = input.L;
        output.R = input.R;
        output.SL = 0;
        output.SR = 0;

    2 -> 5.1 : up-mix from stereo to 5.1
        output.L = input.L;
        output.R = input.R;
        output.C = 0;
        output.LFE = 0;
        output.SL = 0;
        output.SR = 0;

Quad up-mix:

    4 -> 5.1 : up-mix from quad to 5.1
        output.L = input.L;
        output.R = input.R;
        output.C = 0;
        output.LFE = 0;
        output.SL = input.SL;
        output.SR = input.SR;

5.4 ダウンミックスのスピーカー配置

A down-mix will be necessary, for example, if processing 5.1 source material, but playing back stereo.

  Mono down-mix:

      2 -> 1 : stereo to mono
          output = 0.5 * (input.L + input.R);

      4 -> 1 : quad to mono
          output = 0.25 * (input.L + input.R + input.SL + input.SR);

      5.1 -> 1 : 5.1 to mono
          output = 0.7071 * (input.L + input.R) + input.C + 0.5 * (input.SL + input.SR)


  Stereo down-mix:

      4 -> 2 : quad to stereo
          output.L = 0.5 * (input.L + input.SL);
          output.R = 0.5 * (input.R + input.SR);

      5.1 -> 2 : 5.1 to stereo
          output.L = L + 0.7071 * (input.C + input.SL)
          output.R = R + 0.7071 * (input.C + input.SR)

  Quad down-mix:

      5.1 -> 4 : 5.1 to quad
          output.L = L + 0.7071 * input.C
          output.R = R + 0.7071 * input.C
          output.SL = input.SL
          output.SR = input.SR


5.5 チャンネル規則の例

このセクションは参考情報です。

例 10
// Set gain node to explicit 2-channels (stereo).
gain.channelCount = 2;
gain.channelCountMode = "explicit";
gain.channelInterpretation = "speakers";

// Set "hardware output" to 4-channels for DJ-app with two stereo output busses.
context.destination.channelCount = 4;
context.destination.channelCountMode = "explicit";
context.destination.channelInterpretation = "discrete";

// Set "hardware output" to 8-channels for custom multi-channel speaker array
// with custom matrix mixing.
context.destination.channelCount = 8;
context.destination.channelCountMode = "explicit";
context.destination.channelInterpretation = "discrete";

// Set "hardware output" to 5.1 to play an HTMLAudioElement.
context.destination.channelCount = 6;
context.destination.channelCountMode = "explicit";
context.destination.channelInterpretation = "speakers";

// Explicitly down-mix to mono.
gain.channelCount = 1;
gain.channelCountMode = "explicit";
gain.channelInterpretation = "speakers";

6. オーディオ信号の値

どのようなオーディオグラフでも destination ノードにおける全てのオーディオ信号の名目上の範囲は [-1, 1] です。 この範囲外の値の信号、あるいは NaN、正の無限値、負の無限値のオーディオレンダリングはこの仕様では定義されていません。

7. 空間配置 / バンニング

7.1 背景

最近の 3D ゲームで良く要求される機能として、動的な空間音響と複数の音源の 3D 空間での移動があります。 OpenAL、FMOD、クリエイティブ社の EAX、マイクロソフト社の XACT Audio などのようなゲームオーディオエンジンはこの機能を持っています。

PannerNode を使って、オーディオストリームを AudioListener に対する相対的な空間位置に配置し、定位させる事ができます。 AudioContext は単一の AudioListener を持っています。 パンナーとリスナーはどちらも右手系デカルト座標の 3D 空間内の位置を持っています。 エフェクトの計算で使われる座標系は、メートルやフィートのような特別な単位とは独立した不変の座標系になっているため、座標空間で使用される単位は定められておらず、その必要もありません。 (ソースストリームの) PannerNode オブジェクトは音が放出される方向を示す orientation ベクトルを持っています。 加えてそれらは音の指向性の強さを示すサウンドコーンを持っています。 例えば、音が無指向性であれば、方向には関係なくどこからでも聴こえますが、指向性が強い場合、それがリスナーの方向を向いている場合にだけ聴こえます。 (人間の耳を表す) AudioListener オブジェクトは人間が向いている方向を表すために orientationup のベクトルを持っています。 音源ストリームとリスナーの両方が移動できるため、それらはどちらも移動の速度と方向を表す velocity ベクトルを持っています。 これらを基にした2つの速度から、ピッチが変動するドップラー効果を作り出す事ができます。

レンダリングの間、 PannerNodeazimuthelevation を計算します。 これらの値は空間配置をレンダリングするために実装によって内部的に使用されます。 これらの値がどのように使われるかの詳細については、 パンニングアルゴリズム を参照してください。

7.2 アジマスとエレベーション

PannerNodeazimuthelevation を計算するために次のアルゴリズムが使用されなくてはなりません:

  // Calculate the source-listener vector.
  vec3 sourceListener = source.position - listener.position;

  if (sourceListener.isZero()) {
      // Handle degenerate case if source and listener are at the same point.
      azimuth = 0;
      elevation = 0;
      return;
  }

  sourceListener.normalize();

  // Align axes.
  vec3 listenerFront = listener.orientation;
  vec3 listenerUp = listener.up;
  vec3 listenerRight = listenerFront.cross(listenerUp);
  listenerRight.normalize();

  vec3 listenerFrontNorm = listenerFront;
  listenerFrontNorm.normalize();

  vec3 up = listenerRight.cross(listenerFrontNorm);

  float upProjection = sourceListener.dot(up);

  vec3 projectedSource = sourceListener - upProjection * up;
  projectedSource.normalize();

  azimuth = 180 * acos(projectedSource.dot(listenerRight)) / PI;

  // Source in front or behind the listener.
  float frontBack = projectedSource.dot(listenerFrontNorm);
  if (frontBack < 0)
      azimuth = 360 - azimuth;

  // Make azimuth relative to "front" and not "right" listener vector.
  if ((azimuth >= 0) && (azimuth <= 270))
      azimuth = 90 - azimuth;
  else
      azimuth = 450 - azimuth;

  elevation = 90 - 180 * acos(sourceListener.dot(up)) / PI;

  if (elevation > 90)
      elevation = 180 - elevation;
  else if (elevation < -90)
      elevation = -180 - elevation;
  

7.3 バンニングアルゴリズム

モノからステレオステレオからステレオ のバンニングがサポートされなくてはなりません。 モノからステレオ の処理は入力への接続が全てモノの場合に使用されます。そうでない場合、は ステレオからステレオ の処理が使用されます。

7.3.1 等価パワーバンニング

これは基本的な、簡単で比較的コストの低いアルゴリズムですが、妥当な結果が得られます。 StereoPannerNodePannerNodepanningModel 属性が "equalpower" に設定されている場合、に使用されます。elevation の値は無視されます。

PannerNode は次のアルゴリズムが実装されなくてはなりません (MUST)。

  1. アジマスとエレベーションセクションで説明されている azimuth の値を計算します。

  2. 次のようにして azimuth の値を [-90, 90] の範囲内にします:

      // First, clamp azimuth to allowed range of [-180, 180].
      azimuth = max(-180, azimuth);
      azimuth = min(180, azimuth);
    
      // Then wrap to range [-90, 90].
      if (azimuth < -90)
        azimuth = -180 - azimuth;
      else if (azimuth > 90)
        azimuth = 180 - azimuth;
            
  3. モノ入力用に azimuth から正規化された値 x を計算します:

      x = (azimuth + 90) / 180;
            

    ステレオ入力用には次のようになります:

      if (azimuth <= 0) { // -90 ~ 0
        // Transform the azimuth value from [-90, 0] degrees into the range [-90, 90].
        x = (azimuth + 90) / 90;
      } else { // 0 ~ 90
        // Transform the azimuth value from [0, 90] degrees into the range [-90, 90].
        x = azimuth / 90;
      }
            

StereoPannerNode では次のアルゴリズムが実装されなくてはなりません (MUST)。

  1. pan をこの StereoPannerNodepan AudioParamcomputedValue とします。

  2. pan を [-1, 1] の範囲に制限します。

    pan = max(-1, pan);
    pan = min(1, pan);
            
  3. モノ入力用に pan の値を [0, 1] の範囲に正規化した x を計算します:

    x = (pan + 1) / 2;
            

    ステレオ入力用は次のようになります:

    if (pan <= 0)
      x = pan + 1;
    else
      x = pan;
            

等価パワーバンニングを行うために次のステップが使用されます:

  1. 左および右のゲイン値を次のように計算します:

    gainL = cos(x * Math.PI / 2);
    gainR = sin(x * Math.PI / 2);
            
  2. モノ入力の場合のステレオの出力は次のように計算します:

    outputL = input * gainL;
    outputR = input * gainR;
            

    ステレオ入力の場合の計算は次のようになります:

    if (pan <= 0) {
      // Pass through inputL to outputL and equal-power pan inputR as in mono case.
      outputL = inputL + inputR * gainL;
      outputR = inputR * gainR;
    } else {
      // Pass through inputR to outputR and equal-power pan inputR as in mono case.
      outputL = inputL * gainL;
      outputR = inputR + inputL * gainR;
    }
            

7.3.2 HRTF バンニング (ステレオのみ)

この処理には様々な azimuth と elevation で記録された HRTF (Head-related Transfer Function) インパルスレスポンスのセットが必要です。 実装には高度に最適化されたコンボリューション機能が必要になります。 これは "equalpower" よりもコストが必要ですが、より空間的な音を得る事ができます。

HRTF panner
Fig. 12 HRTF を用いたバンニング処理の図

7.4 距離効果

近くの音は大きく、遠くの音は小さくなります。 リスナーからの距離に対して正確にどれだけ音量が変化するのかは、distanceModel 属性に依存します。

オーディオレンダリングの間、 distance 値がパンナーとリスナーの位置を基に次のように計算されます:

  function dotProduct(v1, v2) {
    var d = 0;
    for (var i = 0; i < Math.min(v1.length, v2.length); i++)
      d += v1[i] * v2[i];
    return d;
  }
  var v = panner.position - listener.position;
  var distance = Math.sqrt(dotProduct(v, v));
  

そして、 distance を使って distanceModel 属性に依存した distanceGain が計算されます。 それぞれの距離モデルについて、これがどのように計算されるかの詳細は distanceModel セクションを参照してください。 distanceModel 式によって計算された値は [0, 1] の範囲に制限されます。

この処理の一部として、 PannerNode は入力されるオーディオ信号を distanceGain でスケーリング/増幅し、遠くの音は小さく近ければ大きくします。

7.5 サウンドコーン

リスナーとそれぞれの音源はそれがどの方向を向いているかを表す方向ベクトルを持っています。 それぞれの音源の音の放射特性は、音源の方向ベクトルに対してソース/リスナー間の角度の関数で音の大きさを表した内部および外部の "コーン" で表現されます。 つまり、直接リスナーの方を向いた音源は、違う方向を向いた音源よりも大きく聴こえます。 音源はまた、無指向性に設定する事も可能です。

あるソース(PannerNode))とリスナーに対して、コーン効果によるゲインへの影響を計算するためには、次のアルゴリズムを使用しなくてはなりません:

  function dotProduct(v1, v2) {
    var d = 0;
    for (var i = 0; i < Math.min(v1.length, v2.length); i++)
      d += v1[i] * v2[i];
    return d;
  }

  function diff(v1, v2) {
    var v = [];
    for (var i = 0; i < Math.min(v1.length, v2.length); i++)
      v[i] = v1[i] - v2[i];
    return v;
  }

  if (dotProduct(source.orientation, source.orientation) == 0 || ((source.coneInnerAngle == 0) && (source.coneOuterAngle == 0)))
      return 1; // no cone specified - unity gain

  // Normalized source-listener vector
  var sourceToListener = diff(listener.position, source.position);
  sourceToListener.normalize();

  var normalizedSourceOrientation = source.orientation;
  normalizedSourceOrientation.normalize();

  // Angle between the source orientation vector and the source-listener vector
  var dotProduct = dotProduct(sourceToListener, normalizedSourceOrientation);
  var angle = 180 * Math.acos(dotProduct) / Math.PI;
  var absAngle = Math.abs(angle);

  // Divide by 2 here since API is entire angle (not half-angle)
  var absInnerAngle = Math.abs(source.coneInnerAngle) / 2;
  var absOuterAngle = Math.abs(source.coneOuterAngle) / 2;
  var gain = 1;

  if (absAngle <= absInnerAngle)
      // No attenuation
      gain = 1;
  else if (absAngle >= absOuterAngle)
      // Max attenuation
      gain = source.coneOuterGain;
  else {
      // Between inner and outer cones
      // inner -> outer, x goes from 0 -> 1
      var x = (absAngle - absInnerAngle) / (absOuterAngle - absInnerAngle);
      gain = (1 - x) + source.coneOuterGain * x;
  }

  return gain;
  

7.6 ドップラー効果

PannerNode に直接または間接的に接続されている全ての AudioBufferSourceNode に対する付加的な再生速度係数として使用される、ドップラー効果の変化量を計算するため、次のアルゴリズムが使用されなくてはなりません:

  var dopplerShift = 1; // Initialize to default value
  var dopplerFactor = listener.dopplerFactor;

  if (dopplerFactor > 0) {
      var speedOfSound = listener.speedOfSound;

      // Don't bother if both source and listener have no velocity.
      if (dotProduct(source.velocity, source.velocity) != 0 || dotProduct(listener.velocity, listener.velocity) != 0) {
          // Calculate the source to listener vector.
          var sourceToListener = diff(source.position, listener.position);

          var sourceListenerMagnitude = Math.sqrt(dotProduct(sourceToListener, sourceToListener);

          var listenerProjection = dotProduct(sourceToListener, listener.velocity) / sourceListenerMagnitude;
          var sourceProjection = dotProduct(sourceToListener, source.velocity) / sourceListenerMagnitude;

          listenerProjection = -listenerProjection;
          sourceProjection = -sourceProjection;

          var scaledSpeedOfSound = speedOfSound / dopplerFactor;
          listenerProjection = Math.min(listenerProjection, scaledSpeedOfSound);
          sourceProjection = Math.min(sourceProjection, scaledSpeedOfSound);

          dopplerShift = ((speedOfSound - dopplerFactor * listenerProjection) / (speedOfSound - dopplerFactor * sourceProjection));
          fixNANs(dopplerShift); // Avoid illegal values

          // Limit the pitch shifting to 4 octaves up and 3 octaves down.
          dopplerShift = Math.min(dopplerShift, 16);
          dopplerShift = Math.max(dopplerShift, 0.125);
      }
  }
  

8. パフォーマンスについての考察

8.1 レイテンシー

このセクションは参考情報です。

latency
図. 13 レイテンシーが重要となるユースケース

Web アプリケーションでは、マウスとキーボードのイベント (keydown、mousedown等) と聴こえる音の間のディレイタイムは重要です。

この時間の遅れはレイテンシーと呼ばれ、幾つかの要因 (入力デバイスのレイテンシー、内部バッファのレイテンシー、DSP処理のレイテンシー、出力デバイスのレイテンシー、スピーカーとユーザーの耳の距離、など) によって引き起こされ、累積されてゆきます。 レイテンシーが大きいとユーザー体験の満足度は下がります。 極端な場合、それは音楽制作やゲームプレイを不可能にする事もあります。 ある程度のレベルになるとそれはタイミングに影響し、音が遅れている、あるいはゲームが反応しないなどの印象を与えます。 音楽アプリケーションではタイミングの問題はリズムに影響します。 ゲームではタイミングの問題はゲームプレイの精度に影響します。 インタラクティブなアプリケーションでは、それは一般的にアニメーションのフレームレートがとても低いのと同じようにユーザー体験を非常に安っぽくします。 満足できるレイテンシーはアプリケーションによって異なり、 3 ~ 6 ミリ秒から 25 ~ 50 ミリ秒程度です。

実装は一般的に全体的なレイテンシーを最小化する事を目指します。

全体的なレイテンシーの最小化とあわせて、実装は一般的に AudioContextcurrentTimeAudioProcessingEventplaybackTime の差を最小化する事を目指します。 ScriptProcessorNode が廃止予定となった事でこの考慮はその内問題とならなくなるでしょう。

8.2 オーディオバッファのコピー

AudioBuffer に対して 内容の取得処理が行われる時、処理全体は通常チャンネルデータのコピーをする事なく実装する事ができます。 特に、最後のステップは次の getChannelData の呼び出しまで先延ばしにするべきです。 それは (例えば、複数のAudioBufferSourceNodeが同じAudioBufferを再生するような) 絶え間ない getChannelDataによる、連続した内容の取得処理がアロケーションやコピーをする事なく実装できる事を意味します。

実装は更に追加の最適化をする事も可能です: AudioBufferに新しいArrayBufferが割り当てられておらず、しかし以前のAudioBufferに対する内容の取得処理の呼び出し元の全てが AudioBuffer のデータ使用を止めている場合に、 そのAudioBufferに対する getChannelData呼び出しがあった時、再割り当てやチャンネルデータのコピーを避けてデータバッファの再利用が可能です。

8.3 AudioParam の遷移

このセクションは参考情報です。

属性に直接値を設定した際、自動的な平滑化が行われない一方で、幾つかのパラメータは直接的な値の設定に対して滑らかな変化が望まれます。

setTargetAtTime メソッドを低い timeConstant で使う事で滑らかな変化を実現する事ができます。

8.4 オーディオグリッジ

オーディオグリッジは正常な連続したオーディオストリームが途切れる事で発生し、大きなクリックノイズやポップノイズを引き起こします。 それはマルチメディアシステムでは最悪の失敗と考えられ、絶対に避けなければなりません。 それは適切な優先度を持っていなかったり時間的制約から起こるスケジューリングの遅延のような事が原因で、オーディオストリームをハードウェアに供給するスレッドの反応速度の問題によって引き起こされる事があります。 また、それはオーディオDSPが与えられたCPUの速度ではリアルタイムで処理できないような多量の仕事をしようとする事で起こる場合もあります。

8.5 リアルタイムの処理と合成に関するJavascriptの課題:

JavsScript でオーディオを処理する際に、妥当な低レイテンシーでオーディオにグリッジが無く、信頼性を確保するのは、 特にCPU負荷が高い状況においては極めてチャレンジングな事です。 比較的非力なパフォーマンスと消費電力/バッテリー寿命問題を抱える今日のモバイルデバイスでは、問題はさらに難しくなります。

9. セキュリティに関する考察

このセクションは参考情報です。

10. プライバシーに関する考察

このセクションは参考情報です。

AudioNode が持っている様々な情報から、Web Audio API は潜在的に (オーディオハードウェアのサンプルレートのような) クライアントの特徴的な機能の情報を AudioNode インータフェースを使うどんなページにでもさらけ出します。 更に、AnalyserNodeScriptProcessorNodeのインターフェースからタイミングに関する情報も得られます。 情報はその後クライアントのフィンガープリントを作成するために使われるかも知れません。

現在の所オーディオ入力についてはこの文書では規定していませんが、クライアント機器のオーディオ入力やマイクへのアクセスを得る事ができます。 これにはおそらく getUserMedia() API が使われますが、ユーザーからの許可を適切に得る事が必要になります。

11. 要求と使用例

[webaudio-usecases] を参照してください。

12. 承認

この仕様は W3C Audio Working Group の集合著作物です。

Members of the Working Group are (at the time of writing, and by alphabetical order):
Adenot, Paul (Mozilla Foundation) - Specification Co-editor; Akhgari, Ehsan (Mozilla Foundation); Berkovitz, Joe (Hal Leonard/Noteflight) – WG Chair; Bossart, Pierre (Intel Corporation); Carlson, Eric (Apple, Inc.); Choi, Hongchan (Google, Inc.); Geelnard, Marcus (Opera Software); Goode, Adam (Google, Inc.); Gregan, Matthew (Mozilla Foundation); Hofmann, Bill (Dolby Laboratories); Jägenstedt, Philip (Opera Software); Kalliokoski, Jussi (Invited Expert); Lilley, Chris (W3C Staff); Lowis, Chris (Invited Expert. WG co-chair from December 2012 to September 2013, affiliated with British Broadcasting Corporation); Mandyam, Giridhar (Qualcomm Innovation Center, Inc); Noble, Jer (Apple, Inc.); O'Callahan, Robert(Mozilla Foundation); Onumonu, Anthony (British Broadcasting Corporation); Paradis, Matthew (British Broadcasting Corporation); Raman, T.V. (Google, Inc.); Schepers, Doug (W3C/MIT); Shires, Glen (Google, Inc.); Smith, Michael (W3C/Keio); Thereaux, Olivier (British Broadcasting Corporation); Toy, Raymond (Google, Inc.); Verdie, Jean-Charles (MStar Semiconductor, Inc.); Wilson, Chris (Google,Inc.) - Specification Co-editor; ZERGAOUI, Mohamed (INNOVIMAX)

Former members of the Working Group and contributors to the specification include:
Caceres, Marcos (Invited Expert); Cardoso, Gabriel (INRIA); Chen, Bin (Baidu, Inc.); MacDonald, Alistair (W3C Invited Experts) — WG co-chair from March 2011 to July 2012; Michel, Thierry (W3C/ERCIM); Rogers, Chris (Google, Inc.) – Specification Editor until August 2013; Wei, James (Intel Corporation);

13. Web Audio API チェンジログ

changelog.html を参照してください。

A. リファレンス

A.1 基準リファレンス

[DOM]
Anne van Kesteren; Aryeh Gregor; Ms2ger; Alex Russell; Robin Berjon. W3C DOM4. 19 November 2015. W3C Recommendation. URL: http://www.w3.org/TR/dom/
[HTML]
Ian Hickson. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[TYPED-ARRAYS]
David Herman; Kenneth Russell. Typed Array Specification. 26 June 2013. Khronos Working Draft. URL: https://www.khronos.org/registry/typedarray/specs/latest/
[WEBIDL]
Cameron McCormack; Boris Zbarsky. WebIDL Level 1. 4 August 2015. W3C Working Draft. URL: http://www.w3.org/TR/WebIDL-1/
[Workers]
Ian Hickson. Web Workers. 24 September 2015. W3C Working Draft. URL: http://www.w3.org/TR/workers/
[mediacapture-streams]
Daniel Burnett; Adam Bergkvist; Cullen Jennings; Anant Narayanan. Media Capture and Streams. 14 April 2015. W3C Last Call Working Draft. URL: http://www.w3.org/TR/mediacapture-streams/
[webrtc]
Adam Bergkvist; Daniel Burnett; Cullen Jennings; Anant Narayanan. WebRTC 1.0: Real-time Communication Between Browsers. 10 February 2015. W3C Working Draft. URL: http://www.w3.org/TR/webrtc/

A.2 参考リファレンス

[2dcontext]
Rik Cabanier; Jatinder Mann; Jay Munro; Tom Wiltzius; Ian Hickson. HTML Canvas 2D Context. 19 November 2015. W3C Recommendation. URL: http://www.w3.org/TR/2dcontext/
[WEBGL]
Chris Marrin (Apple Inc.). WebGL Specification, Version 1.0. 10 February 2011. URL: https://www.khronos.org/registry/webgl/specs/1.0/
[XHR]
Anne van Kesteren. XMLHttpRequest Standard. Living Standard. URL: https://xhr.spec.whatwg.org/
[mimesniff]
Gordon P. Hemsley. MIME Sniffing Standard. Living Standard. URL: https://mimesniff.spec.whatwg.org/
[webaudio-usecases]
Joe Berkovitz; Olivier Thereaux. Web Audio Processing: Use Cases and Requirements. 29 January 2013. W3C Note. URL: http://www.w3.org/TR/webaudio-usecases/