この翻訳は不完全です。英語から この記事を翻訳 してください。

この記事では、アプリを経由した音声伝達方法のデザインをする際に、十分な情報に基づいた決断をする助けとなるよう、Web Audio APIの特徴がいかに働いているか、その背後にある音声理論について説明します。この記事はあなたを熟練のサウンドエンジニアにさせることはできないものの、Web Audio APIが動く理由を理解するための十分な背景を提供します。

オーディオグラフ

Web Audio APIは、オーディオコンテキスト内部でのオーディオオペレーションに対するハンドリングを含み、モジュラールーティングを可能とするためにデザインされてきました。基本となる音声操作を成す要素は、オーディオルーチングラフを形作るために、互いに接続されるオーディオノードによります。様々なタイプのチャンネルレイアウトと共に、いくつかの音声源もまた、単一のコンテキスト内部にて支持されています。 このモジュラーデザインは、複雑なオーディオ機能を、ダイナミックな音響効果と共に創造するために必要な柔軟性を与えています。

オーディオノードは、それら入出力を経由し接続され、単一あるいは複数の音声源から開始される一連のチェーンを作り、一つ以上のノードを経由しつつ、最終的な行き先に届き終了します。ただし、たとえば、音声データを視覚化することのみを求める場合などは、このような目的地は省いて構いません。 シンプルで典型的なWeb Audioワークフローでは、以下のようになります:

  1. オーディオコンテキストの作成。
  2. <audio>タグ、オシレーター、ストリーム等といった、該当コンテキスト内での音声源の作成。
  3. リバーブ、バイカッドフィルタ、 パンナーコンプレッサーといった、音響効果用ノードの作成。
  4. 例えばあなたのシステムのスピーカーなど、音声の最終的な行き先の選択。
  5. 音声効果を(あるのならば)かけた後、最後に選択した行き先へ届いて終了する、音声源からの接続の確立。
チャンネルの記法

信号上で利用できるオーディオチャンネルの数字は、2.0や5.1のように、しばしば、数値の形式で表現されます。これはchannel notationと呼ばれます。最初の数値は、該当の信号が含んでいるオーディオチャンネルの数です。ピリオドの後にある数値は、低音増強用出力として確保されているチャンネルの数を示しています。それらはしばしばサブウーファーとも称されます。

A simple box diagram with an outer box labeled Audio context, and three inner boxes labeled Sources, Effects and Destination. The three inner boxes have arrow between them pointing from left to right, indicating the flow of audio information.
各入出力は、互いに特定のオーディオレイアウトを代表する、一つ以上のオーディオチャンネルにより構成されます。個別のチャンネル構造それぞれは、モノラル、ステレオ、クアッド、5.1等を含んでサポートされています。

Show the ability of AudioNodes to connect via their inputs and outputs and the channels inside these inputs/outputs.

音声源はいくつかの方法で取得できます:

  • JavaScript内部で(オシレーターのような)オディオノードにより、直接音声を生成。
  • 未加工のPCMデータから生成(この場合、該当オーディオコンテキストは、対応している音声フォーマット形式へのデコード手段を有しています)。
  • (<video><audio> のような)HTML media elementsより取得。
  • (webcamやマイクロフォンのような)Web RTC  MediaStream により直接取得。

オーディオデータ: サンプルとは?

オーディオシグナルのプロセス中では、サンプリングとは連続的な信号離散的な信号へ変換することを意味します。あるいは別の言い方をすると、バンドのライブ演奏のような連続的な音波を、コンピューターがその音声を区別されたブロックで処理できるようになる(離散時間信号の)一連のサンプルに変換します。

より詳しい情報は、WikipediaのSampling(Signal processing)から見ることができます。

オーディオバッファー: フレーム、サンプル、チャンネルセクション

AudioBufferは、チャンネルの数(モノラルの場合は1,ステレオの場合は2、等)、バッファー長すなわちバッファーに格納されているサンプルフレーム数、サンプルレートすなわち1秒間に再生されるサンプルフレーム数を、そのパラメーターとして持っています。

例として、float32型の値1つは、(ステレオの場合は左側あるいは右側といった)特定のチャンネルにおいて、各特定時点おけるオーディオストリームの値を表しています。フレームまたはサンプルフレームは、一定時点における、音声を再生する全チャンネル分の値全てのまとまりです。 全チャンネルの全サンプルが一緒に再生されます(ステレオならば2チャンネル分、5.1ならば6チャンネル分、等)。

サンプルレートとは、1秒間に再生される、それらサンプルの数(または、1フレームのサンプル全てが同時に再生させることから、フレーム)であり、単位はHzで測定されます。サンプルレートが高まるにつれ、音質は向上します。

モノラルとステレオのオーディオバッファーを見てみましょう。それらは1秒間、44100Hzで再生されます。

  • モノラルバッファーは44100サンプル、44100フレームで構成され、lengthプロパティは44100となる。
  • ステレオバッファーは88200サンプル、44100フレームで構成され、lengthプロパティは、そのフレーム数に等しいため44100のままである。

A diagram showing several frames in an audio buffer in a long line, each one containing two samples, as the buffer has two channels, it is stereo.

バッファが再生されると、最も左のサンプルフレームが聞こえ、次にそのサンプルフレームのすぐ隣のサンプルフレームが続いてゆきます。ステレオの場合、両方のチャンネルから同時に聴こえます。サンプルフレームは、チャンネルの数とは独立しているため非常に便利であり、正確に音声を取り扱う有効な手段として、時間を表現してくれます。

注: フレーム数から秒数を得るためには、フレーム数をサンプルレートで単に除算するだけです。サンプル数からフレーム数を得るためには、チャンネル数で単に除算するだけです。

以下はいくつかの単純なサンプルです:

var context = new AudioContext();
var buffer = context.createBuffer(2, 22050, 44100);

注: デジタルオーディオにおいて、44100Hz(44.1kHzとも表記される)は一般的なサンプリング周波数です。なぜ44.1kHzなのでしょう? 

第一に、人間の耳の可聴範囲は、大雑把に20から20000Hzの範囲です。Nyquist-Shannonのサンプリング定理により、サンプリング周波数は再現したい最大周波数の2倍以上でなくてはなりません。したがって、サンプリングレートは40kHz以上でなくてはなりません。

第二に、シグナルはサンプリング前に、偽信号の発生をさせないため、ローパスフリタリングされていなければなりません。理想的ローパスフィルターが20kHz以下の周波数を(減衰させずに)完璧に通し、20kHz以上の周波数を完璧に遮断する一方で、実際には、周波数が部分的に減衰する場所となる、トランジションバンドが必要です。このバンドが広くなるにつれ、減衰フィルターを作るのは簡単かつ効率的になります。44.1kHzサンプリング周波数は、2.05kHzのトランジションバンドを与えます。

この呼び出しをする場合、チャンネル数2のステレオバッファーを取得し、AudioContext上で(非常に一般的で、通常のサウンドカードではほとんどはレートとなる)44100Hzにて再生される音源が、0.5秒間続きます: 22050 フレーム/44100Hz = 0.5 秒。

var context = new AudioContext();
var buffer = context.createBuffer(1, 22050, 22050);

この呼び出しをする場合、モノラルバッファーをチャンネル数1で取得し、
AudioContext上で44100Hzにて再生される際に自動で44100Hzへ再サンプリングされ(したがって44100フレームとなり)、1秒間続きます: 44100 フレーム/44100Hz = 1 秒。

注: オーディオの再サンプリングは、画像のサイズ変更と非常に似たものです。例えば16x16の画像があり、32x32のスペースを満たしたいとします。サイズ変更(あるいは再サンプリング)を行い、結果として(サイズ変更アルゴリズムの違いに依存して、ぼやけたりエッジができたりと)画質の低下を伴いますが、スペースを減らすサイズ変更済み画像が作れます。再サンプリングされたオーディオもまったく同じです。スペースを保てるものの、実際には高音域のコンテンツや高音を適切に再現することはできません。

バッファーセクションの平面性対交差性

Web AudioAPIは平面的なバッファー形式を採用しています。左右のチャンネルは、以下のように格納されています:

LLLLLLLLLLLLLLLLRRRRRRRRRRRRRRRR (for a buffer of 16 frames)

これは音声処理における一般的な形式です: これにより各チャンネルの独立した処理が簡単になります。

代わりの方式としては、交差的な形式が用いられます:

LRLRLRLRLRLRLRLRLRLRLRLRLRLRLRLR (for a buffer of 16 frames)

この形式は、大掛かりな処理を必要としない音声を、格納し再生する目的として一般的です。例えばデコード済みMP3音楽ストリームなどがあります。

Web Audio APIは、音声処理に適することを理由に、平面的なバッファーのみを採用しています。通常は平面的ですが、再生用に音声がサウンドカードへ送られる際は、交差的に変換されます。反対に、MP3音声がデコードされる場合、元々は交差形式だったものの、音声処理のため平面形式へと変換されます。

オーディオチャンネル

異なるオーディオバッファーでは、それぞれ異なった数のチャンネルを含んでいます: より基本的なモノラルとステレオ(それぞれチャンネル数1と2)から始まり、より複雑なクアッドもしくは5.1のような、異なるサウンドサンプルが各チャンネルに含まれ、よりリッチな音声体験を導くセットもあります。チャンネルは通常、以下のテーブルに示される、標準的な略語によって示されます:

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

アップミキシングとダウンミキシング

入力と出力のチャンネル数が一致しない場合、以下のルールに基づいてアップミキシングまたはダウンミキシングが行われます。 これはAudioNode.channelInterpretation プロパティを speakers またはdiscreteへとセットしてコントロールできます。

説明 入力チャンネル 出力チャンネル ミキシングルール
speakers 1 (Mono) 2 (Stereo) モノラルからステレオへのアップミックス。M入力チャンネルは(LRの)両出力チャンネル用に使われます。
output.L = input.M
output.R = input.M
1 (Mono) 4 (Quad) モノラルからクアッドへのアップミックス。M 入力チャンネルは(LRの)ノンサラウンド出力チャンネル用に使われます。(SLSRの)サラウンド出力チャンネルは無音です。
output.L = input.M
output.R = input.M
output.SL = 0
output.SR = 0
1 (Mono) 6 (5.1) モノラルから5.1.へのアップミックス。M 入力チャンネルは(Cの)ノン中央出力チャンネル用に使われます。 その他全ての(LRLFESLSR)出力チャンネルは無音です。
output.L = 0
output.R = 0

output.C = input.M
output.LFE = 0
output.SL = 0
output.SR = 0
2 (Stereo) 1 (Mono) モノラルからステレオへのダウンミックス。(LRの)両入力チャンネルは等しく結合され、単一出力チャンネル(M)になります。
output.M = 0.5 * (input.L + input.R)
2 (Stereo) 4 (Quad) ステレオからクアッドへのアップミックス。左右(LR)入力チャンネルはそれぞれ(LRの)ノンサラウンド出力チャンネル用に使われます。(SLSRの)サラウンド出力チャンネルは無音です。
output.L = input.L
output.R = input.R
output.SL = 0
output.SR = 0
2 (Stereo) 6 (5.1)

ステレオから5.1.へのアップミックス。左右(LR)入力チャンネルはそれぞれ(LRの)ノンサラウンド出力チャンネル用に使われます。(SLSRの)サラウンド出力チャンネル、中央チャンネル(C)、サブウーファー(LFE)は全て同様に無音です。
output.L = input.L
output.R = input.R
output.C = 0
output.LFE = 0
output.SL = 0
output.SR = 0

4 (Quad) 1 (Mono) クアッドからモノラルへのダウンミックス。(LRSLSR)入力チャンネルは等しく結合され、単一出力チャンネル(M)になります。output.M = 0.25 * (input.L + input.R + input.SL + input.SR)
4 (Quad) 2 (Stereo) クアッドからステレオへのダウンミックス。両左入力チャンネル(LSL)は等しく結合され、単一左出力チャンネル(L)になります。同様に、両右入力チャンネル(RSR)は等しく結合され、単一右出力チャンネル(R)になります。
output.L = 0.5 * (input.L + input.SL)
output.R = 0.5 * (input.R + input.SR)
4 (Quad) 6 (5.1) クアッドから5.1.へのアップミックス。(LRSLSR)入力チャンネルはそれぞれ(LRの)出力チャンネル用に使われます。中央チャンネル(C)、サブウーファー(LFE)は無音です。
output.L = input.L
output.R = input.R
output.C = 0
output.LFE = 0
output.SL = input.SL
output.SR = input.SR
6 (5.1) 1 (Mono)

5.1.からモノラルへのダウンミックス。左チャンネル(L, SL)、右チャンネル(RSR)、中央チャンネルはそれぞれ混合されます。 サラウンドチャンネルは僅かに減衰され、標準側面チャンネルは利用のために、単一チャンネルを√2/2で乗算したものとして出力が補強されます。 サブウーファー(LFE)チャンネルは失われます。
output.M = 0.7071 * (input.L + input.R) + input.C + 0.5 * (input.SL + input.SR)

6 (5.1) 2 (Stereo)

5.1.からステレオへのダウンミックス。中央チャンネルは各側面サラウンドチャンネル(SLSR)と合算され、各側面チャンネルへ混合されます。 2チャンネルへとミックスダウンされる過程は低労力で行われ、各々の場合について、√2/2で乗算されます。 サブウーファー(LFE)チャンネルは失われます。
output.L = input.L + 0.7071 * (input.C + input.SL)
output.R = input.R
+ 0.7071 * (input.C + input.SR)

6 (5.1) 4 (Quad) 5.1.からクアッドへのダウンミックス。中央チャンネルは各側面ノンサラウンドチャンネル(LR)と合算され、各側面チャンネルへ混合されます。 2チャンネルへとミックスダウンされる過程は低労力で行われ、各々の場合について、√2/2で乗算されます。 サラウンドチャンネルへの伝達には変化がありません。 サブウーファー(LFE)チャンネルは失われます。
output.L = input.L + 0.7071 * input.C
output.R = input.R + 0.7071 * input.C
output.SL = input.SL
output.SR = input.SR
その他、非標準レイアウト

非標準チャンネルレイアウトは、channelInterpretation

discreteへセットしたものとして操作されます。新たなスピーカーレイアウトの将来的な定義を、仕様書でははっきりと認めています。従ってこの予備部分は、チャンネルに用いられる特定の数字が示すブラウザの挙動が、将来的に変更された場合のために用意されたものではありません。

discrete 各 (x) 各 (y) (x<y の場合) 離散チャンネルのアップミックス。各出力チャンネルに、それに対応する同番号の入力チャンネルによる入力をします。対応する入力チャンネルが存在しないチャンネルは無音になります。
各 (x) 各 (y) (x>y の場合) 離散チャンネルのダウンミックス。各出力チャンネルに、それに対応する同番号の入力チャンネルによる入力をします。 対応する出力チャンネルが存在しない入力チャンネルは無視されます。

視覚化

原則、オーディオ視覚化は出力オーディオデータ(基本的にはゲインまたは周波数データ)に時間毎にアクセスすることで行われ、更にグラフなどの視覚化出力へ渡すためのグラフィカル技術が用いられます。TWeb Audio APIはAnalyserNodeで、経由して渡されたオーディオ信号を変換せず利用することができます。 ただしその出力は、<canvas>などのような視覚化技術へ受け渡せるオーディオデータです。

Without modifying the audio stream, the node allows to get the frequency and time-domain data associated to it, using a FFT.

以下のメソッドを利用して、データの取得が可能です。

AnalyserNode.getFloatFrequencyData()
現在の周波数データを渡されたFloat32Array型配列にコピーします。
AnalyserNode.getByteFrequencyData()
現在の周波数データを渡されたUint8Array型配列(符号なしバイト配列)にコピーします。
AnalyserNode.getFloatTimeDomainData()
現在の波形データまたはタイムドメインデータを渡されたFloat32Array型配列に
コピーします。
AnalyserNode.getByteTimeDomainData()
現在の波形データまたはタイムドメインデータを渡されたUint8Array型配列(符号なしバイト配列)にコピーします。

: より詳しい情報は、Web Audio API記事中のVisualizations with Web Audio APIを参照してください。

立体化

(Web Audio APIのPannerNodeAudioListenerノードによって操作される)立体音響化によって、オーディオシグナルの、空間を介した点における位置や振る舞いをモデル化することができ、その音声をリスナーが聞くことができます。

パンナーの位置は、直行座標の右側に描かれています。ドップラー効果を作るに必要な、速度ベクトルを用いた移動、そして方向コーンを用いた方向性があります。このコーンは、例えば無指向性音源などのため、とても大きくなり得ます。

The PannerNode brings a spatial position and velocity and a directionality for a given signal.

リスナーの位置は、直行座標の右側に描かれています。度ベクトルを用いた移動と、リスナーの頭がポイントされている(頭部側と顔面側の)二方向ベクターを用いた方向性があります。これらはそれぞれリスナーの頭部の頂点からの方向と、リスナーの鼻にポイントされている方向とを定義しており、これらは直角となっています。

The PannerNode brings a spatial position and velocity and a directionality for a given signal.

: 注: より詳しい情報は、Web audio spatialization basics を参照してください。

ファンインとファンアウト

オーディオ用語では、fan-inChannelMergerNodeが一連の単一入力ソースを受け、単一マルチチャンネル信号を出力するプロセスを意味します。

Fan-outはその対となるプロセスを意味します。ChannelSplitterNodeが一つのマルチチャンネル入力源を受け、複数のモノラル出力信号を出力します。

ドキュメントのタグと貢献者

このページの貢献者: nelly-n
最終更新者: nelly-n,