読者です 読者をやめる 読者になる 読者になる

音の鳴るブログ

鳴らないこともある

ブラウザから音を出す良さそうなやり方

Web Music Developers JP Advent Calendar 2012 の 5日目の記事です。

最後に

色々なブラウザで使えるリアルタイム信号処理用の簡易インターフェイスを作りました。 Chrome, Safari, Firefox, Opera, IE9, iOS6(*1), ブラウザじゃないけど node.js で動作します。

pico.js - Simple interface for a real-time audio processing

*1 iPhone4S, iPad3 のSafari (UIWebViewではない)で確認しました

記事はここから

さて、タイトルのとおりブラウザから音を出す良さそうなやり方について書こうと思ったのですが、ぶっちゃけたところ現状では良いやり方はありません。WebKit系なら Web Audio APIFirefoxなら Audio Data API というようにブラウザごとにやり方が違ったり、さらには同じAPIでもOSによって動作が違うという一昔前のJavaScriptそのものといった地獄しかないです。

ではどうしたら良いのか?というと

  • 対応ブラウザを限定する
  • 便利なライブラリを使う

のどちらかになると思います。

前者の例でいうと、id:aikeさんの Web Audio APIでギター音源作ったよ とか、カレンダー1日目の FM シンセサイザー by HTML5 Web Audio API とか。 Web Audio APIは機能が豊富なのと、内部がC++なので処理が早い点が魅力的です。あと、テストする環境が絞られるのも地味だけど結構助かります。ただし「Web Audio APIの使い方」を覚えないといけなくて、その知識はWeb Audio APIを使う以外に使い道が無さそうな点が残念です。

で、WebKit系以外のブラウザ、たとえばFirefoxでも音を鳴らしたい場合はAudio Data APIを使うことになるのですが、これはWeb Audio APIに比べるとすごくシンプルです。オーディオファイルの設定、読み込みと書き込みくらいしかできません。何らかの信号処理をしようと思うと自前ですべて書かないといけないのですが、逆にいうと既存の信号処理のやり方がそのまま通用します。

信号処理プログラミングというのはひたすら配列に数字を埋めていくと考えておけば、おおよそ間違いありません。乱数を埋めればホワイトノイズになりますし、もうちょっと気を利かせると音楽っぽくなります。このへんは、昨日のカレンダーの記事 簡単な式で波形生成してみる や、同じく g200kg さんの WebBeeper (コメントつきソース) が参考になりますし、大事なことなので二度言いますが既存の信号処理のやり方がそのまま使えるので、C++, Javaはもちろん、ActionScriptや、さらにはVBScriptなど、あらゆるコードをパクり参考にすることができます。

そういう既存の信号処理のやり方というのはWeb Audio APIでも出来るので、インターフェイスを揃えてやれば、Web Audio APIでもAudio Data APIでも使えるものが作れます。実際そういうやり方でハイブリッドに使えるライブラリとして、プロジェクトページが格好良い Audiolet や、拙作 timbre.js なんかがあります。

ただ、こういうライブラリは使い方を覚えるのが大変だったり、そもそも自分のやりたいことが出来るのかどうかを調べないといけないとかちょっと面倒くさいことがあったりします。それを克服するには結構モチベーションを高めないといけないし、頑張ってモチベーションを高めると結果的に全部自前で信号処理することも平気になります。

ということで、最初に最後にという項で書いたように最低限のインターフェイスだけを用意して信号処理は自分でやりたいという人のためのライブラリを作りました。WebKit系はWeb Audio APIFirefoxはAudio Data API、オプションとしてFlash Player経由やAudioUnit経由で音を鳴らします。(Flash経由のやつはあんまり性能良くないけど)

高機能なライブラリを使うより全部自前で書いたほうが楽かと言えば疑問がありますが、これを使えば、 Web Music Developers JP Advent Calendar 2012 で書かれる信号処理の知見を簡単に試したりできるのではないでしょうか。

次回があれば、ライブラリの中の話「いかにして地獄と付き合うのか」について書きます。