ちょっと話題の記事

Web Audio APIをつかった音声処理

2011.11.08

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Web Audio APIとは?

先日参加したGoogle Developers Day 2011で少し紹介されており、興味をもったのでちょっとさわってみました。 Web Audio APIとは、音声処理・合成のためのJavaScript APIです。 いままでWeb上でのオーディオはFlashやQuickTime等のプラグイン経由でしか使うことができませんでしたが、 HTML5でaudio要素が加わり、簡単にブラウザ上でオーディオを扱うことができるようになりました。 今回ご紹介するWeb Audio APIは、それよりも複雑な操作(ミキシング/プロセッシング/フィルタリングなど)を可能にしてくれます。 このAPIを使用すると、Webアプリやゲームにさまざまなサウンドエフェクトを追加することができます。 サンプル紹介ページ※1 には、このAPIを利用して作成されたドラムマシンやエフェクターなどのデモがあります。 現状、これらWeb Audio APIのデモはGoolge Chrome 14以降で動かすことが可能です。 今回は基本的なWeb Audio APIを使用して、mp3の再生を行ってみます。

なお、今回使用した動作環境は以下のとおりです。

  • OS : MacOS X 10.7.2
  • ブラウザ : Google Chrome 15

Web Audio APIの情報源

Web Audio APIについての情報は、HTML5RocksのGetting start ※2があります。 ここではチュートリアル形式でWeb Audio APIについて基本から詳しく解説しています。 今回のサンプルも、ここにあるサンプルを参考に作成しています。 あとはW3CのWeb Audio API仕様 ※3とその日本語訳 ※4があります。これらを参考にすれば、基本的な実装は十分できると思います。

サンプルプログラムを実装する

ではWeb Audio APIのサンプルを実装してみましょう。 今回は二種類のmp3データを用意します。それぞれ、ドラムの音(drm.mp3)とベースの音(bass.mp3)を用意しました。 対応するボタンを押下するとそれぞれのmp3が再生/停止されます。

AudioContextを作成

まずは画面の初期化時にAudioContext(すべての音を管理するためのコンテキスト)を作成します。 その後、BufferLoaderクラス(HTML5Rocksで提供されているこれ) を使用し、用意したmp3をXHRでアクセスし、内容をbufferLoaderに読み込みます。

  window.onload = init;
  var context;
  var bufferLoader;

  function init() {
    context = new webkitAudioContext();
    bufferLoader = new BufferLoader(context,['./bass.mp3','./drm.mp3' ],function(){console.log("finish load.");});
    bufferLoader.load();
  }

bufferLoaderを作成したら、AudioContextからBufferSourceを作成し、そこへmp3の情報などをセットします。 playBass関数が実行されると、context.createBufferSource()でBufferSourceが作成され、ベース音のmp3データがセットされます。 さらに作成したBufferSourceのconnect関数を呼び、出力先(context.destination)をセットし、noteOn関数で再生します。 noteOnに渡している引数は、noteOnがよばれたタイミングからどれくらい後に音を再生するかを秒単位で指定するものです。

var source1;
function playBass() {
    var startTime = context.currentTime + 0.100;
    source1  = playSound(bufferLoader.bufferList[0],startTime);
}

function stopBass() {
    source1.noteOff(0);
}

function playSound(buffer,time) {
    var source = context.createBufferSource();
    source.buffer = buffer;
    source.loop = true;
    source.connect(context.destination);
    source.noteOn(time);
    return source;
}

あとはplayBass関数とstopBass関数をhtmlボタンのonclickで指定すれば、再生と停止を行うことができます。 さらにドラム音のための関数と、両方同時に再生するボタンも用意してみましょう。

var source2;

function playDrm() {
    var startTime = context.currentTime + 0.100;
    source2 = playSound(bufferLoader.bufferList[1],startTime);
}

function stopDrm() {
    source2.noteOff(0);
}

function playBoth() {
    var startTime = context.currentTime + 0.100;
    source1 = playSound(bufferLoader.bufferList[0],startTime);
    source2 = playSound(bufferLoader.bufferList[1],startTime);
}
function stopBoth() {
    source1.noteOff(0);
    source2.noteOff(0);
}

それぞれ個別の再生や、同時再生もできます。 今回は行なっていませんが、エフェクトやボリュームの調整、audioタグからの読み込みも可能です。

まとめ

今回はWeb Audio APIの基本的な部分を使用してみました。 エフェクトなど高度な処理も可能なので、この先Web上でのDAWとかに役立ちそうですね。 Heroku上にnode.js+Web Audio APIの簡単なサンプルを用意してみました。 http://glowing-samurai-8337.herokuapp.com/ 音階を選択してplayを押下すると、ミクさんぽい人がまのびした声で歌ってくれます。

参考サイトなど