かしこくもなりたいし、女の子にもなりたかった。

とってもガーリーなゆるふわ愛され何でも屋を目指す、30代男性がお送りするファビュラスなブログ。

WebAudio APIで効果音ならすライブラリを作ろう。

f:id:takustaqu:20140321133838j:plain

さて、ずいぶん大げさな書き出しになってしまいましたが、iOSのWebAudioAPI対応は、それぐらい素晴らしいものなのです。

何気に Audioタグを試した方はご存じかもしれませんが、audioタグは必ず1度クリックやタップのイベントで発火させないと音が鳴らないというスマートフォン特有の制約がございまして、これのために無意味な連打などをさせるWebアプリケーションが御座いました。

そこに現れたWebAudio APIスマートフォンでもこのような制約に掛からず、また同時にiOSのaudioタグが同時発声できないという制約にも縛られません。つまり、効果音ならしまくりって事なワケです。

boombox.jsでWebAudioAPIの素晴らしさを体感したものの、ちょっと自分の使い道だと不便なので、自分で使いやすいように出来るように自分なりに書いてみました。

動くサンプルはここに置いてあります

ええ、結局またきりんです。きりんさんです。 ヤヤネヒロコ神の声は本当に汎用性が高いですね。

参考にしたのはこちらのサイト。 - Web Audio API 解説 - g200kg Music & Software

コードはこんなの。

var buzz = function(){
    this.buffers = {};
    this.ctx = (function(){
                    if(typeof(webkitAudioContext)!=="undefined"){
                        return new webkitAudioContext();
                    }else if(typeof(AudioContext)!=="undefined"){
                        return new AudioContext();
                    }
                })();
};

buzz.prototype.load = function(arg){

    for(i=0,il=arg.length;i<il;i++){

        (function(target){
            var req = new XMLHttpRequest();
            req.open("GET", arg[i].src, true);
            req.responseType = "arraybuffer";
            req.alias = arg[i].alias;

            req.onload = function() {
                if(req.response) {
                    target.ctx.decodeAudioData(req.response,function(b){
                        target.buffers[req.alias] = b;
                    },function(){
                        // console.log("isFailed")
                    });
                }
            }
            req.send();
        })(this);

    };
};


buzz.prototype.play = function(alias){
    console.log(alias)
    if (this.buffers[alias] == undefined){
        return false;
    }

    var src = this.ctx.createBufferSource();
    src.buffer = this.buffers[alias];
    src.connect(this.ctx.destination);
    src.start(0);
}

まあシンプルですね。ちなみに使い方はこんな感じ。

使い方

//あたらしくbuzzさんになって頂きます。
var sndfx = new buzz;

//loadは配列で渡せます。{alias:"音の名前","src":"音声ファイルのパス"}で。
sndfx.load([
        {"alias":"40cm1","src":"./40cm1.mp3"},
        {"alias":"kara1","src":"./kara1.mp3"},
        {"alias":"kirinsan1","src":"./kirinsan1.mp3"}
]);

sndfx.play("40cm1") //40cm1に指定された音が鳴る

とっても簡単ですね。アホでも使えます。俺用なので。

今後

一応今後のtodoとしては、音量、再生速度(できんのか?)をplayの引数に指定できるようにとか、まあちゃんと再生の終了タイミングでcallback取れるようにしたりとか、そういうところをやっていこうかと。

とりあえずお昼の思いつきとしてはここまで。kirinmatchにはこれで十分だ(結局そこ)