1
0
mirror of https://github.com/moparisthebest/kaiwa synced 2024-08-13 17:03:51 -04:00
kaiwa/clientapp/modules/sound-effect-manager.js
2013-06-03 15:51:30 -07:00

141 lines
4.2 KiB
JavaScript

/*
SoundEffectManager
Loads and plays sound effects useing
HTML5 Web Audio API (as only available in webkit, at the moment).
By @HenrikJoreteg from &yet
*/
/*global webkitAudioContext define*/
(function () {
var root = this;
function SoundEffectManager() {
this.support = !!window.webkitAudioContext;
if (this.support) {
this.context = new webkitAudioContext();
}
this.sounds = {};
}
// async load a file at a given URL, store it as 'name'.
SoundEffectManager.prototype.loadFile = function (url, name, delay, cb) {
if (this.support) {
this._loadWebAudioFile(url, name, delay, cb);
} else {
this._loadWaveFile(url.replace('.mp3', '.wav'), name, delay, 3, cb);
}
};
// async load a file at a given URL, store it as 'name'.
SoundEffectManager.prototype._loadWebAudioFile = function (url, name, delay, cb) {
if (!this.support) return;
var self = this,
request = new XMLHttpRequest();
request.open("GET", url, true);
request.responseType = "arraybuffer";
request.onload = function () {
self.sounds[name] = self.context.createBuffer(request.response, true);
cb && cb();
};
setTimeout(function () {
request.send();
}, delay || 0);
};
SoundEffectManager.prototype._loadWaveFile = function (url, name, delay, multiplexLimit, cb) {
var self = this,
limit = multiplexLimit || 3;
setTimeout(function () {
var a, i = 0;
self.sounds[name] = [];
while (i < limit) {
a = new Audio();
a.src = url;
// for our callback
if (i === 0 && cb) {
a.addEventListener('canplaythrough', cb, false);
}
a.load();
self.sounds[name][i++] = a;
}
}, delay || 0);
};
SoundEffectManager.prototype._playWebAudio = function (soundName) {
var buffer = this.sounds[soundName],
source;
if (!buffer) return;
// creates a sound source
source = this.context.createBufferSource();
// tell the source which sound to play
source.buffer = buffer;
// connect the source to the context's destination (the speakers)
source.connect(this.context.destination);
// play it
source.noteOn(0);
};
SoundEffectManager.prototype._playWavAudio = function (soundName, loop) {
var self = this,
audio = this.sounds[soundName],
howMany = audio && audio.length || 0,
i = 0,
currSound;
if (!audio) return;
while (i < howMany) {
currSound = audio[i++];
// this covers case where we loaded an unplayable file type
if (currSound.error) return;
if (currSound.currentTime === 0 || currSound.currentTime === currSound.duration) {
currSound.currentTime = 0;
currSound.loop = !!loop;
i = howMany;
return currSound.play();
}
}
};
SoundEffectManager.prototype.play = function (soundName, loop) {
if (this.support) {
this._playWebAudio(soundName, loop);
} else {
return this._playWavAudio(soundName, loop);
}
};
SoundEffectManager.prototype.stop = function (soundName) {
if (this.support) {
// TODO: this
} else {
var soundArray = this.sounds[soundName],
howMany = soundArray && soundArray.length || 0,
i = 0,
currSound;
while (i < howMany) {
currSound = soundArray[i++];
currSound.pause();
currSound.currentTime = 0;
}
}
};
// attach to window or export with commonJS
if (typeof module !== "undefined") {
module.exports = SoundEffectManager;
} else if (typeof root.define === "function" && define.amd) {
root.define(SoundEffectManager);
} else {
root.SoundEffectManager = SoundEffectManager;
}
})();