
Edge AnimateはJavaScriptを使っているので、JavaScriptで出来ることなら何でも追加できます。(ん?)
多少なりとも音楽を習得した者として"Web Audio API"を使わない手はありません。
このAPIを使えば、ブラウザで(つまりiPadやAndroidでも!)ドラムマシンやシンセが作れちゃうんですよ?
というわけでWeb Audio APIを0から解説してみようかと思います。
まず、Web Audio APIってなんぞやっていうところから。
Web Audio APIってのは「webページでゲームやシンセアプリが作れちゃうスゴイやつ!」と理解しておけば大体OKです。
もうちょい詳しく言うと「オシレーターが作れたり、フィルターやリバーブなどのエフェクターが使えたり、レイテンシーを小さくできたりするスゴイやつ」のことです。
HTML5には、単純なオーディオ再生のタグ<audio>が用意されています。
普段よくみるオーディオプレイヤーの形をしたものを想像してもらえば、だいたい合っています。
オーディオファイルを読み込んで再生したり、一時停止したり、シークしたり。
このaudioタグは扱いが簡単なんですが、それではゲームやシンセアプリのような複雑なものは作れないので、より高機能なAPI(拡張プログラムみたいなものです)が作られました。
それがWeb Audio APIです。
まあ、JavaScriptが”基礎魔法”だとするとWeb Audio APIは”風属性の上級魔法”みたいなものです。
どうです?なんかよくわからないけどカッコよさそうでしょう?w
では、さっそく、その”上級魔法”の”呪文”を唱えてみましょう。
一番簡単な「音声ファイルを再生する」呪文はこうです。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//=============================ステップ1===================================== | |
//XMLHttpRequest (XHR) は、非同期なデータの通信(Ajax)を実現するための API | |
var xhr = new XMLHttpRequest(); | |
//(HTTPメソッド、アクセス先URL、非同期通信)を指定する | |
var url = "xxx/xxx.mp3"; | |
xhr.open('GET', url, true); | |
//arraybuffer バイナリで読み込む | |
xhr.responseType = 'arraybuffer'; | |
//XHR通信を開始 | |
xhr.send(); | |
//==============================ステップ2====================================== | |
//audioContext(オーディオ環境)インスタンスを作る | |
context = new webkitAudioContext(); | |
//HXR通信が成功した時のイベント .onload XHR通信が成功したときのみ実行される | |
xhr.onload = function(){ | |
//バイナリをデコード hxr.response(読み込んだバイナリデータ)function(buffer)(コールバック関数) | |
context.decodeAudioData(xhr.response, function(buffer){ | |
//decodeAudioData()の処理が完了した際に、コールバック関数が呼ばれ、デコード済みの波形データがbufferに入る | |
decodedBuffer = buffer; | |
}); | |
} | |
//===============================ステップ3====================================== | |
//オーディオバッファソースノードを作成(使い捨て) | |
var source = context.createBufferSource(); | |
//バッファソースノードにデコードした波形データを渡す | |
source.buffer = decodedBuffer; | |
//バッファソースノードとディスティネーションノードを接続 | |
source.connect(context.destination); | |
//音声再生 start(開始時間(秒), オフセット, デュレーション) | |
source.start(0); |
さすが上級呪文。
一目見ただけではさっぱりわからないと思いますw
でも、これが一番シンプルな呪文なんですよ。
上の呪文のステップ1と2をEdge AnimateのStageに、ステップ3を適当なクリックイベントにコピペしてオーディオファイル名を指定すれば、魔法が発動します。
では、もう少し真面目に踏み込んだ解説をしましょうか。
まず、この「音声ファイルを再生する」コードは3つのステップに分かれています。
ステップ1は音声ファイルの読み込みです。
Web Audio APIはwavやmp3、oggなどのファイルが扱えますが、XHR(XMLHttpRequest)を使ってバイナリで読み込む必要があります。
ちなみに、XHRならオーディオのロードとは見なされないので”オーディオのプリロード禁止”というモバイルブラウザ特有の制限に引っかからないという大きな利点があります。
ステップ2はXHR通信が完了したときの処理です。
Web Audio APIのAudioBufferSourceNodeは一般的な音声ファイルをそのまま再生することができません。
なので、audioContextインスタンスを作ってからdecodeAudioData()でデコードして、プレーンな波形データにしてやらなければいけません。
手間はかかりますが、事前にデコードできる分、再生は高速に処理できます。
ステップ3は再生です。
Web Audio APIはノードと呼ばれる複数のモジュールを接続して最終的に音声が出力されます。
例えるならモジュラーシンセのパッチングみたいなものです。
オシレーターとフィルターをつなげてから、アンプを通して…といった具合です。
ここでは単純に波形ソースを最終出力(distination)へconnect()しています。
最後にstart()すれば音が鳴る、というわけです。
んー、ややこしいですねw
<audio>タグなら読み込んで再生するだけなので簡単ですが、Web Audio APIは読み込み、デコード、ノード生成、ノード接続、そして再生と細かく記述しなくてはいけません。
でも、だからこそ、<audio>タグより高速で、高機能なのです。
最終的に、このブログで「パッドサンプラー」や「ドラムマシン」を作ってみるつもりです。
