After a bit of work, I've changed my code a lot from the previous question:
I was recommended by George Mauer and schism to make a better structural design, so hopefully this new build is a bit sleeker in design. I will note that my main target is optimal performance. But like Mr. Mauer said, it is most likely negligible in this particular case.
What I've attempted since is removing duplicate code at the same time optimizing performance and fixing design. Here is what I came up with:
var MediaMaster = new (function(){
var sounds = {};// a container of Audio instances and names(keys) as a reference to their respective values.
// Master Controll of sounds
var liveSounds = [],
instanceVolume = {},
globalVolume = 1;
var SB = {muted: false, previousVolume:1};
this.soundBatch = this.sBatch = SB;
SB.toggleMute = function(){
if( SB.muted === false ){
// mute everything
liveSounds.forEach(function(snd){
snd.previousVolume = snd.volume;
snd.volume = 0;
});
SB.previousVolume = globalVolume;
globalVolume = 0;
return (SB.muted = true);
}
//unmute everything
liveSounds.forEach(function(snd){
snd.volume = snd.previousVolume;
delete snd.previousVolume;
});
globalVolume = SB.previousVolume;
return (SB.muted = false);
};
// Hide specific soundBatch functionality
(function(SB){
function killSound(snd){
snd.pause();
snd.onended();
snd.currentTime = 0;
}
function globalVolumeChange(v){ globalVolume = Math.pow(v,2);}
function globalStop(){liveSounds.forEach(function(snd){killSound(snd)});}
function globalPause(){ liveSounds.forEach(function(snd){snd.pause();}); }
function globalGetLive(){return liveSounds.slice();}
//Applies a callback to anything that passes the filter
function instanceApply(name, callback){
var match = sounds[name].src;
liveSounds.forEach(function(snd){
if( snd.src !== match ) return;
callback(snd);
});
}
SB.volume = function(name, v){
if(!name)return globalVolumeChange(v);
instanceVolume[name] = Math.pow(v,2);
};
SB.stop = SB.kill = function( name ){
if(!name)return globalStop();
instanceApply(name, killSound);
};
SB.pause = function( name ){
if(!name)return globalPause();
instanceApply(name, function(snd){ snd.pause(); });
}
SB.getLive = function( name ){
if(!name)return globalGetLive();
return liveSounds.filter(function(snd){ return( snd.src === match );});
}
})(this.soundBatch);
var prototypePlay = Audio.prototype.play;//keep a reference
// Getting sounds
this.sound = function(name){
var snd = new Audio( sounds[name].src );
snd.volume = instanceVolume[name];
snd.play = function(){
var that = this;// used for removing "liveSounds" this conflict.
that.volume *= globalVolume;
prototypePlay.apply(that);
liveSounds.push(that);
this.onended = function(){ liveSounds.splice( liveSounds.indexOf(that), 1 );};
};
return snd;
};
})();
If you're looking for an ever bigger picture of what this belongs too, it is a part of my Game Framework I started July 4th. Look for "mediaManager.js"