Web Audio APIを利用してオーディオビジュアライザを制作したので、それに関する備忘録です。
まとめて書くと内容が長くなり、複雑で解りにくなりそうなので分けて書いています。
その1は簡単な概要と音声データを読み込んで音を出すところまでです。
Web Audio APIとは
- Audioを扱うAPI。
- AudioNodeを接続して、音(信号)に対して様々な操作ができる。
AudioNodeとは
音量の調整、周波数の解析、フィルタをかけたりと音(信号)に対して様々な操作ができるノード。(モジュールのようなもの)
AudioNodeはいくつでも接続することができ、最終的にはAudioDestinationNode
(出力)に接続して音を出す。
現実世界で言うとマイク(入力)、エフェクタ(フィルタ)、スピーカー(出力)をコードで繋げていくのと同じ。
とりあえず音を出す
デモ(ページを開くと音が流れるので音量注意)
以下のノードを接続して音を出す。
OscillatorNode (入力)
指定した周波数、波形の音(音源)を生成するノード
GainNode (フィルタ)
音量を調整するノード
AudioDestinationNode (出力)
音の出力先(スピーカー)となるノード
ディレクトリ構成
.
├── index.html
└── audio.js
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>とりあえず音を出す</title>
</head>
<body>
<script src="audio.js"></script>
</body>
</html>
audio.js
// AudioNodeを管理するAudioContextの生成
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var oscillatorNode = audioCtx.createOscillator(); // OscillatorNode(入力、音源)を作成
var gainNode = audioCtx.createGain(); // GainNode(フィルタ)を作成
gainNode.gain.value = 0.5; // 音量を小さくする
oscillatorNode.connect(gainNode); // oscillatorNodeをgainNodeに接続
gainNode.connect(audioCtx.destination); // gainNodeをAudioDestinationNode(出力)に接続
oscillatorNode.start(0); // 再生開始
GainNode
を介しているので、本来より音量が小さくなった音がでる。
#音声データを読み込んで音を出す
デモ(ページを開くと音が流れるので音量注意)
音声データを読み込み、以下のノードを接続して音を出す。
AudioBufferSourceNode (入力)
指定したバッファ(音声データ)を音源に設定するノード
AudioDestinationNode (出力)
音の出力先(スピーカー)となるノード
ディレクトリ構成
.
├── index.html
├── audio.js
└── sample.mp3
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>音声データを読み込んで音を出す</title>
</head>
<body>
<script src="audio.js"></script>
</body>
</html>
audio.js
audio.js
は以下のような処理になる。
- XMLHttpRequestを利用して音声データ(バッファ)を読み込む。
- 読み込み完了後、取得したデータをデコードし、それを
AudioBufferSourceNode
で音源に設定する。 -
AudioBufferSourceNode
をAudioDestinationNode
に接続し、再生する。
// AudioNodeを管理するAudioContextの生成
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var Loader = function(url) {
this.url = url; // 読み込む音声データのURL
};
// XMLHttpRequestを利用して音声データ(バッファ)を読み込む。
Loader.prototype.loadBuffer = function() {
var loader, request;
loader = this;
request = new XMLHttpRequest();
request.open('GET', this.url, true);
request.responseType = 'arraybuffer';
request.onload = function() {
// 取得したデータをデコードする。
audioCtx.decodeAudioData(this.response, function(buffer) {
if (!buffer) {
console.log('error');
return;
}
loader.playSound(buffer); // デコードされたデータを再生する。
}, function(error) {
console.log('decodeAudioData error');
});
};
request.onerror = function() {
console.log('Loader: XHR error');
};
request.send();
};
// 読み込んだ音声データ(バッファ)を再生する。
Loader.prototype.playSound = function(buffer) {
var sourceNode = audioCtx.createBufferSource(); // AudioBufferSourceNode(入力)を作成
sourceNode.buffer = buffer; // 取得した音声データ(バッファ)を音源に設定
sourceNode.connect(audioCtx.destination); // AudioBufferSourceNodeをAudioDestinationNode(出力)に接続
sourceNode.start(0); // 再生開始
};
var loader = new Loader('sample.mp3');
loader.loadBuffer();
終わり
その2では再生中の音から波形データを取得してcanvasに描画してみます。
理解が曖昧な気もするため、認識が間違っている場合、ご指摘ください。