163 lines
4.3 KiB
JavaScript
163 lines
4.3 KiB
JavaScript
#include utility.js
|
|
#include sound/sndlibrary.js
|
|
#include sound/sndpacks.js
|
|
|
|
const MamiSoundManager = function(context) {
|
|
const supported = [], fallback = [],
|
|
formats = {
|
|
opus: 'audio/ogg;codecs=opus',
|
|
ogg: 'audio/ogg;codecs=vorbis',
|
|
mp3: 'audio/mpeg;codecs=mp3',
|
|
caf: 'audio/x-caf;codecs=opus',
|
|
wav: 'audio/wav',
|
|
};
|
|
|
|
const loaded = new Map;
|
|
|
|
(function() {
|
|
const elem = $e('audio');
|
|
for(const name in formats) {
|
|
const format = formats[name], support = elem.canPlayType(format);
|
|
if(support === 'probably')
|
|
supported.push(name);
|
|
else if(support === 'maybe')
|
|
fallback.push(name);
|
|
}
|
|
})();
|
|
|
|
const pub = {};
|
|
|
|
const findSupportedUrl = function(urls) {
|
|
if(typeof urls === 'string')
|
|
return urls;
|
|
|
|
// lol we're going backwards again
|
|
if(Array.isArray(urls)) {
|
|
const tmp = urls;
|
|
urls = {};
|
|
|
|
for(const item of tmp) {
|
|
let type = null;
|
|
|
|
if(item.type)
|
|
type = item.type;
|
|
else {
|
|
switch(item.format) {
|
|
case 'audio/mpeg':
|
|
case 'audio/mp3':
|
|
type = 'mp3';
|
|
break;
|
|
case 'audio/ogg': // could also be opus, oops!
|
|
type = 'ogg';
|
|
break;
|
|
case 'audio/opus': // isn't real lol
|
|
type = 'opus';
|
|
break;
|
|
case 'audio/x-caf':
|
|
type = 'caf';
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(type === null || type === undefined)
|
|
continue;
|
|
|
|
urls[type] = item.url;
|
|
}
|
|
}
|
|
|
|
// check "probably" formats
|
|
let url = null;
|
|
for(const type of supported) {
|
|
if(type in urls) {
|
|
url = urls[type];
|
|
break;
|
|
}
|
|
}
|
|
|
|
// check "maybe" formats
|
|
if(url === null)
|
|
for(const type of fallback) {
|
|
if(type in urls) {
|
|
url = urls[type];
|
|
break;
|
|
}
|
|
}
|
|
|
|
return url;
|
|
};
|
|
|
|
pub.findSupportedUrl = findSupportedUrl;
|
|
|
|
pub.loadAnonymous = function(urls, callback) {
|
|
const url = findSupportedUrl(urls);
|
|
if(url === null) {
|
|
callback.call(pub, false, 'No supported audio format could be determined.');
|
|
return;
|
|
}
|
|
|
|
context.createBuffer(url, function(success, buffer) {
|
|
callback.call(pub, success, buffer);
|
|
});
|
|
};
|
|
|
|
pub.load = function(name, urls, callback) {
|
|
const hasCallback = typeof callback === 'function';
|
|
|
|
if(loaded.has(name)) {
|
|
if(hasCallback)
|
|
callback.call(pub, true, loaded.get(name));
|
|
return;
|
|
}
|
|
|
|
const url = findSupportedUrl(urls);
|
|
if(url === null) {
|
|
const msg = 'No supported audio format could be determined.';
|
|
if(hasCallback)
|
|
callback.call(pub, false, msg);
|
|
else
|
|
throw msg;
|
|
return;
|
|
}
|
|
|
|
context.createBuffer(url, function(success, buffer) {
|
|
if(!success) {
|
|
if(hasCallback)
|
|
callback.call(pub, success, buffer);
|
|
else // not actually sure if this will do anything but maybe it'll show in the console
|
|
throw buffer;
|
|
return;
|
|
}
|
|
|
|
loaded.set(name, buffer);
|
|
|
|
if(hasCallback)
|
|
callback.call(pub, success, buffer);
|
|
});
|
|
};
|
|
|
|
pub.unload = function(name) {
|
|
loaded.delete(name);
|
|
};
|
|
pub.reset = function() {
|
|
loaded.clear();
|
|
};
|
|
|
|
pub.play = function(name) {
|
|
if(loaded.has(name))
|
|
loaded.get(name).createSource().play();
|
|
};
|
|
|
|
pub.isLoaded = function(name) {
|
|
return loaded.has(name);
|
|
};
|
|
|
|
pub.get = function(name) {
|
|
if(!loaded.has(name))
|
|
return null;
|
|
return loaded.get(name).createSource();
|
|
};
|
|
|
|
return pub;
|
|
};
|