音楽の覚えがあるエンジニアとしては、触らなきゃダメだろーと思いつつ、なかなか手を付けられていなかったWebAudioAPI、
先日のハッカソンでようやく着手できました。
その過程でわかったこと・つくったものなどまとめました。
登場人物
HTML5のAudio要素を使う時と違って、
WebAudioAPIの場合は、使っているオブジェクトがけっこう多い。
そのあたりを把握するのが、WebAudioAPIのマスターの第一歩っぽい。
context (AudioContext)
音をとりまとめるcontext。
音の再生先(destination)なんかも、このcontextが握っているみたい。
WebAudioAPIに対応しているブラウザは、
window.AudioContext (window.WebkitAudioContext)というのが生えてるので、
これをインスタンス化すると作れる。
var context = new window.AudioContext();
buffer
再生する音のデータ。
.wavなど外部のファイルを使う場合は、
- XMLHttpRequest(responseType: arraybuffer で!)で読み込む
- 読み込んだものを、contextにdecodeしてもらう (
context.decodeAudioData
)
という流れでできる。
// ここにbufferを格納したい
var buffer;
// ファイルを取得 (arraybufferとして)
var request = new XMLHttpRequest();
request.open('GET', '/sounds/sample.wav', true);
request.responseType = 'arraybuffer';
request.send();
request.onload = function () {
// 読み込みが終わったら、decodeしてbufferにいれておく
var res = request.response;
context.decodeAudioData(res, function (buf) {
buffer = buf;
});
};
source
こうして作ったbufferを再生するためには、sourceというものを作る。
これもcontextに生えているメソッドを使う。(context.createBufferSource
)
// source作成
var source = context.createBufferSource();
// さきほど作ったbufferを、ここにセット
source.buffer = buffer;
// 再生準備。contextの持っている再生先に接続
source.connect(context.destination);
// 再生 (引数はtimeout)
source.noteOn(0);
たとえば、できること
音の高さを変える
厳密にはピッチ変更ではないけれど、
単発の音を鳴らすのであれば、sourceのplaybackRate.valueをいじればおk。
気をつけること
sourceは使い捨て
sourceは、 再生するたびに生成して、使い捨てるというかたち になっている。
最初は、つくったsourceに対して何度も .noteOn
したりできるのかと思ってた。
一度は、ユーザーアクションをトリガーにして、音再生させないとだめ。
逆に言えば、1度タップのタイミングなどで再生をさせてしまえば、 その後は好きなタイミングで鳴らし放題 なもよう。
その辺の挙動から、「ユーザーアクションで再生許可」は、おそらくcontextに紐付いてるんじゃないかなぁという印象。
(source単位での許可だとすると、sourceは再生のたびに使い捨ててるので、再生のたびに許可が必要なはず)
ちゃんとしらべてないけど。
ちなみに、ユーザアクションから間接的に音再生呼んだ場合、
(clickのlistenerでsetTimeout通して音再生、とか)
なんかときどき再生できちゃってたけれど、
確実に鳴らしたいなら、やっぱり1度は直接再生呼び出しした方がいいみたい。
つくったもの
DripMetro
先日のハッカソンで作ったもの。
ぴちょんぴちょん言うメトロノーム。
いちおうBPMを上げるほど、音も高くなるようにしてます。
ToneMap
↑のDripMetroを作る過程でできた、WebAudioAPIのwrapper。
(wrapperとはいえ、もうすこし機能追加するつもり)
複数の音源を使う場合でも、やりやすくなる…はず。
デモでは、
画面タッチで音再生→スワイプのスピードに応じて音を高く
っていうのやってます。
まとめ
- たのしい
- ↓のデモなど見ても思うけれど、iOSは十分にWebAudioAPIつかえるっぽい
- 音をばしばしつかったスマホサイトなんかも、挑戦したいなぁ
参考とかっこいいデモ
-
http://jlongster.com/2012/09/12/web-apps.html
- iOSでもぬるぬる動くデモあり すごい!
-
http://mohayonao.github.io/timbre/
- WebAudioAPIをつかって、sin波を鳴らすライブラリ。べんりそう。
-
http://mohayonao.hatenablog.com/entry/2012/09/21/203833
- ↑のtimbre.jsのひとの、iOS WebAudioAPIのはなし。
-
http://www.html5rocks.com/en/tutorials/webaudio/intro/
- おなじみhtml5rocks。WebAudioAPIの基礎。
-
こちらもhtml5rocks。ゲームで音を使う場合のあれこれを解説。