この文書は、W3Cの文書 "「Web Audio API」 W3C Working Draft 08 December 2015" の日本語訳です。
Web Audio APIの正式な文書は英語版のみであり、日本語訳には翻訳に起因する誤りが含まれている場合があります。
正式な文書はW3Cのサイト : http://www.w3.org/TR/webaudio/にあります。
なお、翻訳元の文書もまだドラフト(Working Draft)です。現状ではまだ説明が不足している部分があったり、今後も頻繁に更新される可能性がある事に注意してください。
日本語訳GitHub : https://github.com/g200kg/web-audio-api-ja
日本語訳公開URL : http://g200kg.github.io/web-audio-api-ja/
Tatsuya Shinyagaito @ g200kg
誤りその他があればGitHubページ、下のサイト経由などで連絡をお願いいたします。
http://www.g200kg.com/
2016年1月20日
Copyright © 2013-2015 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
この仕様はWebアプリケーションにおけるオーディオの処理および合成に関する高レベルの
JavaScript API について記述します。
その基本的な枠組みとなっているのはオーディオのルーティンググラフであり、
多数のAudioNode
オブジェクトが互いに接続される事で最終的なオーディオ出力が定義されます。
実際の処理は基本的に下層にある実装 (典型的には最適化されたアセンブリ言語/C/C++コード)で行われますが、
JavaScriptによる直接的な処理と合成もサポートされています。
序文セクションではこの仕様の背後にある動機についても取り上げます。
このAPIは他のAPIやWebプラットフォームの要素、 特に(responseType
と response
属性を使った) 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はより高度な機能を後から追加できるように設計されています。
この API は、これらの基本機能をサポートします:
audio
または video
メディア要素からのオーディオに対する処理
MediaStreamAudioSourceNode
と[webrtc]を使ってリモート・ピアから受け取ったオーディオの処理
MediaStreamAudioDestinationNode
と [webrtc]を使ったリモート・ピアへの送信
モジュラールーティングによって異なる AudioNode
オブジェクト同士を任意に接続できます。 それぞれのノードは入力および出力を持っています。
ソースノードは入力は持たず、1つの出力を持ちます。 デスティネーションノードは1つの入力を持ち、出力は持っていません。この最も一般的な例が最終的なオーディオハードウェアに繋がるAudioDestinationNodeです。 フィルタなどの他のノードはソースとデスティネーションの間に配置することができます。 2つのオブジェクトが互いに接続している場合、低レベルのストリーム形式の詳細について開発者が煩わされる事なく、適正な処理が行われます。 例えばもしモノラルの音声ストリームがステレオの入力に接続されていても、左右のチャンネルに適正にミックスされます。
最も単純な例は、1つの音声ソースを出力に直接接続したものです。 すべての接続は単一のAudioDestinationNode
を持つAudioContext
内部で行われます:
この単純なルーティングを図示します。この例では単一の音を再生しています:
var context = new AudioContext(); function playSound() { var source = context.createBufferSource(); source.buffer = dogBarkingBuffer; source.connect(context.destination); source.start(0); }
これはもっと複雑な例で、3つのソースとコンボリューションリバーブが最終出力段にあるダイナミックコンプレッサーを介して送られます:
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
パラメータに接続する事もできます。この場合は、ノードからの出力は
入力信号ではなくモジュレーション信号として働きます。
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); }
定義されているインターフェースは次の通りです:
AudioNode
間の接続を表すオーディオ信号グラフを保持します。
AudioNode
インターフェースは、オーディオのソース、オーディオの出力、その間にある処理モジュールを表します。AudioNode
はmodular fashionで動的に互いに接続されます。 AudioNode
はAudioContext
のコンテキスト内に存在します。
AudioDestinationNode
インターフェースは、 AudioNode
のサブクラスでオーディオの最終的な出力地点を表します。
AudioBuffer
インターフェースは、 メモリ内に保持されるオーディオのリソースで使用されます。これらはワンショットの音、またはもっと長いオーディオクリップを表します。
AudioBufferSourceNode
インターフェースは、 AudioBuffer からの音を発生する AudioNode
です。
MediaElementAudioSourceNode
インターフェースは、 audio、video その他のメディア要素を音源とする AudioNode
です。
MediaStreamAudioSourceNode
インターフェースは、 ライブオーディオ入力やリモート・ピアから受け取ったような MediaStream を音源とする AudioNode
です。
MediaStreamAudioDestinationNode
インターフェースは、 リモート・ピアに送信する MediaStream へ出力する AudioNode
です。
AudioWorker
インターフェースは、JavaScriptでオーディオを直接処理するカスタムノードを作成するファクトリを表します。
AudioWorkerNode
インターフェースは、 AudioWorker で処理される AudioNode
を表します。
AudioWorkerGlobalScope
インターフェースは、 AudioWorker の処理スクリプトが実行されるコンテキストです。
AudioWorkerNodeProcessor
インターフェースは、 AudioWorker 内の1つのノードのインスタンスを表します。
AudioParam
インターフェースは、 AudioNode
の個別の機能、例えば音量などを制御します。
GainNode
インターフェースは、明示的なゲイン制御を行う AudioNode
です。 AudioNode
への入力は (ユニティ・ゲイン(訳注:ゲインが1である事)の加算による) 複数の接続をサポートしているため、 GainNode を使う事でミキサーが簡単に構成できます。
BiquadFilterNode
インターフェースは、 次のような一般的な低次のフィルタの AudioNode
です:
IIRFilterNode
インターフェースは、一般的な IIR フィルターの AudioNode
です。
DelayNode
インターフェースは、動的に調整可能な遅延を加える AudioNode
です。
SpatialPannerNode
インターフェースは、3次元空間内で定位を行う AudioNode
です。
SpatialListener
インターフェースは、 SpatialPannerNode
と共に空間定位のために使用されます。
StereoPannerNode
インターフェースは、ステレオストリームで equal-power 方式の定位を行う AudioNode
です。
ConvolverNode
インターフェースは、 (例えばコンサートホールでの残響効果のような)リアルタイム線形エフェクトを加える AudioNode
です。
AnalyserNode
インターフェースは、ミュージックビジュアライザーやその他の視覚化アプリケーションで使用される AudioNode
です。
ChannelSplitterNode
インターフェースは、 ルーティンググラフ内のオーディオストリームの個別のチャンネルにアクセスするために使用される
AudioNode
です。
ChannelMergerNode
インターフェースは、 複数のオーディオストリームから1つのオーディオストリームにチャンネルの結合を行う AudioNode
です。
DynamicsCompressorNode
インターフェースは、 ダイナミクス・コンプレッションのための AudioNode
です。
WaveShaperNode
インターフェースは、 例えばディストーションや微妙なウォーミング効果(訳注:いわゆるサチュレーション効果の事)など、非線形のウェーブシェイピング・エフェクトを加えるための AudioNode
です。
OscillatorNode
インターフェースは、周期的な波形を発生する AudioNode
です。
また非推奨ですがまだ削除されておらず、置き換えの実装が予定されているいくつかの Web Audio API があります。
PannerNode
インターフェースは、3D 空間での空間音響/空間定位のための AudioNode
です。これは SpatialPannerNode
および 簡単なシナリオのためにはStereoPannerNode
で置き換えられます。
AudioListener
インターフェースは、 PannerNode
と共に空間音響のために使用されます。
ScriptProcessorNode
インターフェースは、JavaScriptでオーディオを直接生成または処理するための
AudioNode
です。
AudioProcessingEvent
インターフェースは、 ScriptProcessorNode
オブジェクトと共に用いられるイベントタイプです。
この仕様内で参考情報と書かれているセクション、オーサリングガイドライン、図、例、注は非基準要件です。この仕様内のそれ以外の全ては基準要件となります。
キーワードMUST、 REQUIRED、SHALL は [RFC2119] に記述されているように解釈されます。
次の準拠クラスがこの仕様によって定義されています:
この仕様の全てのMUST-、 REQUIRED-、 SHALL レベルの基準を満足する実装がされているユーザーエージェントが、準拠した実装と判断されます。
この仕様で定められたAPIの実装にECMAScriptを使用するユーザーエージェントは、Web IDL仕様 [WEBIDL]で定義されるECMAScriptバインディングの仕様と用語がこの仕様での使用と矛盾しない方法で実装しなくてはなりません。
このインターフェースは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);
};
currentTime
double 型, readonly コンテキストのレンダリンググラフで最後に処理されたオーディオブロックの最後のサンプルフレームの次のサンプルの秒で表した時刻です。もしコンテキストのレンダリンググラフがまだオーディオブロックを処理していない場合 currentTime
は0になります。
currentTime
の時間軸で0はグラフで処理される最初のブロックの最初のサンプルフレームに対応します。このシステムの経過時間はBaseAudioContext
が生成するオーディオストリームの経過時間に対応し、それはシステム内の他の時計には同期しないかも知れません。(OfflineAudioContext
では、ストリームはどのデバイスも能動的に再生しないため、実時間とはまったく違う進み方になります)
Web Audio API の全てのスケジュールされた時刻は currentTime
に対する相対値になります。
BaseAudioContext
が running
状態にある時、この属性は単調増加し、レンダリングスレッドにより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" の時、これ以上の状態の遷移はできません。
close
オーディオコンテキストをクローズし、BaseAudioContext
で使用されていたシステムの全てのリソースを解放します。
この呼び出しでは他からの参照が同様に開放されない限り BaseAudioContext が作成したオブジェクトは全て自動的には解放されません。しかし、これ以降にオーディオコンテキストが作成され、使用され、BaseAudioContext
の currentTime の進行を suspend し、処理を終了する事を妨げる可能性のあるシステムのオーディオリソースは強制的に開放されます。
Promise は、全てのオーディオコンテキストの作成をブロックするリソースが解放された時にリゾルブされます。もしこれが OfflineAudioContext
に対して呼び出された場合、InvalidStateError
の名前の DOMException
で Promise はリジェクトされます。
Promise<void>
createAnalyser
AnalyserNode
を作成します。
AnalyserNode
createAudioWorker
AudioWorker
オブジェクトを作成し、対応するスクリプトを AudioWorkerGlobalScope
にロードして返却した Promise をリゾルブします。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
scriptURL | DOMString | ✘ | ✘ |
このパラメータはAudioWorker ノードファクトリとしてロードするスクリプトのURLを表します。
詳細は AudioWorker セクションを参照してください。
|
Promise<AudioWorker
>
createBiquadFilter
BiquadFilterNode
を作成します。
BiquadFilterNode
createBuffer
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
numberOfChannels | unsigned long | ✘ | ✘ | バッファが持つチャンネル数を指定します。 実装は少なくとも32チャンネルをサポートしなくてはなりません。 |
length | unsigned long | ✘ | ✘ | バッファのサイズをサンプルフレーム数で指定します。 |
sampleRate | float | ✘ | ✘ | バッファ内のリニアPCMオーディオデータのサンプルレートを秒あたりのサンプルフレーム数で表します。 実装は少なくとも8192から96000の範囲をサポートしなくてはなりません。 |
AudioBuffer
createBufferSource
AudioBufferSourceNode
を作成します。
createChannelMerger
ChannelMergerNode
を作成します。 パラメータの値が無効の場合、IndexSizeError 例外を発生します(MUST)。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
numberOfInputs | unsigned long = 6
| ✘ | ✔ | numberOfInputs は入力の数を指定します。値は32までサポートされなくてはなりません。 もし指定されない場合は6となります。 |
ChannelMergerNode
createChannelSplitter
ChannelSplitterNode
を作成します。 パラメータの値が無効の場合、IndexSizeError 例外を発生します(MUST)。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
numberOfOutputs | unsigned long = 6
| ✘ | ✔ | 出力の数を指定します。32までサポートされなくてはなりません。 もし指定されない場合は6となります。 |
ChannelSplitterNode
createConvolver
ConvolverNode
を作成します。
ConvolverNode
createDelay
DelayNode
を作成します。 初期化時のデフォルト遅延時間は0秒です。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
maxDelayTime | double = 1.0
| ✘ | ✔ | maxDelayTime パラメータはオプションであり、その遅延機能の遅延時間の最大値を秒で指定します。 もし指定する場合は、その値は0よりも大きく3分よりも小さくなければなりません(MUST)。そうでない場合 NotSupportedError 例外を発生します(MUST)。 |
DelayNode
createDynamicsCompressor
DynamicsCompressorNode
を作成します。
createGain
GainNode
を作成します。
GainNode
createIIRFilter
IIRFilterNode
を作成します。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
feedforward | sequence<double> | ✘ | ✘ | IIR フィルターの伝達関数のフィードフォワード(分子)の係数の配列です。 この配列の最大の長さは20です。もし全ての値が0の場合、InvalidStateError 例外を発生しますMUST。配列の長さが0または20より大きい場合は NotSupportedError 例外を発生しますMUST。 |
feedback | sequence<double> | ✘ | ✘ | IIR フィルターの伝達関数のフィードバック(分母)の係数の配列です。 この配列の最大の長さは20です。もし配列の最初の要素が0の場合、InvalidStateError 例外を発生しますMUST。もし配列の長さが0または20より大きい場合は NotSupportedError 例外を発生しますMUST。 |
IIRFilterNode
createOscillator
OscillatorNode
を作成します。
OscillatorNode
createPanner
PannerNode
を作成します。
PannerNode
createPeriodicWave
PeriodicWave
を作成します。 real
および imag
パラメータは Float32Array
([TYPED-ARRAYS] で説明される)型で0より大きい同じ長さでなくてはなりません。
そうでない場合、IndexSizeError 例外を発生します(MUST)。
全ての実装は少なくとも8192までの配列の長さをサポートしなくてはなりません。
これらのパラメータは任意の周期波形を表すフーリエ級数の係数の一部分を表します。 作成されたPeriodicWave
は OscillatorNode
と共に使用され、 デフォルトでは絶対値の最大が1となる正規化された時間領域の波形を表現します。 別の言い方をするとこれは OscillatorNode
が発生する波形の最大ピークが0dBFSであるという事です。
これは都合よく Web Audio API で使用される最大振幅の信号に対応します。 PeriodicWave はデフォルトでは作成時に正規化されるため、real
および imag
パラメータは相対値を表します。
もし disableNormalization
パラメータによってディセーブルされていた場合、正規化は行われず、時間領域の波形はフーリエ係数で与えられた振幅を持ちます。
PeriodicWave
オブジェクトはこれらの配列をコピーして管理するため、real
および imag
パラメータとして使用した配列を createPeriodicWave()
呼び出し後に変更しても PeriodicWave
オブジェクトには反映されません。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
real | Float32Array | ✘ | ✘ |
real パラメータはコサイン 項(慣習的な言い方でA項)の配列を表します。 オーディオの用語では最初の要素(インデックス0)は周期波形の DC オフセットとなります。 2番目の要素(インデックス1)は基本周波数を表します。3番目の要素は最初の倍音を表し、それ以降も同様に続いてゆきます。
最初の要素は無視され、実装は内部的に0に設定しなくてはなりません。
|
imag | Float32Array | ✘ | ✘ |
imagパラメータはサイン 項(慣習的な言い方でB項)の配列を表します。 最初の要素(インデックス0)はフーリエ級数には存在しないため、0でなくてはなりません(これは無視されます)。 2番目の要素(インデックス1)は基本周波数を表します。3番目の要素は最初の倍音を表し、それ以降も同様に続いてゆきます。
|
constraints |
| ✘ | ✔ |
もし与えられていない場合は、波形は正規化されます。そうでない場合、波形は constraints に与えられた値に従って正規化されます。
|
PeriodicWave
createScriptProcessor
ScriptProcessorNode
を作成します。 もし、bufferSize
または numberOfInputChannels
または numberOfOutputChannels
が範囲外の場合、IndexSizeError 例外を発生します(MUST)。
numberOfInputChannels
と numberOfOutputChannels
の両方が0となるのは不正となります。この場合、IndexSizeError 例外を発生します(MUST)。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
bufferSize | unsigned long = 0
| ✘ | ✔ |
bufferSize パラメータはサンプルフレーム数でバッファのサイズを指定します。 もしそれが渡されない場合、または値が0である場合、実装はノードのライフタイムを通して一定な、動作環境に最適な2の累乗のバッファサイズを選択します。 それ以外の場合は明示的にバッファサイズを指定します。それは次の値のどれかでなければなりません: 256、512、1024、2048、4096、8192、16384。 この値は audioprocess イベントが発生する頻度とそれぞれの呼び出しでどれだけのサンプルフレームを処理する必要があるかを制御します。 bufferSize が小さい値ならば レイテンシー は低く(良く)なります。 オーディオが途切れ、グリッジが発生する事を避けるには大きな値が必要となります。 レイテンシーとオーディオ品質の間のバランスを取るためには、プログラマはこのバッファサイズを指定せず、実装に最適なバッファサイズを選択させる事が推奨されます。
もしこのパラメータの値が上に示した許された2の累乗の値でない場合、IndexSizeError 例外を発生します(MUST)。
|
numberOfInputChannels | unsigned long = 2
| ✘ | ✔ | このパラメータはこのノードの入力チャンネル数を指定します。32チャンネルまでの値がサポートされなくてはなりません。 |
numberOfOutputChannels | unsigned long = 2
| ✘ | ✔ | このパラメータはこのノードの出力チャンネル数を指定します。 32チャンネルまでの値がサポートされなくてはなりません。 |
ScriptProcessorNode
createSpatialPanner
SpatialPannerNode
を作成します。
SpatialPannerNode
createStereoPanner
StereoPannerNode
を作成します。
StereoPannerNode
createWaveShaper
WaveShaperNode
を作成します。
WaveShaperNode
decodeAudioData
responseType
に "arraybuffer" を指定した場合の response
属性としてロードされます。
オーディオファイルデータは audio
または video
要素でサポートされるどのフォーマットでも構いません。
decodeAudioData に渡されるバッファは [mimesniff] で説明される手順で判定されるコンテントタイプを持ちます。
この関数の基本的なインターフェースの手段は戻り値の Promise ではありますが、歴史的な理由からコールバックのパラメータも提供されています。システムは Promise がリゾルブまたはリジェクト、またコールバック関数が呼ばれて完了する前に AudioContext
がガベージコレクションされない事を保証しなくてはなりません。
次のステップが実行されなくてはなりません:
NotSupportedError
という名前の DOMException
とします。
"EncodingError"
という名前の DOMException
とします。
AudioContext
のサンプルレートと異なっていた場合はリサンプルされたオーディオデータをデコード結果として受け取ります。
AudioBuffer
とします。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
audioData | ArrayBuffer | ✘ | ✘ | 圧縮されたオーディオデータを含む ArrayBuffer です |
successCallback |
| ✘ | ✔ | デコードが完了した時に呼び出されるコールバック関数です。コールバック関数の引数は1つでデコードされた PCM オーディオデータをあらわす AudioBuffer になります。 |
errorCallback |
| ✘ | ✔ | オーディオファイルをデコード中にエラーが起こった場合に呼び出されるコールバック関数です。 |
Promise<AudioBuffer
>
resume
サスペンド状態にある BaseAudioContext
の currentTime の進行を再開し、フレームバッファの内容を再度送り出します。
Promise はシステムが(必要なら)オーディオハードウェアへのアクセスを再度得て、ディスティネーションへのストリーミングを開始した時、あるいは、もしコンテキストが既に実行状態なら(副作用なく)即時にリゾルブされます。
Promise はもしコンテキストがクローズされている場合
リジェクトされます。もしコンテキストが現在サスペンド状態でない場合 Promise はリゾルブされます。
このメソッドの呼び出しの後、オーディオの最初のブロックがレンダリングされるまで currentTime は変化しない事に注意してください。
Promise<void>
suspend
BaseAudioContext
のcurrentTime の進行をサスペンドします。現在既にディスティネーションに送り出すために処理されているブロックの処理は許可され、システムはオーディオハードウェアの使用を解放します。これは一般的にアプリケーションが BaseAudioContext
をしばらく使用しない事がわかっていて、オーディオハードウェアのパワーダウンを行いたい場合に有用です。
Promise はフレームバッファが空になった(ハードウェアに渡し終えた)時か、もしコンテキストが既にサスペンド状態にあれば(副作用なく)即時にリゾルブされます。 Promise はもしコンテキストがクローズされていればリジェクトされます。
システムがサスペンドされている間、 MediaStream は出力が無視されます---つまりメディアストリームのリアルタイム性によってデータが失われる事になります。 HTMLMediaElement も同様にシステムが resume されるまで出力が無視されます。 AudioWorker と ScriptProcessorNode は単純に onaudioprocess イベントが発行されなくなりますが、resume された時には復帰します。 AnalyserNode では窓関数の目的から、データは継続的に流れているものとみなされます - つまり resume() / suspend() は AnalyserNode のデータストリームに無音状態を作りません。
Promise<void>
DecodeSuccessCallback
パラメータ decodedData
AudioBuffer
型DecodeErrorCallback
パラメータ error
DOMException 型AudioContextOptions
メンバー playbackCategory
AudioContextPlaybackCategory 型
, デフォルトは "interactive"
AudioContext
は一度作成された後、これ以上再生する音がなくなるまで、あるいはページを移動するまで再生を続けます。
このセクションは参考情報です
Web Audio API は音源のスケジューリングに fire-and-forget アプローチを取っています。つまり、音源ノードは、 AudioContext
のライフタイムの間の1つひとつの音に対応して作成され、明示的にグラフからの削除は行いません。これはシリアライゼーション API とは互換性がなく、そのためシリアライズ可能な固定的なノードのセットもありません。
更に、内部検査のための API を持つためにはスクリプトの中身のガベージコレクションの監視が必要になります。
このインターフェースは、その AudioDestinationNode
がデバイスへのリアルタイム出力によって直接ユーザーに信号が届くオーディオグラフを表します。多くの場合、1つのドキュメントにつき1つの AudioContext
が使用されます。
interface AudioContext : BaseAudioContext
{
MediaElementAudioSourceNode
createMediaElementSource (HTMLMediaElement mediaElement);
MediaStreamAudioSourceNode
createMediaStreamSource (MediaStream mediaStream);
MediaStreamAudioDestinationNode
createMediaStreamDestination ();
};
createMediaElementSource
AudioContext
の処理グラフにリルートされるようになります。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
mediaElement | HTMLMediaElement | ✘ | ✘ | リルートされるメディアエレメントです。 |
createMediaStreamDestination
MediaStreamAudioDestinationNode
を作成します。
createMediaStreamSource
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
mediaStream | MediaStream | ✘ | ✘ | 音源となるメディアストリームです。 |
OfflineAudioContext
はレンダリング/ミックスダウンで使用される特殊な AudioContext
であり、(可能性としては)リアルタイムよりも高速に動作します。 それはオーディオハードウェアに出力しない代わりに可能な限り高速に動作して、 Promise にレンダリング結果を AudioBuffer
として戻します。
OfflineAudioContext は AudioContext.CreateBuffer と同じ引数で作成されます。 もし引数のどれかが負の値、0、あるいは範囲外であった場合は NotSupportedException 例外を発生しますMUST。
[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;
};
oncomplete
EventHandler 型OfflineAudioCompletionEvent 型のイベントハンドラーです。
resume
サスペンド状態のオーディオコンテキストの進行を再開します。
OfflineAudioContext
はオーディオハードウェアを必要としないため、 Promise は即時にリゾルブされます。もしコンテキストが現在サスペンド状態でない、あるいはレンダリングがまだ開始されていない場合、 Promise は InvalidStateError
でリジェクトされます。
ライブ情報を扱う AudioContext
とは違い、サスペンド状態の間コンテキストのオーディオストリームが進まないため、 currentTime の値は常にオーディオグラフによって次にレンダリングされるブロックの先頭時間を指します。
Promise<void>
startRendering
与えられた現在の接続とスケジュールされたオートメーションでオーディオのレンダリングを開始します。システムは Promise がリゾルブされコールバック関数が呼び出されるまで、あるいは suspend
関数が呼び出されるまで OfflineAudioContext
がガベージコレクションされない事を保証します。
オーディオデータのレンダリング結果を得る基本的なメソッドは Promise の戻り値ですが、歴史的な理由によりこのインスタンスは complete
という名前のイベントも発行します。
次のステップが実行されなくてはなりません:
startRendering
が既に呼ばれている場合、 Promise は InvalidStateError
でリジェクトされます。
numberOfChannels
をチャンネル数、 length
を長さ、 sampleRate
をサンプルレートとした新しい AudioBuffer
を buffer とします。
length
のサンプルフレーム数のオーディオを buffer にレンダリング開始します。
OfflineAudioCompletionEvent
のインスタンスで complete
という名前のイベントを発行するためにキューに入れ、その renderedBuffer
プロパティに buffer をセットします。
Promise<AudioBuffer
>
suspend
オーディオコンテキストの時間の進行を指定の時刻にサスペンドする事をスケジューリングし、 Promise を返します。
これは一般的に OfflineAudioContext
上でオーディオグラフを同期的に操作するために役立ちます。
サスペンドの最大の精度はレンダリング処理の分割のサイズであり、指定されたサスペンド時刻は最も近い分割の境界に丸められる事に注意してください。このため、同じ分割フレーム内に複数のサスペンドをスケジューリングする事はできません。また、スケジューリングはコンテキストが高精度のサスペンドを保証しない実行を行っている間に行わなくてはなりません。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
suspendTime | double | ✘ | ✘ |
レンダリングのサスペンドをスケジュールする時刻。これはレンダリングの分割サイズの境界に丸められます。 もし丸められた結果のフレーム数が、
InvalidStateError でリジェクトされます。
|
Promise<void>
[Constructor]
interface AudioContext : BaseAudioContext
{
};
これは OfflineAudioContext
に対して歴史的な理由により、ディスパッチされる Event
です。
interface OfflineAudioCompletionEvent : Event {
readonly attribute AudioBuffer
renderedBuffer;
};
renderedBuffer
AudioBuffer 型
, readonly
レンダリングされたオーディオデータを保持する AudioBuffer
です。
AudioNode は AudioContext
の構成ブロックです。
このインターフェースはオーディオのソース、出力先、中間の処理モジュールを表しています。これらのモジュールは互いに接続されて、 音をオーディオハードウェアに出力するための処理グラフを形成します。 それぞれのノードは入力や出力を持つ事ができます。 ソースノードは入力を持たず、単一の出力を持ちます。
AudioDestinationNode
は 単一の入力を持ち、出力を持たず、オーディオハードウェアへの最終的な出力地点を表しています。
フィルターのような殆どの処理ノードは1つの入力と1つの出力を持ちます。
それぞれのタイプの AudioNode
はどのようにオーディオを処理したり合成したりするかの詳細が異なっています。 しかし、一般的に AudioNode は(持っていれば)その入力を処理し、(持っていれば)その出力にオーディオ信号を送り出します。
それぞれの出力は1つ以上のチャンネルを持っています。正確なチャンネル数はそれぞれの AudioNode
の詳細に依存します。
出力は1つ以上の AudioNode
入力に接続でき、つまりファンアウトがサポートされています。
入力は初期化時には接続されていません。しかし、1つ以上の AudioNode
出力から接続する事ができ、即ち、ファンインがサポートされています。
AudioNode
の出力を AudioNode
の入力に接続するため connect()
メソッドが呼ばれた時、それをその入力への接続と呼びます。
各 AudioNode
の入力はその時々で特定のチャンネル数を持ちます。この数はその入力への接続によって変化します。 もし入力が接続を持っていない場合、チャンネル数は1で無音となります。
AudioNode
入力について、その入力への接続のミックス(通常はアップミックス)を行います。 この詳細に関して参考情報としては
3. ミキサーゲイン構成
、基準としての詳細要件については
5.
チャンネルのアップミックスとダウンミックス
セクションを参照してください。
AudioNode
の入力および内部の処理は、そのノードが出力を接続されているか、またそれらの出力が AudioContext
の AudioDestinationNode
に到達しているかに関わらず、 AudioContext
の時刻を踏まえて継続的に行われます。
パフォーマンス的な理由から実際の実装ではそれぞれの AudioNode
は決まったブロックサイズのサンプルフレームをブロック単位に処理する事が必要になると思われます。
実装による振る舞いを統一するため、この値を明示的に定めます。ブロックサイズはサンプルレート44.1kHzにおいて約3msとなる128サンプルフレームとします。
AudioNode は、DOM [DOM] で記述される EventTarget です。 これは他の EventTarget がイベントを受け取るのと同じ方法でイベントを AudioNode
にディスパッチする事が可能である事を意味します。
enum ChannelCountMode {
"max",
"clamped-max",
"explicit"
};
列挙値の説明 | |
---|---|
max |
は全ての接続のチャンネル数の最大値として計算されます。 このモードでは channelCount は無視されます。
|
clamped-max
|
"max" と同様ですが、 channelCount を上限とします。 |
explicit |
の値は 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;
};
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
のタイプで固定の値になりますが、 ChannelMergerNode
や AudioWorkerNode
のような幾つかの AudioNode
では入力の数は可変です。
numberOfOutputs
unsigned long型, readonly AudioNode
から出る出力の数です。この属性は幾つかの AudioNode
では固定の値ですが、 ChannelSplitterNode
や AudioWorkerNode
などでは可変になります。
connect
あるノードの特定の出力から別のノードの特定の入力への接続は1つだけ存在できます。同じ端子間の複数回の接続は無視されます。例えば:
nodeA.connect(nodeB); nodeA.connect(nodeB);
は次のものと同じ効果になります。
nodeA.connect(nodeB);
例 | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
destination |
| ✘ | ✘ |
destination パラメータは接続先のAudioNode です。もしdestination が他のAudioContext によって作成されたAudioNode の場合、InvalidAccessError 例外を発生します(MUST)。
つまり AudioNodes は複数の AudioContext 間で共有する事はできません。
|
output | unsigned long = 0
| ✘ | ✔ |
output パラメータは AudioNode のどの出力を接続するかを指定するインデックスです。
もしこのパラメータが範囲外の場合、 IndexSizeError 例外を発生します (MUST)。
connect() を複数回呼び出して AudioNode の出力から複数の入力に接続する事は可能です。つまり、"ファンアウト"がサポートされています。
|
input | unsigned long = 0
| ✘ | ✔ |
input パラメータは接続先の AudioNode のどの入力に接続するかを指定するインデックスです。もしこのパラメータが範囲外の場合、 IndexSizeError 例外を発生します (MUST)。
ある AudioNode から他の AudioNode に循環を作るような接続を行う事も可能です:
つまりある AudioNode から、最初の AudioNode に接続を行っている別の AudioNode に対して接続を行う事ができます。
これは循環の中に少なくとも1つの DelayNode がある場合にのみ可能で、そうでなければ NotSupportedError 例外を発生します (MUST)。
|
AudioNode
connect
AudioNode
を AudioParam
に接続し、パラメータの値をオーディオレートの信号で制御します。
connect() を複数回呼び出す事で AudioNode
の出力を複数の AudioParam
に接続する事が可能です。即ち、"ファンアウト"がサポートされています。
connect() を複数回呼び出す事で、複数の AudioNode
を1つの AudioParam
に接続する事が可能です。即ち、"ファンイン"がサポートされています。
AudioParam
はそれに接続されている AudioNode
の出力からレンダリングされたオーディオデータを取り出し、それがモノでなければ、ダウンミックスによってモノに変換します。 そして接続されている各出力をミックスし、更に最終的にパラメータが持っているタイムラインの変化スケジュールを含む固有値( AudioParam
に何も接続されていない状態での値
)とミックスします。
特定のノードの出力と特定の AudioParam
の間の接続は1つのみ存在できます。 同じ終端点を持つ複数の接続は無視されます。例えば:
nodeA.connect(param); nodeA.connect(param);は次と同じ効果を持ちます
nodeA.connect(param);
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
destination |
| ✘ | ✘ |
destination パラメータは接続先の AudioParam です。
このメソッドは 接続先 の AudioParam オブジェクトを返しません。
|
output | unsigned long = 0
| ✘ | ✔ |
output パラメータは AudioNode のどの出力から接続するかを指定するインデックスです。
もし parameter が範囲外の場合、IndexSizeError 例外を発生します (MUST)。
|
void
disconnect
AudioNode
から出る全ての接続を切断します。
void
disconnect
AudioNode
の1つの出力から他のAudioNode
またはAudioParam
オブジェクトへの接続を全て切断します。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
output | unsigned long | ✘ | ✘ |
このパラメータは接続を切る AudioNode の出力のインデックスです。 これは与えられた出力から出る全ての接続を切断します。
もしこのパラメータが範囲外の場合、IndexSizeError 例外を発生します (MUST)。
|
void
disconnect
AudioNode
の全ての出力から特定の接続先となる AudioNode
に繋がる接続を切断します。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
destination |
| ✘ | ✘ |
destination パラメータは切断する AudioNode です。これは与えられた destination に対する全ての接続を切断します。
もしdestination に対する接続がない場合、InvalidAccessError を発生します (MUST)。
|
void
disconnect
AudioNode
の特定の出力から特定の AudioNode
への接続を切断します。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
destination |
| ✘ | ✘ |
destination パラメータは切断する AudioNode です。もし、与えられた出力から destination への接続が存在しない場合、InvalidAccessError 例外を発生します (MUST )。
|
output | unsigned long | ✘ | ✘ |
output パラメータは接続を切る AudioNode の出力を表すインデックスです。もしこのパラメータが範囲外の場合は IndexSizeError 例外を発生します (MUST)。
|
void
disconnect
AudioNode
の特定の出力から
接続先 AudioNode
の特定の入力への接続を切断します。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
destination |
| ✘ | ✘ |
destination パラメータは切断する AudioNode です。もし与えられた出力から destination の与えられた入力への接続が存在しない場合、InvalidAccessError 例外を発生します (MUST)。
|
output | unsigned long | ✘ | ✘ |
output パラメータは切断する AudioNode の出力のインデックスです。もしこのパラメータが範囲外の場合、IndexSizeError 例外を発生します (MUST)。
|
input | unsigned long | ✘ | ✘ |
input パラメータは切断する接続先 AudioNode の入力のインデックスです。もしこのパラメータが範囲外の場合、IndexSizeError 例外を発生します (MUST)。
|
void
disconnect
特定の接続先 AudioParam
に繋がる AudioNode
の全ての出力を切断します。
この操作によって、この AudioNode
からパラメータ値の計算への寄与は0となります。パラメータの固有値はこの操作に影響されません。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
destination |
| ✘ | ✘ |
destination パラメータは切断する AudioParam です。もし destination への接続が存在しない場合、InvalidAccessError 例外を発生します (MUST)。
|
void
disconnect
AudioNode
の特定の出力から特定のAudioParam
への接続を切断します。
この操作によって、この AudioNode
からパラメータ値の計算への寄与は0となります。パラメータの固有値はこの操作に影響されません。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
destination |
| ✘ | ✘ |
destination パラメータは切断される AudioParam です。もし destination への接続が存在しない場合、InvalidAccessError 例外を発生します (MUST)。
|
output | unsigned long | ✘ | ✘ |
output パラメータは切断される AudioNode の出力のインデックスです。もし、parameter が範囲外の場合、IndexSizeError 例外を発生します (MUST)。
|
void
このセクションは参考情報です。
実装では、必要のないリソース利用や未使用または終了しているノードが際限なくメモリを使うのを避ける為の何らかの方法を選ぶでしょう。 以降の説明は、一般的に期待されるノードのライフタイムの管理の仕方を案内するものです。
何かしら参照される限り、AudioNode
は存在し続けるでしょう。参照には何種類かのタイプがあります。:
AudioBufferSourceNode
と OscillatorNode
の再生中の参照。 再生している間これらのノードは、自分自身への再生中参照を維持します。
AudioNode
から接続されている場合に発生します。
AudioNode
は何かしらの内部プロセスで未解放のステートになっている場合は、その間、自分自身を維持します。 例えば、ConvolverNode
は無音の入力を受けた後でも再生し続ける余韻を持ちます。 (大きなコンサートホールで柏手を打つと、ホール中に響きわたる音が聞こえるのをイメージして下さい)。 いくつかの AudioNode
は、この特性を持ちます。 各ノードの詳細を見てください。
環状に接続され、且つ直接または間接的に AudioContext
の AudioDestinationNode
に接続されるすべての AudioNode
はその AudioContext
が存在している間は存在したままになります。
AudioNode
の継続的な動作はそのノードへの暗黙的に参照が存在しているという事を意味し、たとえオーディオグラフから切断されていても、ノードは入力を処理し続け、内部状態を更新し続けます。
この処理はCPUと電力を消費し続けるため、開発者は注意深くリソースの使用について考慮しなくてはなりません。
特に、可能な時には明示的に切断されたノードを停止状態にする事でリソースの消費を最小化するのは良い考えです。
参照を全く持たなくなった時、AudioNode
は削除されます。 しかしそれが削除される前に、他の AudioNode
から自分への接続を切断します。 同様にこのノードから他のノードに対するすべての接続参照(3)を解放します。
上記の参照の種類に関わらず、ノードの AudioContext
が削除された時には、もちろん AudioNode
は削除されます。
これはユーザーが聴く事になる最終的な音の出力地点を表す AudioNode
です。 それは多くの場合、スピーカーが接続されているオーディオ出力デバイスと考えられます。 聴こえるべきすべてのレンダリングされた音は AudioContext
のルーティンググラフの"終端点"であるこのノードに導かれます。 AudioDestinationNode は1つの AudioContext
に付き、AudioContext
の destination
属性を介して 1つだけ存在します。
numberOfInputs : 1 numberOfOutputs : 0 channelCount = 2; channelCountMode = "explicit"; channelInterpretation = "speakers";
interface AudioDestinationNode : AudioNode
{
readonly attribute unsigned long maxChannelCount;
};
maxChannelCount
unsigned long 型, readonly
channelCount
属性で設定できるチャンネル数の最大値です。
AudioDestinationNode
(通常は)オーディオハードウェアの終端点を表し、マルチチャンネル対応のハードウェアならば2チャンネル以上の音を出力する事ができます。
maxChannelCount
はハードウェアがサポートできるチャンネル数の最大値です。
もしこの値が 0 ならば channelCount は変更できない事を表します。
これは OfflineAudioContext
の AudioDestinationNode
やハードウェアの基本実装がステレオ出力のみに対応している場合です。
通常の AudioContext
の destination では、channelCount のデフォルト値は 2 であり、0 以外で maxChannelCount
と同じか小さい値に設定する事ができます。
値が有効な範囲外の場合、IndexSizeError
例外を発生します (MUST)。 具体的な例をあげれば、もしオーディオハードウェアが8チャンネル出力をサポートしている場合、channelCount を 8 に設定でき、8 チャンネルの出力が得られます。
OfflineAudioContext
の AudioDestinationNode
については、 channelCount
は OfflineAudioContext が作成された時点で決定され、この値は変更できません。
AudioParam
は AudioNode
の例えば音量のような個別の機能をコントロールします。 パラメータは value
属性を使って特定の値に即時にセットする事ができます。 あるいは(AudioContext
の currentTime 属性の時間軸で) 非常に高い時間精度で値の変化のスケジュールを組む事ができ、エンベロープ、音量のフェード、LFO、フィルタスイープ、グレイン窓、などに応用する事ができます。
このような方法で任意のタイムラインベースのオートメーション曲線をすべての AudioParam
に対して設定する事が可能です。 また更に、 AudioNode
からの出力の音声信号を AudioParam
に接続する事ができ、個別に持っているパラメータの固有値に加算する事ができます。
幾つかの合成や処理の AudioNode
は、オーディオサンプル単位で反映されなくてはならない AudioParams
型の属性を持っています。 その他の AudioParams
はサンプル単位の精度は重要ではなく、その値の変化はより粗く取り込まれます。 各 AudioParam
は a-rate パラメータつまりサンプル単位で反映されるか、それ以外の k-rate パラメータかが指定されます。
実装はそれぞれの AudioNode
について、128 サンプルフレーム毎のブロック単位の処理を行わなくてはなりません。
それぞれの 128 サンプルフレームのブロックに対して、 k-rate パラメータは最初のサンプルのタイミングで取り込まれ、その値は ブロック全体に対して使用されなくてはなりません。 a-rate パラメータはブロック内のサンプルフレーム毎に取り込まれなくてはなりません。
AudioParam
は時間軸に沿ったイベントリストを保持し、その初期値は空になっています。
この時間は AudioContext
の currentTime 属性による時間軸を使用します。 イベントは時刻に対して値を割り付けるものです。
以降のメソッドはメソッド毎に固有のタイプのイベントをリストに新しく加える事でイベントリストを変更します。
それぞれのイベントは対応する時刻を持っており、リスト上で常に時刻順に保持されます。
これらのメソッドはオートメーションメソッドと呼ばれます:
これらのメソッドが呼ばれる時、次の規則が適用されます:
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);
};
defaultValue
float 型, readonly value
属性の初期値です。
value
float 型
浮動小数のパラメータの値です。
この属性の初期値は defaultValue
です。 もし value
がオートメーションイベントが設定されている期間中に設定された場合、それは無視され、例外は発生しません。
この属性を設定した場合の効果は setValueAtTime()
を現在の AudioContext
の currentTime
と値で呼び出すのと同じです。
それ以降のこの属性の値へのアクセスは同じ値を返します。
cancelScheduledValues
startTime
と同じかそれ以降にスケジュールされているすべてのパラメータ変化をキャンセルします。
(与えられた時間よりも小さな startTime
を指定した) アクティブな setTargetAtTime
オートメーション もまたキャンセルされます。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
startTime | double | ✘ | ✘ |
開始時間が同じかそれ以降に設定されていたパラメータ変化のスケジュールをキャンセルする時刻です。
これは AudioContext の currentTime と同じ時間軸の時刻を使用します。
もし 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可 | 省略可 | 説明 |
---|---|---|---|---|
value | float | ✘ | ✘ | パラメータが指数変化により指定された時刻に到達する値です。 この値が 0 より小さいまたは 0、または前のイベントで指定された値が 0 より小さいまたは 0 の場合、NotSupportedError 例外を発生します (MUST)。 |
endTime | double | ✘ | ✘ |
AudioContext の currentTime 属性と同じ時間軸で、指数変化が終了する時刻です。
もし 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可 | 省略可 | 説明 |
---|---|---|---|---|
value | float | ✘ | ✘ | 与えられた時刻にパラメータが直線変化で到達する値です。 |
endTime | double | ✘ | ✘ |
AudioContext の currentTime 属性と同じ時間軸で、オートメーション終了する時刻です。
もし 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可 | 省略可 | 説明 |
---|---|---|---|---|
target | float | ✘ | ✘ | パラメータが指定の時刻から変化を開始する目標値です。 |
startTime | double | ✘ | ✘ |
AudioContext の currentTime 属性と同じ時間軸で指数的漸近を開始する時刻です。
もし start が負の値または有限数でない場合は TypeError 例外を発生します (MUST)。
|
timeConstant | float | ✘ | ✘ |
目標値に漸近する一次フィルター (指数) の時定数の値です。
この値が大きいと変化はゆっくりになります。値は真に正の値(訳注: 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可 | 省略可 | 説明 |
---|---|---|---|---|
value | float | ✘ | ✘ | 指定の時刻にパラメータが変化する値です。 |
startTime | double | ✘ | ✘ |
AudioContext の currentTime 属性と同じ時間軸で与えられた値に変化する時刻です。
もし 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可 | 省略可 | 説明 |
---|---|---|---|---|
values | Float32Array | ✘ | ✘ |
パラメータ値の曲線を表す Float32Array です。
これらの値は与えられた時刻から始まる期間に割り当てられます。
このメソッドが呼び出された時、オートメーションのために曲線の内部的なコピーが作成されます。
そのため、それ以降に渡した配列の中身を変更しても AudioParam に対する効果はありません。
|
startTime | double | ✘ | ✘ |
AudioContext の currentTime 属性と同じ時間軸の曲線の適用を開始する時刻です。
もし startTime が負の値または有限数でない場合 TypeError 例外を発生します (MUST)。
|
duration | double | ✘ | ✘ | ( time (訳注:startTime)以降の) 秒で表される期間の長さであり、 この期間、値は values パラメータに従って計算されます。 |
AudioParam
computedValue はオーディオDSPを制御する最終的な値であり、オーディオレンダリングスレッドがそれぞれのレンダリング時刻に計算します。 内部的には次のように計算されなくてはなりません:
value
属性に直接設定されるか、あらかじめ、またはこの時刻に値の変化スケジュールが設定(オートメーションイベント)されていればこれらのイベントから固有の値が計算されます。 もし、オートメーションイベントがスケジュールされた後に value
属性が設定された場合、これらのイベントは削除されます。 value
属性を読みだした場合は常に現在の固有の値を返します。 もしオートメーションイベントが与えられた期間から削除された場合、 固有 の値は value
属性が直接設定されるか、その期間を対象にオートメーションイベントが追加されるまで、直前の値を保持したままになります。
AudioParam
は AudioNode
の出力が接続されている場合、その出力がモノでなければダウンミックスしてモノに変換し、他の同様に接続されている出力とミックスします。 もし AudioNode
が接続されていない場合はこの値は0となり、 computedValue には影響を及ぼしません。
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);
オーディオ信号のゲインを変える事はオーディオアプリケーションでは基本的な処理です。 GainNode
はミキサーの構成ブロックの1つとなります。 このインターフェースは1つの信号入力と1つの信号出力を持つ AudioNode
です:
numberOfInputs : 1 numberOfOutputs : 1 channelCountMode = "max"; channelInterpretation = "speakers";
GainNode
の入力データの各チャンネルの各サンプルは gain
AudioParam
の computedValue が乗じられます (MUST)。
interface GainNode : AudioNode
{
readonly attribute AudioParam
gain;
};
gain
AudioParam
型, readonly value
は1です(ゲイン変更なし)。名目上の minValue
は 0 ですが、位相反転のために負の値に設定する事もできます。 名目上の maxValue
は1ですが (例外が発生する事なく) より大きな値を設定する事もできます。このパラメータは a-rate です。
ディレイ機能はオーディオアプリケーションの基本的な構成要素です。このインターフェースは単一の入力と単一の出力を持つ 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;
};
delayTime
AudioParam
型, readonly
適用する遅延(単位は秒)の量を表すAudioParam
オブジェクトです。
デフォルト値
は 0 (遅延なし) です。
最小の値は 0 で最大の値は AudioContext
の createDelay
メソッドの引数、 maxDelayTime
で決定されます。
もし DelayNode
が 循環の一部になっている場合、delayTime
属性の最小値は 128 フレーム (1ブロック)にクランプされます。
このパラメータは a-rate です。
このインターフェースはメモリ上に保持されるオーディオのリソース(ワンショットの音やその他の短いオーディオクリップ)を表します。 そのフォーマットは-1 ~ +1の名目上の範囲を持つ非インターリーブのIEEE 32ビット・リニアPCMです。
1つ以上のチャンネルを持つ事ができます。
典型的には、そのPCMデータは適度に(通常1分以内程度に)短いと見込まれます。 音楽の1曲分のような長時間の音に関しては audio
要素と MediaElementAudioSourceNode
によるストリーミングを使うべきです。
AudioBuffer
は1つ以上の AudioContext
で使用される場合があり、また OfflineAudioContext
と AudioContext
で共有する事もできます。
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
);
};
duration
double 型, readonly length
long 型, readonly numberOfChannels
long 型, readonly sampleRate
float 型, readonly copyFromChannel
copyFromChannel
メソッドは AudioBuffer
の指定されたチャンネルから destination
で示される配列にサンプルをコピーします。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
destination | Float32Array | ✘ | ✘ | チャンネルデータをコピーする先の配列です。 |
channelNumber | unsigned long | ✘ | ✘ |
データをコピーするチャンネルのインデックスです。
もし channelNumber が AudioBuffer のチャンネル数よりも大きいまたは等しい場合、IndexSizeError 例外を発生します (MUST)。
|
startInChannel | unsigned long = 0
| ✘ | ✔ |
オプションのオフセットで、コピーをどこから行うかを指定します。もし startInChannel が AudioBuffer の length より大きい場合、IndexSizeError 例外を発生します (MUST)。
|
void
copyToChannel
copyToChannel
メソッドは source
で示される配列から AudioBuffer
の指定されたチャンネルにサンプルをコピーします。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
source | Float32Array | ✘ | ✘ | チャンネルデータをコピーする元の配列です。 |
channelNumber | unsigned long | ✘ | ✘ |
データをコピーする先のチャンネルのインデックスです。もし、 channelNumber が AudioBuffer のチャンネル数よりも大きいまたは等しい場合、IndexSizeError 例外を発生します (MUST)。
|
startInChannel | unsigned long = 0
| ✘ | ✔ |
オプションのオフセットで、コピーをどこへ行うかを指定します。もし startInChannel が AudioBuffer の length より大きい場合、IndexSizeError 例外を発生します (MUST)。
|
void
getChannelData
Float32Array
を返します。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
channel | unsigned long | ✘ | ✘ |
このパラメータはデータを取得するチャンネルのインデックスです。
インデックス値0は最初のチャンネルを表します。
このインデックスは numberOfChannels より小さくなくてはならず(MUST)、そうでない場合 IndexSizeError 例外を発生します(MUST)。
|
Float32Array
copyToChannel
および copyFromChannel
メソッドは より大きな配列に対する view である Float32Array
を渡す事で配列の一部だけを埋める事ができます。
AudioBuffer
のチャンネルから一塊として処理できるデータを読み出す場合、getChannelData
を呼び出して結果の配列にアクセスするよりも 不必要なメモリー割り当てとコピーを避けられるため、copyFromChannel
を使用するべきです。
APIの実装が AudioBuffer
の内容が必要になった時、「AudioBuffer
の内容の取得」の内部処理が起動されます。
この処理は呼び出し元に変更不能なチャンネルデータを返します。
AudioBuffer
の「AudioBuffer
の内容の取得」処理は次のステップで実行されます:
AudioBuffer
の ArrayBuffer
のどれかが無力化されている場合はこれらのステップを中止し、長さ 0 のチャンネルデータを呼び出し元に返します。
AudioBuffer
であらかじめ getChannelData
によって返されている全ての ArrayBuffer
を無力化します。
ArrayBuffer
の下層のデータバッファを保持して、呼び出し元(訳注:API の実装側)に参照を返します。
getChannelData
の呼び出しでは、
データのコピーを持っている ArrayBuffer
を AudioBuffer
に割り当てて返します。
AudioBuffer
の内容の取得」処理は以下の場合に呼び出されます:
AudioBufferSourceNode.start
が呼び出された時、ノードの buffer
の「内容の取得」が行われます。もしこの処理に失敗した場合再生は行われません。
ConvolverNode
で、 node が出力ノードに接続されている状態で buffer
に AudioBuffer
が設定された時、あるいは ConvolverNode
の buffer
に AudioBuffer
が設定されている状態で出力ノードに接続された時、 「AudioBuffer
の内容の取得」が行われます。
AudioProcessingEvent
のディスパッチが完了した時、 outputBuffer
の 「内容の取得」 が行われます。
これは copyToChannel
は AudioNode
が AudioBuffer の内容を取得して現在使用状態にある AudioBuffer
の内容を変更できない事を意味します。AudioNode
は以前に取得したデータを使い続けます。
このインターフェースは 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;
};
buffer
AudioBuffer
型, nullableInvalidStateError
例外を発生します (MUST)。
detune
AudioParam
型, readonly loop
boolean 型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です。
start
start
は1回のみ呼びだす事ができ、呼び出すのは stop
が呼ばれる前でなくてはなりません。
そうでない場合、InvalidStateError 例外を発生します (MUST)。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
when | double = 0
| ✘ | ✔ |
when パラメータは、再生の開始時刻を(秒で)指定します。 これは AudioContext の currentTime 属性と同じ時間軸の時刻を使用します。 もしこの値に 0 、あるいは currentTime よりも小さな値を渡した場合、音は即時に再生されます。
もし when が負の値の場合、TypeError 例外を発生します (MUST)。
|
offset | double = 0
| ✘ | ✔ |
offset パラメータはバッファ中の再生開始位置を(秒で)指定します。
もしこの値に 0 が渡された場合、再生はバッファの先頭から開始されます。
もし offset が負の値の場合 TypeError 例外を発生します (MUST)。
もし offset が loopEnd より大きい場合、再生は loopEnd から始まり (そして即時に loopStart にループし) ます。
このパラメータはバッファのサンプルレートと乗算され、最も近い整数値に丸められる事でバッファ中の正確なサンプルフレームのオフセットに変換されます。
そのため動作は playbackRate パラメータの値に影響されません。
|
duration | double | ✘ | ✔ |
duration パラメータは再生される部分の長さを(秒で)指定します。 もしこの値が渡されなかった場合、再生の長さは AudioBuffer 全体の長さから offset を引いたものになります。
つまり、offset も duration も指定されなかった場合、暗黙的に duration は AudioBuffer 全体の長さとなります。
もし duration が負の値の場合、TypeError 例外を発生します (MUST)。
|
void
stop
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
when | double = 0
| ✘ | ✔ |
when パラメータは、再生の停止時刻を(秒で)指定します。 これは AudioContext の currentTime 属性と同じ時間軸の時刻を使用します。 もしこの値に 0 、あるいは currentTime よりも小さな値を渡した場合、音は即時に停止されます。
もし when が負の値の場合、TypeError 例外を発生します (MUST)。
もし stop が一度呼ばれた後に再度呼ばれた場合、呼び出しの前に既にバッファが停止しているのでなければ、最後の呼び出しのみが適用されて以前の呼び出しで設定された停止時刻は適用されません。
もしバッファが既に停止している時に更に stop を呼び出しても効果はありません。もしスケジュールされている開始時刻より前に停止時刻に到達した場合、再生は開始されません。
|
void
playbackRate
および detune
はどちらも k-rate パラメータであり、共に computedPlaybackRate の計算に使用されます。
computedPlaybackRate(t) = playbackRate(t) * pow(2, detune(t) / 1200)
computedPlaybackRate
はこの AudioBufferSourceNode
の AudioBuffer
が再生されるべき速度になります (MUST)。
これは入力データを 1 / computedPlaybackRate
の率でリサンプリングし、音高と速度を変化させるように実装しなくてはなりません (MUST)。
もし 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)。
それはつまり、サブフレームでのスケジューリングは不可能である事を意味します。
このインターフェースは audio
または video
要素からの音声ソースを表します。
numberOfInputs : 0 numberOfOutputs : 1
出力のチャンネル数は HTMLMediaElement
で参照されるメディアのチャンネル数に対応します。 そのため、メディア要素の .src 属性を変更する事によって、このノードの出力チャンネル数が変化します。 もし .src 属性が設定されていない場合、出力は 1 チャンネルの無音となります。
interface MediaElementAudioSourceNode : AudioNode
{
};
MediaElementAudioSourceNode
は HTMLMediaElement
からAudioContext
の createMediaElementSource()
メソッドを使用して作成されます。
出力は1つでチャンネル数は createMediaElementSource()
の引数として渡された HTMLMediaElement
のオーディオのチャンネル数と同じになります。 もしその HTMLMediaElement
がオーディオを持っていない場合、1となります。
HTMLMediaElement
は MediaElementAudioSourceNode
が作成された後、オーディオが直接、音として再生されなくなる代わりに MediaElementAudioSourceNode
からルーティンググラフを通して再生されるようになる事を除けば、MediaElementAudioSourceNodeを使わない場合と全く同じように振る舞わなくてはなりません。
つまり、ポーズ、シーク、ボリューム、 src
属性の変更、その他 HTMLMediaElement
としての見掛けは MediaElementAudioSourceNode
を使用していない場合と同様に通常どおり働かなくてはなりません。
var mediaElement = document.getElementById('mediaElementID'); var sourceNode = context.createMediaElementSource(mediaElement); sourceNode.connect(filterNode);
HTMLMediaElement
はクロスオリジン・リソースの再生が可能です。 Web Audio はリソースの内容の検査が、
(例えば、 MediaElementAudioSourceNode
や ScriptProcessorNode
を使ってサンプルを読む事で) 可能なので、もしある
origin からのスクリプトが別の
origin からのリソースの内容を検査する事で情報の漏洩が起こり得ます。
これを防ぐため、 MediaElementAudioSourceNode
は、もしその HTMLMediaElement
がフェッチアルゴリズムの実行により
CORS-cross-origin とラベルが付けられている場合、通常の HTMLMediaElement
の出力の代わりに無音を出力しなくてはなりません (MUST)。
AudioWorker オブジェクトは Javascript でオーディオを処理するワーカー"スレッド"のメインスレッドでの表現です。
この AudioWorker オブジェクトは同じタイプの複数のオーディオノードを作成するのに使用されるファクトリになっています。
つまりこれによりコード、プログラムデータ、グローバルな状態をノードをまたいで共有する事が簡単にできます。
AudioWorker はその AudioWorker で処理される個別のノードのメインスレッドでの表現である AudioWorkerNode
のインスタンスを作成するために使用されます。
これらのメインスレッドオブジェクトはオーディオスレッドでのコンテキストの処理をインスタンス化します。 全ての AudioWorkerNode のオーディオ処理はオーディオ処理スレッド内で実行されます。 これは特に注意すべき幾つかの副作用を持っています: オーディオワーカーのスレッドをブロックすると音のグリッジが発生し、(グリッジが起こる可能性を下げるために)もしオーディオ処理スレッドの優先度を上げるなら(ユーザーが供給するスクリプトコードのスレッド優先度の上昇の連鎖を避けるため)通常のスレッドの優先度を格下げしなくてはなりません。
オーディオワーカースクリプトの内部からは、オーディオワーカーのファクトリはノードのコンテキストの情報を表す AudioWorkerGlobalScope
オブジェクトとして、ファクトリで作成された個別のノードは AudioWorkerNodeProcessor
として見えます。
加えて、同じ AudioWorker
で作成された全ての AudioWorkerNode
は AudioWorkerGlobalScope
を共有します。つまりこれにより、それらのノードはコンテキストを共有し、ノードをまたいでデータの共有(例えば、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);
};
onloaded
EventHandler型AudioWorkerGlobalScope
を初期化するためにそのグローバルスコープのコードが実行されます。
onmessage
EventHandler型AudioWorkerGlobalScope
がメインスレッドにメッセージをポストした時に常に呼び出されます。
parameters
array of AudioWorkerParamDescriptor
型, readonly addParameter
この AudioWorker
によって作成される(既に存在するあるいは今後作成される)全ての AudioWorkerNode
に名前に対応したリードオンリーの AudioParam
を付加し、
以降のこれらのノードの AudioProcessEvent
上に現れる parameters
オブジェクトに名前に対応したリードオンリーの Float32Array を付加します。
AudioParam は即時にそのスケジューリングメソッドが呼び出されたり、 .value に値を設定されたり、あるいは AudioNode
から接続されたりするかも知れません。
name
パラメータはそのリードオンリーの AudioParam を AudioWorkerNode に追加する際に使用され、また、以降の AudioProcessEvent
上の parameters
オブジェクトでのリードオンリー Float32Array
の名前として使用されます。
defaultValue
パラメータはその AudioParam
の value 属性のデフォルト値です。そのため、ワーカースクリプトでは(もしパラメータの書き換えや接続によって値が変わらなければ) Float32Array のデフォルトの値として現れます。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
name | DOMString | ✘ | ✘ | |
defaultValue | float | ✘ | ✘ |
AudioParam
createNode
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
numberOfInputs | int | ✘ | ✘ | |
numberOfOutputs | int | ✘ | ✘ |
AudioWorkerNode
postMessage
AudioWorkerGlobalScope
にメッセージを送るために呼ばれます。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
message | any | ✘ | ✘ | |
transfer | sequence<Transferable> | ✘ | ✔ |
void
removeParameter
この AudioWorker
とその AudioWorkerGlobalScope
に結びついた全ての AudioWorkerNode
から、それまでに追加された name
の名前を持つパラメータを削除します。
またこれは名前の付いたリードオンリーの AudioParam
を AudioWorkerNode
から削除し、さらにAudioProcessEvent
の parameters
メンバーからその名前の付いたリードオンリーの Float32Array を 削除します。
この AudioWorker
にその名前のパラメーターが存在しない場合、NotFoundError 例外を発生します。
name
は削除するパラメータを指定します。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
name | DOMString | ✘ | ✘ |
void
terminate
AudioWorkerGlobalScope
に関連するオーディオワーカー内の全ての AudioProcessEvent
のディスパッチを停止しなくてはなりません。
これはまた全ての関連する AudioWorkerNode の処理を停止し、ワーカーのコンテキストも破棄します。実際的な言い方をすれば、これは AudioWorker から作成された全てのノード自体を切断し、全ての意味のある動作を停止させます。
void
AudioWorkerNode
オブジェクトは addParameter
メソッドによって追加されたそれぞれの名前に対応したリードオンリーの AudioParam オブジェクトを持っている事に注意してください。これは動的に行われるため、IDL 表現には含まれていません。
AudioWorker
インターフェースは Worker
から継承されるため、オーディオワーカースクリプトとの通信のために Worker
のインターフェースを実装しなくてはなりません。
このインターフェースはオーディオを直接生成、処理、分析する Worker
スレッドに対して作用する AudioNode
を表します。
ユーザーは AudioWorkerGlobalScope 内に保持される分離されたオーディオ処理のワーカースクリプトを作成し、メインUIスレッドではなくオーディオ処理スレッド内で実行されます。
AudioWorkerNode はメイン処理スレッドのノードグラフ内では処理ノードとして表されます。つまり、AudioWorkerGlobalScope はユーザーのオーディオ処理スクリプトを動作させるコンテキストを表します。
Web Audio の実装は通常オーディオ処理スレッドの優先度をノーマルよりも高くするのが普通である事に注意してください。(ユーザースクリプトはノーマルよりも高い優先度で動作させる事ができないため) AudioWokerNode の利用はオーディオ処理スレッドの優先度を格下げする場合があります。
numberOfInputs : variable numberOfOutputs : variable channelCount = numberOfInputChannels; channelCountMode = "explicit"; channelInterpretation = "speakers";
createAudioWorkerNode()(訳注:createNode()の間違いと思われます) の呼び出しの際に指定された入力と出力のチャンネルの数が初期状態の入出力のチャンネル数(および入出力それぞれに対応して AudioWorkerGlobalScope
内に存在する AudioProcess イベントハンドラーに渡されるAudioBufferのチャンネル数) を決定します)。
numberOfInputChannels
と numberOfOutputChannels
の両方が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;
};
onmessage
EventHandler型postMessage
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
message | any | ✘ | ✘ | |
transfer | sequence<Transferable> | ✘ | ✔ |
void
AudioWorkerNode
オブジェクトはまた、AudioWorker の addParameter
メソッドによって追加された名前付きパラメータ毎に対応したリードオンリーの AudioParam オブジェクトを持っている事に注意してください。これは動的に行われるため、IDL には表現されていません。
このインターフェースは AudioWorkerNodeのAudioParam -- 端的にはその名前とデフォルト値を表します。これは (AudioParamのインスタンスを保持していない) AudioWorkerGlobalScope から AudioParam に対する反復処理を行いやすくします。
interface AudioWorkerParamDescriptor {
readonly attribute DOMString name;
readonly attribute float defaultValue;
};
defaultValue
of type float, readonly name
DOMString型, readonly
このインターフェースは 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;
};
onaudioprocess
EventHandler型AudioWorkerGlobalScope
にディスパッチされる audioprocess
イベントに対応する ([HTML]で説明される) EventHandler
を設定するために使用されるプロパティです。
onnodecreate
EventHandler型AudioWorkerNode
が新しく作成された時に
AudioWorkerGlobalScope
にディスパッチされる
nodecreate
イベントのための ([HTML]で説明されている) EventHandler
を設定するために使用されるプロパティです。
これは AudioNodeProcessor オブジェクトのノードレベルの初期化を行う事を可能にします。
AudioWorkerNodeCreationEvent
がイベントハンドラーにディスパッチされます。
parameters
array of AudioWorkerParamDescriptor
型, readonly sampleRate
float型, readonly AudioContext
のサンプルレートです。
(Worker
内のスコープではユーザーは AudioContext
に直接のアクセスはできません)
addParameter
このファクトリによって作成される(既に存在するあるいは今後作成される)全ての AudioWorkerNode
に名前に応じたリードオンリーの AudioParam
を付加し、 また以降のこれらのノードの AudioProcessEvent
上の parameters
オブジェクトに名前に応じたリードオンリーの Float32Array を付加します。
オーディオワーカーに対してメインスレッドまたはワーカースクリプトのどちらからでも AudioParam が追加(あるいは削除)できる事は意図的なものです。 これは瞬時にワーカーベースのノードとそのプロトタイプの作成する事を可能にするだけでなく、 AudioParam の構成も単一のスクリプトに含んだワーカー全体のパッケージ化も可能にします。 ワーカースクリプトがノードを構成できるように AudioWorkerNode の oninitialized が呼び出された後でのみノードが使用される事が推奨されます。
name
パラメータは
AudioWorkerNode に追加されるリードオンリーの AudioParam の名前として、また以降の AudioProcessEvent
でアクセスできる parameters
オブジェクト上に現れるリードオンリーの Float32Array
の名前として使用される。
defaultValue パラメータは
AudioParam
の value 属性のデフォルト値であり、また
(もし他のパラメータ変更あるいは接続の影響がなければ) ワーカースクリプトの Float32Array にデフォルト値として表れます
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
name | DOMString | ✘ | ✘ | |
defaultValue | float | ✘ | ✘ |
AudioParam
removeParameter
このファクトリで作成されたノードから以前に追加された name
の名前を持つパラメータを削除します。
またこれはこの名前を持つリードオンリーの AudioParam
を AudioWorkerNode
から削除し、さらに以降のオーディオ処理イベントでこの名前を持つリードオンリーの Float32Array も AudioProcessEvent
の parameters
のメンバーから削除します。 このノードにその名前のパラメーターが存在しない場合、NotFoundError 例外を発生します(MUST)。
name
は削除するパラメータを特定します。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
name | DOMString | ✘ | ✘ |
void
このインターフェースをサポートするオブジェクトは AudioWorkerGlobalScope
内でインスタンス化された個別のノードを表します。
これは個々のノードのデータを管理するために設計されています。
複数のオーディオノードのインスタンス間で共有されるコンテキストは AudioWorkerGlobalScope
からアクセス可能です。
このオブジェクトは個々のノードを表し、データストレージまたはメインスレッドとの通信に使用できます。
interface AudioWorkerNodeProcessor : EventTarget {
void postMessage (any message, optional sequence<Transferable> transfer);
attribute EventHandler onmessage;
};
onmessage
EventHandler型postMessage
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
message | any | ✘ | ✘ | |
transfer | sequence<Transferable> | ✘ | ✔ |
void
このセクションは参考情報です
ビットクラッシュはオーディオストリームの音質を下げる機構です -- (整数ベースオーディオの低ビット深度をシミュレートする)値のクオンタイズと(低サンプルレートをシミュレートする)時間方向のクオンタイズの両方を使用します。 この例は AudioWorker 内での AudioParam (この例では a-rateとして処理します)の使い方を示します。
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); } );
// 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; } } };
もう一つのよくある例はクリップ検出とボリュームメーターです。 この例は Workerとの間で (AudioParam スケジューリングを必要としない) 基本的なパラメータの通信とメインスレッドに対してデータを送り返すやり方を示しています。このノードは出力を使用していません。
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 } });
// 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; } };
このワーカーは複数の入力を1つの出力チャンネルにまとめる例を示しています。
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 } );
onaudioprocess= function (e) { for (var input=0; input<e,node.inputs.length; input++) e.node.outputs[0][input].set(e.node.inputs[input][0]); };
このセクションは参考情報です
このインターフェースはJavaScriptによってオーディオを直接、合成、加工、分析する事ができる AudioNode
です。
このノードタイプは廃止予定で、AudioWorkerNode
で置き換えられます -- この文章は実装がこのノードタイプを削除するまでの参考として置いてあります。
numberOfInputs : 1 numberOfOutputs : 1 channelCount = numberOfInputChannels; channelCountMode = "explicit"; channelInterpretation = "speakers";
channelCountMode
は "explicit" からの変更はできず、channelCount
は変更する事ができません。
どちらかを変更しようとすると InvalidStateError 例外を発生します (MUST)。
ScriptProcessorNode
は bufferSize として次の値のどれかで作成されます: 256、512、1024、2048、4096、8192、16384。
この値は audioprocess イベントがディスパッチされる周期とそれぞれの呼び出しで処理が必要なサンプルフレームの数を制御します。
audioprocess
イベントは ScriptProcessorNode
が少なくとも1つの入力か1つの出力が接続されている場合にのみディスパッチされます。
bufferSize が小さいと、latency は低く(良く)なります。
オーディオの途切れや グリッジ を避けるには大きい値が必要になります。
createScriptProcessor
に渡される bufferSize 引数がない、または 0 の場合、実装によって自動的に選択されます。
numberOfInputChannels と numberOfOutputChannels は入力と出力のチャンネル数を決定します。
numberOfInputChannels
と numberOfOutputChannels
の両方が 0 になるのは不正になります。
var node = context.createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels);
interface ScriptProcessorNode : AudioNode
{
attribute EventHandler onaudioprocess;
readonly attribute long bufferSize;
};
bufferSize
long 型, readonly onaudioprocess
が呼ばれる毎に処理が必要なバッファのサイズ(サンプルフレーム数)です。
使用可能な値は (256、 512、 1024、 2048、 4096、 8192、 16384) です。
onaudioprocess
EventHandler 型ScriptProcessorNode
ノードにディスパッチされる
audioprocess
イベントに対する
(HTML [HTML] で説明される) EventHandler
です。
AudioProcessingEvent
型のイベントがイベントハンドラーにディスパッチされます。
これは新しいノードオブジェクトが作成された時に AudioWorkerGlobalScope
オブジェクトにディスパッチされる Event
オブジェクトです。
これにより、 AudioWorkerは ノード・ローカルな (例えばディレイを割り当てたり、ローカル変数を初期化する等の) データの初期化ができます。
interface AudioWorkerNodeCreationEvent : Event {
readonly attribute AudioWorkerNodeProcessor
node;
readonly attribute Array inputs;
readonly attribute Array outputs;
};
inputs
Array 型, readonly node
AudioWorkerNodeProcessor
型, readonly outputs
Array 型, readonly
これは処理を実行するために 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;
};
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 playbackTime
double 型, readonly BaseAudioContext
の currentTime 属性と同じです。
このセクションは参考情報です
これは ScriptProcessorNode
ノードにディスパッチされる Event
オブジェクトです。これは ScriptProcessorNode が削除される時に削除され、代替となる AudioWorker
は AudioProcessEvent
を使用します。
イベントハンドラは (もしあれば) 入力からのオーディオを inputBuffer
属性からデータにアクセスして処理します。 処理結果 (あるいは入力がなければ合成した) オーディオデータは outputBuffer
に出力します。
interface AudioProcessingEvent : Event {
readonly attribute double playbackTime;
readonly attribute AudioBuffer
inputBuffer;
readonly attribute AudioBuffer
outputBuffer;
};
inputBuffer
AudioBuffer
型, readonly numberOfInputChannels
と同じチャンネル数を持ちます。 この AudioBuffer は onaudioprocess
関数のスコープ中でのみ有効です。 その値はスコープの外では意味を持ちません。
outputBuffer
AudioBuffer
型, readonly numberOfOutputChannels
と同じチャンネル数を持ちます。 onaudioprocess
関数スコープ中のスクリプトコードはこの AufioBuffer 中のチャンネルデータが表す Float32Array
配列に 書き込む事が期待されます。 このスコープ外での、この AudioBuffer に対するスクリプトによる変更は何も効果を持ちません。
playbackTime
double 型, readonly AudioContext
の currentTime と同じ時間軸で表された、そのオーディオが再生される時刻です。
このインターフェースは入力されるオーディオストリームの3D空間での 定位 / 空間音響を処理するためのノードを表します。 空間音響は AudioContext
の AudioListener
(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;
};
coneInnerAngle
float 型coneOuterAngle
float 型coneOuterGain
となります。
デフォルトの値は360で、値は 360 の剰余で扱われます。
coneOuterGain
float 型coneOuterAngle
の外側の場合の減衰率です。
デフォルトの値は0です。
これは (dBでなく) リニア値で [0, 1] の範囲になります。
もしこのパラメータがこの範囲外の場合、 InvalidStateError 例外を発生します (MUST)。
distanceModel
DistanceModelType
型PannerNode
で使用される距離モデルを指定します。
デフォルトは "inverse"
です。
maxDistance
float 型panningModel
PanningModelType
型PannerNode
で使用されるバンニングモデルを指定します。
デフォルトは "equalpower"
です。
refDistance
float 型rolloffFactor
float 型setOrientation
3D 空間のデカルト座標系で音源の向いている方向を表します。 音がどれくらいの指向性 ( cone 属性で制御されます) を持っているかによって音が リスナーからはずれると小さくなったり全く聴こえなくなったりします。
x, y, z
パラメータは 3D 空間内での方向を表します。
デフォルトの値は (1, 0, 0) です。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
x | float | ✘ | ✘ | |
y | float | ✘ | ✘ | |
z | float | ✘ | ✘ |
void
setPosition
listener
属性に相対する音源の位置を設定します。
3D のデカルト座標系が使用されます。
x, y, z
パラメータは 3D 空間中の座標を表します
デフォルトの値は (1, 0, 0) です。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
x | float | ✘ | ✘ | |
y | float | ✘ | ✘ | |
z | float | ✘ | ✘ |
void
setVelocity
音源の速度ベクトルを設定します。 このベクトルは 3D 空間内での移動する方向と速度の両方を制御します。 この速度とリスナーの速度の相対値によってどれくらいのドップラー効果 (ピッチの変化) が適用されるかが決定します。 このベクトルの単位はメートル / 秒で、位置や方向ベクトルで使われる単位とは独立しています。
x, y, z
パラメータは移動の方向と大きさを表すベクトルです。
デフォルトの値は (0, 0, 0) です。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
x | float | ✘ | ✘ | |
y | float | ✘ | ✘ | |
z | float | ✘ | ✘ |
void
このセクションは参考情報です。
StereoPannerNode
に対するチャンネル制限が PannerNode
にも適用されます。
このインターフェースは廃止予定です。
これは SpatialListener
で置き替えられます。このインターフェースはオーディオシーンを聴く人の位置と方向を表します。
全ての PannerNode
オブジェクトは BaseAudioContext
の listener
との相対関係により空間処理されます。
空間処理の詳細については 空間配置 / バンニング セクション を参照してください。
interface AudioListener {
void setPosition (float x, float y, float z);
void setOrientation (float x, float y, float z, float xUp, float yUp, float zUp);
};
setOrientation
3D デカルト座標空間でリスナーが向いている方向を表します。 front ベクトルと up ベクトルの両方が与えられます。 簡単のため人間について言えば、front ベクトルはその人の鼻が向いている方向を表します。 up ベクトルはその人の頭頂向いている方向です。 これらは線形独立 (互いに直角) の関係になります。 これらの値がどのように解釈されるかの基準としての要件は空間配置 / バンニング セクションを参照してください。
x, y, z
パラメータは 3D 空間中の front 方向ベクトルであり、デフォルトの値は (0, 0, -1) です。
xUp, yUp, zUp
パラメータは 3D 空間中の up 方向ベクトルであり、デフォルトの値は (0, 1, 0) です。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
x | float | ✘ | ✘ | |
y | float | ✘ | ✘ | |
z | float | ✘ | ✘ | |
xUp | float | ✘ | ✘ | |
yUp | float | ✘ | ✘ | |
zUp | float | ✘ | ✘ |
void
setPosition
3D デカルト座標空間でのリスナーの位置を設定します。
PannerNode
オブジェクトはこの位置と個別の音源との相対的な位置を空間音響のために使用します。
x, y, z
パラメータは 3D 空間内の座標を表します。
デフォルトの値は (0, 0, 0) です。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
x | float | ✘ | ✘ | |
y | float | ✘ | ✘ | |
z | float | ✘ | ✘ |
void
このインターフェースは入力されるオーディオストリームを 3D 空間内に定位させる処理を行うノードを表します。空間定位は AudioContext
の SpatialListener
(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;
};
coneInnerAngle
float型coneOuterAngle
float 型coneOuterGain
となります。 デフォルトの値は360です。
coneOuterGain
float 型coneOuterAngle
よりも外側の場合の音量の減衰率です。 デフォルトの値は0です。
distanceModel
DistanceModelType
型PannerNode
(訳注:SpatialPannerNode) で使用される距離モデルを指定します。デフォルトは "inverse"
です。
maxDistance
float 型orientationX
AudioParam
型, readonly orientationX、 orientationY、 orientationZ
パラメータは 3D 空間内での方向を表します。
orientationY
AudioParam
型, readonly orientationZ
AudioParam
型, readonly panningModel
PanningModelType
型PannerNode
(訳注:SpatialPannerNode) で使用される定位モデルを指定します。デフォルトは "equal-power"
です。
positionX
AudioParam
型, readonly positionY
AudioParam
型, readonly positionZ
AudioParam
型, readonly refDistance
float 型rolloffFactor
float 型
このインターフェースは人がオーディオシーンを聴く位置と方向を表します。
全ての SpatialPannerNode
オブジェクトは AudioContext
のspatialListener
との関係で空間音響処理を行います。
空間音響についての詳細は 空間音響/定位 セクション を参照してください。
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;
};
forwardX
AudioParam
型, readonly forwardX, forwardY, forwardZ
パラメータは 3D 空間内のベクトルを表します。
forward
ベクトルと up
ベクトルはリスナーの方向を決定します。
簡単に人間についての言葉で言えば、forward
ベクトルは人の鼻が指している方向です。
up
ベクトルは人の頭頂が指している方向になります。
これらの値は(お互いに直角であり)線形独立と期待され、そうでなければ予期できない結果をもたらします。
これらの値をどのように解釈するかの基準要件については、空間音響セクションを参照してください。
forwardY
AudioParam
型, readonly forwardZ
AudioParam
型, readonly positionX
AudioParam
型, readonly SpatialPannerNode
オブジェクトはこの位置と個々の音源の相対的な位置関係を空間音響処理に使用します。
デフォルト値は 0 です。このパラメータは a-rate です。
positionY
AudioParam
型, readonly positionZ
AudioParam
型, readonly upX
AudioParam
型, readonly upX, upY, upZ
パラメータは 3D 空間でのリスナーの "up" 方向を指示する方向ベクトルを表します。
この値がどのように解釈されるかの基準要件については、空間音響セクションを参照してください。
upY
span class="idlAttrType">AudioParam
型, readonly upZ
AudioParam
型, readonly 入力されるオーディオストリームに対してローコストなイコールパワー・バンニングアルゴリズムによりステレオでの定位処理を行うノードを表します。このバンニング効果はステレオストリームでの定位を行う方法として一般的なものです。
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;
};
pan
AudioParam
型, readonly このセクションは参考情報です。
処理について上記のような制約があるため、StereoPannerNode
の処理は2チャンネルまでのオーディオのミキシングと2チャンネルのオーディオの生成に限られています。
(訳注:それ以上のチャンネル数を扱いたい場合)
ChannelSplitterNode
を使用し、GainNode
などによるサブグラフでの中間的な処理を行ってChannelMergerNode
を通して再度結合するような処理によって任意のバンニング/ミキシングを実現する事は可能です。
このインターフェースはインパルスレスポンスによって線形コンボリューションエフェクトを 適用する処理ノードを表すインターフェースです。
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;
};
buffer
AudioBuffer
型, nullableConvolverNode
で使用される(マルチチャンネルの場合もある)インパルスレスポンスを保持する モノ、ステレオ、または4チャンネルのAudioBuffer
です。
AudioBuffer
は 1、2、または 4チャンネルでなくてはならずそうでない場合は NotSupportedError 例外を発生します (MUST)。
この AudioBuffer
は AudioContext
と同じサンプルレートでなくてはなりません。
そうでない場合は NotSupportedError 例外を発生します (MUST)。
この属性が設定される際に、buffer と normalize 属性によってこのインパルスレスポンスが与えられた正規化の後、ConvolverNode
の構成に使われます。
この属性の初期値はnullです。
normalize
boolean 型
buffer
属性がセットされた時に等価パワーで正規化してインパルスレスポンスをスケーリングされるかどうかを制御します。
このデフォルトの値は true
で、様々なインパルスレスポンスをロードした時にコンボルバーからの出力レベルを均一化するようになっています。
もし normalize
が false
に設定された場合、インパルスレスポンスの前処理/スケーリングなしでコンボリューションが行われます。 この値を変更した場合、次回に buffer 属性をセットするまで効果は現れません。
もし buffer 属性が設定された時に normalize 属性が false の場合 ConvolverNode
は buffer 内のインパルスレスポンスをそのまま使用して線形コンボリューションを行います。
そうでなく、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 を掛け合わせたバージョンのインパルスレスポンスを作るなど、 何らかの数学的に等価な演算が使用されるかも知れません。
実装は 1 または 2 チャンネルの入力に対する様々なリバーブエフェクトを実現するために次のような ConvolverNode
のインパルスレスポンスのチャンネル構成をサポートしなくてはなりません (MUST)。
図示されている最初の図は一般的なケースで、音源が N 個の入力チャンネル、インパルスレスポンスは K 個のチャンネル、再生システムは M 個の出力チャンネルを持っています。
ConvolverNode
は 1 または 2 チャンネルの入力に限られていますので、全てのケースについて対処できるわけではありません。
単一チャンネルのコンポリューションはモノラルオーディオ入力に対してモノラルインパルスレスポンスを使用してモノラル出力を得ます。
残りの図はモノラルおよびステレオ再生で N と M は 1 または 2、 K は 1 または 2 または 4 の場合です。
開発者がより複雑で任意のマトリックスを必要とするなら ChannelSplitterNode
と 複数の単一チャンネルの ConvolverNode
および ChannelMergerNode
を使用して構成する事もできます。
このインターフェースはリアルタイムの周波数および時間領域の分析を可能にするノードを表します。 オーディオストリームは加工されずに入力から出力に渡されます。
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;
};
fftSize
of type unsigned longfrequencyBinCount
unsigned long型, readonly maxDecibels
float型minDecibels
より小さいか同じ値に設定された場合、IndexSizeError 例外を発生します (MUST)。
minDecibels
float型maxDecibels
よりも大きいか同じに設定された場合、IndexSizeError 例外 を発生します (MUST)。
smoothingTimeConstant
float型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可 | 省略可 | 説明 |
---|---|---|---|---|
array | Uint8Array | ✘ | ✘ | このパラメータは周波数領域の分析データをコピーする場所を示します。 |
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可 | 省略可 | 説明 |
---|---|---|---|---|
array | Uint8Array | ✘ | ✘ | このパラメータは時間領域のサンプルデータをコピーする場所を示します。 |
void
getFloatFrequencyData
現在の周波数データ を渡された浮動小数配列にコピーします。 もし配列が frequencyBinCount
よりも小さい場合、余った要素は捨てられます。もし配列が frequencyBinCount
よりも大きい場合、余剰の要素は無視されます。
周波数データの単位はdBです。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
array | Float32Array | ✘ | ✘ | このパラメータは周波数領域の分析データをコピーする場所を示します。 |
void
getFloatTimeDomainData
現在のダウンミックスされた時間領域(波形)データを渡された浮動小数配列にコピーします。もし配列が fftSize
よりも小さい場合、余った要素は捨てられます。もし配列が fftSize
よりも大きい場合、余剰の要素は無視されます。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
array | Float32Array | ✘ | ✘ | このパラメータは時間領域のサンプルデータをコピーする場所を示します。 |
void
次の式では \(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\)
周波数データの時間軸のスムージング は次のように処理されます:
AnalyserNode
の smoothingTimeConstant
属性とします。
そしてスムージングされた値、\(\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]\) は minDecibels
と maxDecibels
の範囲内にクリップされ、
minDecibels
が 0、maxDecibels
が 255 になるようにスケーリングされます。
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 になります。 "アクティブ"でないどの出力も無音を出力し、通常はどこにも接続されません。
この例ではスプリッターはチャンネルの(例えば左チャンネル、右チャンネルなどの)識別はせず、単純に入力チャンネルの順序に従って出力チャンネルを分割する事に注意してください。
ChannelSplitterNode
を使うアプリケーションの1つは個別のチャンネルのゲインの制御を必要とする "マトリックス・ミキシング" を行うものです。
interface ChannelSplitterNode : AudioNode
{
};
ChannelMergerNode
は高度なアプリケーションで、ChannelSplitterNode
と組み合わせて使われます。
numberOfInputs : Variable N (default to 6) numberOfOutputs : 1 channelCount = 1; channelCountMode = "explicit"; channelInterpretation = "speakers";
このインターフェースは複数のオーディオストリームからチャンネルを結合して1つのオーディオストリームにする AudioNode
を表します。 これは可変数の入力 (デフォルトは 6 ) の入力を持ちますが、全ての入力を接続する必要はありません。 出力は 1 つでそのオーディオストリームは、接続された入力の数のチャンネル数を持ちます。
複数の入力を1つの出力にまとめる時、それぞれの入力は指定のミキシングルールによって1チャンネル(モノ)にダウンミックスされます。 接続されていない入力も1チャンネルの無音としてカウントされて出力されます。 入力ストリームを変える事は出力のチャンネルの順序に影響しません。
ChannelMergerNode
の channelCount
および channelCountMode
を変更する事はできません。変更しようとした場合、InvalidState
例外を発生します (MUST)。
例えば、デフォルトの ChannelMergerNode
に 2 つのステレオ入力を接続した時、1 番目と 2 番目の入力はそれぞれモノラルにダウンミックスされます。
出力は 6 チャンネルのストリームで最初の 2 チャンネルが 2 つの (ダウンミックスされた) 入力に割り当てられ、残りのチャンネルは無音になります。
また、ChannelMergerNode
は複数のオーディオストリームを例えば 5.1 サラウンドシステムのような決まった順序のマルチチャンネルスピーカー配列に合わせて並べるのに使用する事ができます。
マージャーは(左、右等のような)チャンネルの識別を行わず、単純に入力された順序でチャンネルを組み合わせます。
interface ChannelMergerNode : AudioNode
{
};
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;
};
attack
AudioParam
型, readonly value
は 0.003 です。
knee
AudioParam
型, readonly value
は 0 から 40 の範囲中、 30 になっています。
ratio
AudioParam
型, readonly value
は、 1 から 20 の範囲中 12 になっています。
reduction
float 型, readonly release
AudioParam
型, readonly value
は 0.250 です。
threshold
AudioParam
型, readonly value
は -100 から 0 の範囲中、 -24 になっています。
BiquadFilterNode
は非常に一般的な低次フィルタを実装した AudioNode
です。
低次フィルタは基本的なトーンコントロール(バス、ミドル、トレブル)やグラフィックイコライザーやより高度なフィルタを構成するブロックです。 複数の BiquadFilterNode
フィルタを組み合わせてより複雑なフィルタを作る事もできます。 フィルタのパラメータの frequency
などを時間と共に変化させてフィルタスイープやその他の効果を得る事もできます。 それぞれの BiquadFilterNode
は下のIDLで紹介する一般的なフィルタの型のうちの1つに設定する事ができます。 デフォルトのフィルタの型は "lowpass"
です。
frequency
と detune
はどちらも 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/オクターブ のロールオフを持ちます。
|
highpass |
ハイパスフィルタはローパスフィルタの反対の機能を持ちます。 カットオフ周波数よりも高い周波数をそのまま通し、カットオフよりも低い周波数を減衰させます。 これは標準的な2次レゾナントハイパスフィルタの実装で、 12dB/オクターブ のロールオフを持ちます。
|
bandpass |
バンドパスフィルタはある範囲の周波数をそのまま通し、この周波数範囲より上または下の周波数を減衰させます。 これは2次のバンドパスフィルタを実装しています。
|
lowshelf |
ローシェルフフィルタは全ての周波数を通しますが、低い周波数だけを増幅(または減衰)させます。 これは2次のローシェルフフィルタを実装しています。
|
highshelf |
ハイシェルフフィルタはローシェルフフィルタとは反対に、すべての周波数を通しますが高い周波数だけを増幅します。 これは2次のハイシェルフフィルタを実装しています。
|
peaking |
ピーキングフィルタは全ての周波数を通しますが、ある周波数の範囲だけが増幅(または減衰)されます。
|
notch |
ノッチフィルタ (バンドストップまたはバンドリジェクション・フィルタとも呼ばれます) は、バンドパスフィルタの逆の機能です。 ある周波数を除く全ての周波数を通します。
|
allpass |
オールパスフィルタは全ての周波数を通しますが、周波数の変化に対して位相が変化します。 これは2次のオールパスフィルタを実装しています。 |
BiquadFilterNode
の属性は全て a-rate の AudioParam
です。
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);
};
Q
AudioParam
型, readonly detune
AudioParam
型, readonly frequency
AudioParam
型, readonly BiquadFilterNode
が働く周波数で Hz で表されます。デフォルト値は 350Hz で、名目上の範囲は 10Hz から ナイキスト周波数の半分になります。
gain
AudioParam
型, readonly type
BiquadFilterType
型BiquadFilterNode
のタイプです。これ以外のパラメータの正確な意味は type
の値に依存します。
getFrequencyResponse
現在のフィルタパラメータの設定から指定の周波数に対する応答特性を計算します。
3 つのパラメータは同じ長さの Float32Array
でなくてはなりません (MUST)。そうでない場合は InvalidAccessError
例外を発生します (MUST)。
周波数応答は、現在の処理ブロックに対応した AudioParam
によって計算されて返されなくてはなりません (MUST)。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
frequencyHz | Float32Array | ✘ | ✘ |
このパラメータは応答特性を計算する周波数の配列を指定します。 |
magResponse | Float32Array | ✘ | ✘ |
パラメータはリニア振幅特性の値を受け取る配列を指定します。
もし |
phaseResponse | Float32Array | ✘ | ✘ |
パラメータはラジアン単位の位相特性を受け取る配列を指定します。
もし |
void
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 です。
上記の伝達関数内の係数はそれぞれのノードタイプによって異なります。BiquadFilterNode
の AudioParam
の computedValue に基づいて次の中間変数が計算のために必要になります。
AudioContext
の sampleRate
の値とします。
computedFrequency
の値とします。
gain
AudioParam
の値とします。
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*} $$
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*} $$
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);
};
getFrequencyResponse
与えられた現在のフィルターの設定で、指定の周波数における周波数応答を計算します。
Parameter | Type | Nullable | 省略可 | Description |
---|---|---|---|---|
frequencyHz | Float32Array | ✘ | ✘ | このパラメータは応答を計算する周波数の配列を指定します。 |
magResponse | Float32Array | ✘ | ✘ |
このパラメータはリニア振幅応答の出力結果を受け取る配列を指定します。
もしこの配列が frequencyHz よりも小さい場合、NotSupportedError 例外を発生します (MUST)。
|
phaseResponse | Float32Array | ✘ | ✘ |
このパラメータはラジアンでの位相応答の出力結果を受け取る配列を指定します。
もしこの配列が frequencyHz よりも小さい場合、NotSupportedError 例外を発生します (MUST)。
|
void
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 になっています。
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;
};
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" の値は次のステップを実行しなくてはならない事を意味します:
AudioContext
のサンプルレートの 2x または 4x にアップサンプリングします。そのため、それぞれの処理ブロックは 128 サンプルから 256 (2x の場合) または 512 (4x の場合) サンプルになります。
AudioContext
のサンプルレートにダウンサンプリングして戻します。つまり処理された 256 (または 512)のサンプルから 最終的な結果の 128 サンプルを生成します。
正確なアップサンプリングおよびダウンサンプリングフィルターは定められておらず、(低エイリアシング等の)音の品質、低レイテンシー、パフォーマンス等をチューニングする事もできます。
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;
};
detune
AudioParam
型, readonly frequency
を与えられた量だけオフセットします。 デフォルトの value
は 0 です。 このパラメータは a-rate です。
frequency
AudioParam
型, readonly value
は 440 です。このパラメータは a-rate です。
onended
EventHandler 型OscillatorNode
にディスパッチされる ended イベントに対する (
HTML[HTML]で記述される) EventHandler
を設定するために使われる属性です。 OscillatorNode
が再生を終了した時 (例えば停止時刻に到達した時)、 (HTML[HTML]で記述される) イベントタイプ Event
が イベントハンドラにディスパッチされます。
type
OscillatorType
型setPeriodicWave()
メソッドを使用する事ができ、それによってこの属性は "custom" に設定されます。
デフォルト値は "sine" です。属性が設定された時、オシレータの位相は保存されなくてはなりません (MUST)。
setPeriodicWave
PeriodicWave
で与えられる任意のカスタム周期波形を設定します。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
periodicWave |
| ✘ | ✘ |
void
start
AudioBufferSourceNode
で定義されている when
と同じです。(訳注:少し文章がおかしいですが、メソッドの機能自体もAudioBufferSourceNode
と同じです)
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
when | double = 0 | ✘ | ✔ |
void
stop
AudioBufferSourceNode
で定義されているものと同じです。
パラメータ | 型 | Null可 | 省略可 | 説明 |
---|---|---|---|---|
when | double = 0 | ✘ | ✔ |
void
様々なオシレータのタイプのための理想的な数学的波形をここで定義します。 概要としては全ての波形は時間 0 の時に正の傾きを持つ奇関数として数学的に定義されます。 実際にオシレータで生成される波形はエイリアシングの影響を避けるため少し異なったものになります。
$$ x(t) = \sin t $$.
$$ x(t) = \begin{cases} 1 & \mbox{for } 0≤ t < \pi \\ -1 & \mbox{for } -\pi < t < 0. \end{cases} $$
$$ x(t) = \frac{t}{\pi} \mbox{ for } -\pi < t ≤ \pi; $$
$$ 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\) に拡張します。
PeriodicWave は OscillatorNode
で使用される任意の周期波形を表します。 詳細は createPeriodicWave() 、 および
setPeriodicWave() を参照してください。
interface PeriodicWave {
};
PeriodicWaveConstraints
ディクショナリは波形が正規化されるかどうかを指定するために使用されます。
dictionary PeriodicWaveConstraints {
boolean disableNormalization = false;
};
PeriodicWaveConstraints
メンバー disableNormalization
boolean 型, デフォルト値は false
true
ならば波形は正規化されません。そうでなければ波形は正規化されます。
createPeriodicWave() メソッドは 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) $$
これが基本的な (正規化されていない) 波形になります。
デフォルトでは前のセクションで定義された波形は正規化され、最大値が 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} $$
固定値の正規化係数は全ての生成された波形に適用しなくてはなりません。
組み込み済みのオシレータタイプは PeriodicWave
オブジェクトを使用して作られます。
完全性のため、それぞれの組み込みオシレータタイプのための PeriodicWave の係数をここに定めます。
次の記述において、 \(a\) は createPeriodicWave()
で使用するリアル係数の配列で \(b\) はイマジナリ係数の配列です。
全てのケースで波形は奇関数のため、全ての \(n\) に対して \(a[n] = 0\) となります。
また、全てのケースで \(b[0] = 0\) です。そのため、 \(n \ge 1\) の \(b[n]\) だけが以下に規定されています。
$$ b[n] = \begin{cases} 1 & \mbox{for } n = 1 \\ 0 & \mbox{otherwise} \end{cases} $$
$$ b[n] = \frac{2}{n\pi}\left[1 - (-1)^n\right] $$
$$ b[n] = (-1)^{n+1} \dfrac{2}{n\pi} $$
$$ b[n] = \frac{8\sin\dfrac{n\pi}{2}}{(\pi n)^2} $$
このインターフェースは MediaStream
からのオーディオソースを表します。 MediaStream
からの最初の AudioMediaStreamTrack
がオーディオソースとして使用されます。
これらのインターフェースは [mediacapture-streams] に記述されています。
numberOfInputs : 0 numberOfOutputs : 1
出力のチャンネル数は、AudioMediaStreamTrack
のチャンネル数に対応します。 もし有効なオーディオトラックがない場合、1 チャンネルの無音が出力されます。
interface MediaStreamAudioSourceNode : AudioNode
{
};
このインターフェースは 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;
};
stream
MediaStream 型, readonly このセクションは参考情報です。
オーディオ処理グラフについて考える時に重要な事の1つが、各ポイントにおけるゲイン(音量)をどのように調整するかです。 例えば、標準的なミキサー卓モデルの場合、それぞれの入力バスは、プリゲイン、ポストゲイン、センドゲインを持っています。 サブミックスとマスター出力バスもまたゲインコントロールを持っています。 ここで述べるゲインコントロールは他のアーキテクチャーと同じように標準的なミキサー卓に使用する事ができます。
AudioNode
の入力は複数の出力からの接続を受け付ける能力を持っています。 入力はそれぞれの出力を他と足し合わせる、ユニティ・ゲインのサミング接続として振舞います(訳注:複数の信号をそのまま足し合わせる事を指します)。:
各出力のチャンネルレイアウトが一致しない場合は、ミキシング規則に従ってミックス(通常はアップミックス)が行われます。
オーディオグラフ中のダイナミックレンジを最大化するため AudioNode
の入力または出力にクリッピングは適用されません。
多くの場合、それぞれの出力信号のゲインを制御できる事が重要です。 GainNode
によってこのコントロールが可能です:
ユニティ・ゲイン・サミング接続と GainNode という2つの概念を使う事で、簡単な、あるいは複雑なミキシングのシナリオを構成する事が可能です。
複数のセンドとサブミックスを含むルーティングのシナリオでは、ミキサーへのそれぞれの接続について音量または "ゲイン" のわかりやすい制御が必要です。 基本的なレコーディングスタジオに置かれている電子機器の一番単純なものでさえ、そのようなルーティング・トポロジーは非常に一般的に使われます。
これは 2 つのセンド・ミキサーと 1 つののメインミキサーの例です。 可能ではありますが、単純化のため、プリゲインコントロールとインサート・エフェクトは図示していません。:
この図では省略した書き方を使っています。 "send 1"、"send 2"、"main bus" は実際には AudioNode
に入力されますがここではサミングバスとして書かれており、交点にある g2_1、g3_1、などが、あるミキサー上のあるソースの "ゲイン" または音量を表します。 このゲインをコントロールするために GainNode
が使われます。:
上の図を JavaScript で構築したものがこれになります:
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. }
このセクションは参考情報です。 基準情報としての要求事項については AudioContextのライフタイム および AudioNodeのライムタイム を参照してください。
静的なルーティング設定の構築が可能である事に加えて、動的に割り当てられて限られたライフタイムを持つ「ボイス」に対して特別なエフェクトのルーティングを行う事が可能である必要があります。 この議論のためにこれらの短期間だけ存在する音を "ノート" と呼びます。 多くのオーディオアプリケーションがこのノートという考え方を組み込んでおり、例として、ドラムマシン、シーケンサー、多くのワンショットの音がゲームプレイに従ってトリガーされる3Dゲームがあります。
従来のソフトウェアシンセサイザーでは、ノートは使用可能なリソースのプールから動的に割り当てられ、解放されます。 ノートは MIDI ノートオン・メッセージを受信すると割り当てられます。 それはそのノートが発音を終了するか、(もしループ再生でなければ)サンプルデータの終わりに達した時に解放されます。 それは、エンベロープで値が 0 のサスティンフェーズに達したり、 MIDI ノートオフ・メッセージによってエンベロープのリリースフェーズに達したりする事で発生します。 MIDI ノートオフの場合には、そのノートは即時ではなく、リリースエンベロープが終了した時点で解放されます。 どの時間においても、多数のノートが再生中であり、常に新しいノートがルーティンググラフに追加され、古いノートが解放されながらそのノートの組は常に変化しています。
オーディオシステムはそれぞれの "ノート" イベントに対して、ルーティンググラフの一部分の切り落としを自動的に行います。 1 つの "ノート" は1つの AudioBufferSourceNode
で表され、それは直接、他の処理ノードに接続さする事ができます。 ノートが再生を終了した時、コンテキストは自動的にその AudioBufferSourceNode
への参照を解放します。 それによって、そのノードが接続されていた先の全てのノードへの参照が解放され、という風に続きます。 そのノードは自動的にグラフから切断され、全ての参照が無くなった時点で破棄されます。 グラフ内の、長時間存在して動的なボイスから共有されるノードは明示的に管理する事ができます。 複雑なように聞こえますが、これらは全て、特にJavaScriptでハンドリングする必要なく、自動的に行われます。
ローパスフィルタ、パンナー、 2 番目のゲインノードがワンショットの音から直接接続されています。 そのため再生が終わった時、コンテキストは自動的にそれら (点線内の全て) を解放します。 もし JavaScript からワンショットの音とそれに接続されているノードへの参照がもう無ければ、それらはすぐにグラフから外され破棄されます。 ストリーミングのソースはグローバルな参照を持っており、それが明示的に切断されるまで接続されたままで残ります。 JavaScript ではどうなるのかをここに示します:
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); }
このセクションは基準情報です。
3.
ミキサーゲイン構成
では、 AudioNode
の入力が 1 つ以上の AudioNode
の出力からどのように 接続されるかを記述しています。 これらの出力からの接続のそれぞれは、0 以外の特定のチャンネル数を持っています。 入力はそれら全ての接続のチャンネルを組み合わせるためのミキシング規則を持っています。 単純な例としては、もし入力がモノラル出力とステレオ出力から接続されている場合、そのモノラル接続は通常、ステレオにアップミックスされ、ステレオ接続と加算されます。 しかしもちろん、全ての AudioNode
の全ての入力について、その正確なミキシング規則を定義する事が重要です。 全ての入力に対するデフォルトのミキシング規則は、特に非常に良く使われるモノラルとステレオのストリームに対しては、あまり詳細について煩わされる事なく "ちゃんと動作する" ように選ばれます。 しかし、高度な使用例、特にマルチチャンネルの場合にはその規則は変更する事が可能です。
幾つかの用語の定義として、アップミックスは、小さなチャンネル数のストリームを受け取り、 大きなチャンネル数のストリームに変換する処理を指します。 ダウンミックスは、大きなチャンネル数のストリームを受け取り、 小さなチャンネル数のストリームに変換する処理を指します。
AudioNode
の入力は全ての出力からの接続をどのようにミックスするかを決定するために、3 つの基本的な情報を使用します。 この処理の一部として、任意の時刻における、入力の実際のチャンネル数を表す内部的な値、 computedNumberOfChannels
を計算します:
チャンネルのアップミックス、ダウンミックス規則に関わる AudioNode
の属性は 上に定義されています。
以下はそのそれぞれが何を意味しているかの、より正確な仕様です。
channelCount
は computedNumberOfChannels
を計算する補助として使用されます。
channelCountMode
は computedNumberOfChannels
がどのように計算されるかを決定します。 この数が一度計算されると、その数のチャンネル数に全ての接続はアップまたはダウンミックスされます。 ほとんどのノードはデフォルトの値として "max"
を持ちます。
"max"
:
computedNumberOfChannels
は全ての接続のチャンネル数の最大値として計算されます。 このモードでは channelCount
は無視されます。
"clamped-max"
:
"max" と同様ですが、 channelCount
を上限とします。
"explicit"
:
computedNumberOfChannels
の正確な値が channelCount
で指定されます。
channelInterpretation
はそれぞれのチャンネルがどのように取り扱われるかを指定します。
例えば、特定の配置をされたスピーカーや、単なる別々のチャンネルがあります。 この値はまさにアップ、ダウンミックスがどのように行われるかに影響します。
デフォルトの値は "speakers" です。
“discrete”
:
アップミックスの場合、チャンネルを使い切るまで順に埋めて行き、余っているチャンネルには 0 を出力します。 ダウンミックスでは、可能な限りチャンネルを順に埋め、余ったチャンネルは捨てられます。
AudioNode
のそれぞれの入力の実装は次のようにしなくてはなりません:
computedNumberOfChannels
を計算します。
channelInterpretation
に従って computedNumberOfChannels
にアップミックスまたはダウンミックスします。
channelInterpretation
が "speakers" の場合、特定のチャンネル配置に対してのアップミックスおよびダウンミックスが定義されます。
モノ (1 チャンネル)、ステレオ (2 チャンネル)、クワッド (4 チャンネル) そして 5.1 (6 チャンネル) がサポートされなくてはなりません (MUST)。それ以外のチャンネル配置についてはこの仕様で将来サポートされるかもしれません。
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
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;
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
このセクションは参考情報です。
// 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";
どのようなオーディオグラフでも destination ノードにおける全てのオーディオ信号の名目上の範囲は [-1, 1] です。
この範囲外の値の信号、あるいは NaN
、正の無限値、負の無限値のオーディオレンダリングはこの仕様では定義されていません。
最近の 3D ゲームで良く要求される機能として、動的な空間音響と複数の音源の 3D 空間での移動があります。 OpenAL、FMOD、クリエイティブ社の EAX、マイクロソフト社の XACT Audio などのようなゲームオーディオエンジンはこの機能を持っています。
PannerNode
を使って、オーディオストリームを AudioListener
に対する相対的な空間位置に配置し、定位させる事ができます。 AudioContext
は単一の AudioListener
を持っています。
パンナーとリスナーはどちらも右手系デカルト座標の 3D 空間内の位置を持っています。 エフェクトの計算で使われる座標系は、メートルやフィートのような特別な単位とは独立した不変の座標系になっているため、座標空間で使用される単位は定められておらず、その必要もありません。
(ソースストリームの) PannerNode
オブジェクトは音が放出される方向を示す orientation ベクトルを持っています。 加えてそれらは音の指向性の強さを示すサウンドコーンを持っています。 例えば、音が無指向性であれば、方向には関係なくどこからでも聴こえますが、指向性が強い場合、それがリスナーの方向を向いている場合にだけ聴こえます。 (人間の耳を表す) AudioListener
オブジェクトは人間が向いている方向を表すために orientation と up のベクトルを持っています。 音源ストリームとリスナーの両方が移動できるため、それらはどちらも移動の速度と方向を表す velocity ベクトルを持っています。 これらを基にした2つの速度から、ピッチが変動するドップラー効果を作り出す事ができます。
レンダリングの間、 PannerNode
は azimuth と elevation を計算します。 これらの値は空間配置をレンダリングするために実装によって内部的に使用されます。 これらの値がどのように使われるかの詳細については、 パンニングアルゴリズム を参照してください。
PannerNode
の azimuthと elevation を計算するために次のアルゴリズムが使用されなくてはなりません:
// 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;
モノからステレオ と ステレオからステレオ のバンニングがサポートされなくてはなりません。 モノからステレオ の処理は入力への接続が全てモノの場合に使用されます。そうでない場合、は ステレオからステレオ の処理が使用されます。
これは基本的な、簡単で比較的コストの低いアルゴリズムですが、妥当な結果が得られます。
StereoPannerNode
と PannerNode
で panningModel
属性が "equalpower"
に設定されている場合、に使用されます。elevation の値は無視されます。
PannerNode
は次のアルゴリズムが実装されなくてはなりません (MUST)。
アジマスとエレベーションセクションで説明されている azimuth の値を計算します。
次のようにして 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;
モノ入力用に 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)。
pan をこの StereoPannerNode
の pan
AudioParam
の computedValue とします。
pan を [-1, 1] の範囲に制限します。
pan = max(-1, pan); pan = min(1, pan);
モノ入力用に pan の値を [0, 1] の範囲に正規化した x を計算します:
x = (pan + 1) / 2;
ステレオ入力用は次のようになります:
if (pan <= 0) x = pan + 1; else x = pan;
等価パワーバンニングを行うために次のステップが使用されます:
左および右のゲイン値を次のように計算します:
gainL = cos(x * Math.PI / 2); gainR = sin(x * Math.PI / 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; }
この処理には様々な azimuth と elevation で記録された HRTF (Head-related Transfer Function) インパルスレスポンスのセットが必要です。 実装には高度に最適化されたコンボリューション機能が必要になります。 これは "equalpower" よりもコストが必要ですが、より空間的な音を得る事ができます。
近くの音は大きく、遠くの音は小さくなります。 リスナーからの距離に対して正確にどれだけ音量が変化するのかは、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 でスケーリング/増幅し、遠くの音は小さく近ければ大きくします。
リスナーとそれぞれの音源はそれがどの方向を向いているかを表す方向ベクトルを持っています。 それぞれの音源の音の放射特性は、音源の方向ベクトルに対してソース/リスナー間の角度の関数で音の大きさを表した内部および外部の "コーン" で表現されます。 つまり、直接リスナーの方を向いた音源は、違う方向を向いた音源よりも大きく聴こえます。 音源はまた、無指向性に設定する事も可能です。
あるソース(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;
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); } }
このセクションは参考情報です。
Web アプリケーションでは、マウスとキーボードのイベント (keydown、mousedown等) と聴こえる音の間のディレイタイムは重要です。
この時間の遅れはレイテンシーと呼ばれ、幾つかの要因 (入力デバイスのレイテンシー、内部バッファのレイテンシー、DSP処理のレイテンシー、出力デバイスのレイテンシー、スピーカーとユーザーの耳の距離、など) によって引き起こされ、累積されてゆきます。 レイテンシーが大きいとユーザー体験の満足度は下がります。 極端な場合、それは音楽制作やゲームプレイを不可能にする事もあります。 ある程度のレベルになるとそれはタイミングに影響し、音が遅れている、あるいはゲームが反応しないなどの印象を与えます。 音楽アプリケーションではタイミングの問題はリズムに影響します。 ゲームではタイミングの問題はゲームプレイの精度に影響します。 インタラクティブなアプリケーションでは、それは一般的にアニメーションのフレームレートがとても低いのと同じようにユーザー体験を非常に安っぽくします。 満足できるレイテンシーはアプリケーションによって異なり、 3 ~ 6 ミリ秒から 25 ~ 50 ミリ秒程度です。
実装は一般的に全体的なレイテンシーを最小化する事を目指します。
全体的なレイテンシーの最小化とあわせて、実装は一般的に AudioContext
の currentTime
と AudioProcessingEvent
の playbackTime
の差を最小化する事を目指します。
ScriptProcessorNode
が廃止予定となった事でこの考慮はその内問題とならなくなるでしょう。
AudioBuffer
に対して 内容の取得処理が行われる時、処理全体は通常チャンネルデータのコピーをする事なく実装する事ができます。
特に、最後のステップは次の
getChannelData
の呼び出しまで先延ばしにするべきです。
それは (例えば、複数のAudioBufferSourceNode
が同じAudioBuffer
を再生するような) 絶え間ない
getChannelData
による、連続した内容の取得処理がアロケーションやコピーをする事なく実装できる事を意味します。
実装は更に追加の最適化をする事も可能です:
AudioBuffer
に新しいArrayBuffer
が割り当てられておらず、しかし以前のAudioBuffer
に対する内容の取得処理の呼び出し元の全てが AudioBuffer
のデータ使用を止めている場合に、
そのAudioBuffer
に対する
getChannelData呼び出しがあった時、再割り当てやチャンネルデータのコピーを避けてデータバッファの再利用が可能です。
このセクションは参考情報です。
属性に直接値を設定した際、自動的な平滑化が行われない一方で、幾つかのパラメータは直接的な値の設定に対して滑らかな変化が望まれます。
setTargetAtTime
メソッドを低い timeConstant
で使う事で滑らかな変化を実現する事ができます。
オーディオグリッジは正常な連続したオーディオストリームが途切れる事で発生し、大きなクリックノイズやポップノイズを引き起こします。 それはマルチメディアシステムでは最悪の失敗と考えられ、絶対に避けなければなりません。 それは適切な優先度を持っていなかったり時間的制約から起こるスケジューリングの遅延のような事が原因で、オーディオストリームをハードウェアに供給するスレッドの反応速度の問題によって引き起こされる事があります。 また、それはオーディオDSPが与えられたCPUの速度ではリアルタイムで処理できないような多量の仕事をしようとする事で起こる場合もあります。
このセクションは参考情報です。
このセクションは参考情報です。
AudioNode
が持っている様々な情報から、Web Audio API は潜在的に (オーディオハードウェアのサンプルレートのような) クライアントの特徴的な機能の情報を AudioNode
インータフェースを使うどんなページにでもさらけ出します。
更に、AnalyserNode
やScriptProcessorNode
のインターフェースからタイミングに関する情報も得られます。 情報はその後クライアントのフィンガープリントを作成するために使われるかも知れません。
現在の所オーディオ入力についてはこの文書では規定していませんが、クライアント機器のオーディオ入力やマイクへのアクセスを得る事ができます。 これにはおそらく getUserMedia() API が使われますが、ユーザーからの許可を適切に得る事が必要になります。
[webaudio-usecases] を参照してください。
この仕様は 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);
changelog.html を参照してください。