Web Audio APIによる音声(矩形波)出力

現在ドラフト段階にあるWeb Audio APIは、Webページ内のJavaScriptで音声合成やメディアなどの音声ソースに対する音声処理を実現するAPIです。まずは、Web Audio APIによる音声合成(動的な音声データ生成と出力)の基本的な流れを確認するために、JavaScriptで矩形波を生成し、出力してみましょう。

Web Audio APIの中心になるのは、AudioContextです。このAudioContextを通して音声データを保持する各種オブジェクト(ソース)を生成したり、音声を出力します。今回は、一つの音声データを作成し出力するので、流れとしては

  1. AudioContextを作成する
  2. AudioContextから音声データを保持するAudioBufferを取得する
  3. AudioBufferに実際の音声データを書き込む
  4. AudioContextから音声ソースとなるAudioSourceを取得する
  5. AudioSourceのbufferとして音声データを書き込んだAudioBufferを設定する
  6. AudioSourceをAudioContextのdestinationにconnectする
  7. AudioSourceをnoteOnして音声を出力する

という流れになります。

まず、AudioContextを作りますが、現在Web Audio APIはドラフト段階で実装しているブラウザもwebkit系の一部(Chromeと最新版Safari)のみなので、ベンダープリフィックスが必要です。

// AudioContextを作成
var context = new webkitAudioContext();

今回は、サンプリング周波数48KHzでモノラルの音声データを作ってみることにしましょう。AudioContextにデータ形式を設定し、その形式にあわせたAudioBufferも作成します。

// サンプリングレートを48KHzに設定
context.sampleRate = 48000;

// モノラル/48KHz/48000サンプルのAudioBufferを作成
var buf = context.createBuffer(1, 48000, 48000);

これで「48KHzのモノラルPCM波形データ」を保持して再生するための準備ができました。続いて、実際にデータを保持するChannelDataを取得し、書き込んでいきましょう。

波形データは、-1から1の値をとる32ビット浮動小数点の配列の形で設定することになっています。とりあえず、今回は100サンプル周期(周波数480Hz)で-0.5/0.5の値を繰り返す矩形波を書き込んでみましょう。

// データが格納されている配列を取得
var data = buf.getChannelData(0);

// 配列に音声データを書き込む
for (i = 0;i < data.length;i++) {
	if ((i % 100) < 50) {
		data[i] = 0.5;
	} else {
		data[i] = -0.5;
	}
}

音声データができたら、AudioSouceに設定してcontext.destinationから出力します。

Chromeなどの対応ブラウザで下のボタンをクリックすると、サウンドデバイスから480Hzの矩形波が出力されると思います。

JavaScriptのソース全体は、以下のとおりです。

function audioTest() {

	// AudioContextを作成
	var context = new webkitAudioContext();

	// サンプリングレートを48KHzに設定
	context.sampleRate = 48000;

	// モノラル/48KHz/48000サンプルのAudioBufferを作成
	var buf = context.createBuffer(1, 48000, 48000);

	// データが格納されている配列を取得
	var data = buf.getChannelData(0);

	var i;

	// 配列に音声データを書き込む
	for (i = 0;i < data.length;i++) {
		if ((i % 100) < 50) {
			data[i] = 0.5;
		} else {
			data[i] = -0.5;
		}
	}

	// AudioSourceを作成
	var src = context.createBufferSource();

	// AudioSourceに作成した音声データを設定
	src.buffer = buf;

	// 出力先を設定
	src.connect(context.destination);

	// 出力開始
	src.noteOn(0);

}

現在は、Web Audio API対応ブラウザが限定されている状況ですが、標準化と実装が進めばサウンドファイルを用意しなくてもJavaScriptで効果音を作成できるようになるので、楽しみですね。


創作プログラミングの街