152 lines
4 KiB
JavaScript
152 lines
4 KiB
JavaScript
#include utility.js
|
|
#include audio/buffer.js
|
|
#include audio/source.js
|
|
|
|
const MamiSRLEEncode = function(input, cutoff) {
|
|
let output = '', last = '', repeat = 0;
|
|
|
|
input = (input || '').toString();
|
|
cutoff = cutoff || 1
|
|
|
|
for(let i = 0; i <= input.length; ++i) {
|
|
const chr = input[i];
|
|
if(last === chr)
|
|
++repeat;
|
|
else {
|
|
if(repeat > cutoff)
|
|
for(const repChr in repeat.toString()) output += ')!@#$%^&*('[parseInt(repChr)];
|
|
else
|
|
output += last.repeat(repeat);
|
|
repeat = 0;
|
|
if(chr !== undefined) {
|
|
output += chr;
|
|
last = chr;
|
|
}
|
|
}
|
|
}
|
|
|
|
return output;
|
|
};
|
|
|
|
const MamiSRLEDecode = function(input) {
|
|
let output = '', repeat = '', chr;
|
|
|
|
input = (input || '').toString().split('').reverse();
|
|
|
|
for(;;) {
|
|
const chr = input.pop(), num = ')!@#$%^&*('.indexOf(chr);
|
|
if(num >= 0) repeat += num;
|
|
else {
|
|
if(repeat) {
|
|
output += output.slice(-1).repeat(parseInt(repeat));
|
|
repeat = '';
|
|
}
|
|
if(chr === undefined) break;
|
|
output += chr;
|
|
}
|
|
}
|
|
|
|
return output;
|
|
};
|
|
const MamiDetectAutoPlaySource = '/+NIxA!!FhpbmcA#PA$wA@fgAV$#q$#/$#A#OUxBTUUzLjEwMAIeA!)UCCQC8CIA@gA@H49wpKWgA!%&/+MYxA$NIA$ExBTUUzLjEwMFV^%/+MYxDsA@NIA$FV&&/+MYxHYA@NIA$FV&&';
|
|
|
|
const MamiDetectAutoPlay = async () => {
|
|
try {
|
|
const audio = $e('audio', { src: 'data:audio/mpeg;base64,' + MamiSRLEDecode(MamiDetectAutoPlaySource) });
|
|
|
|
try {
|
|
await audio.play();
|
|
} catch(ex) {
|
|
if('name' in ex && ex.name !== 'NotAllowedError' && ex.name !== 'AbortError') {
|
|
console.error(ex);
|
|
throw ex;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
} catch(ex) {}
|
|
|
|
return true;
|
|
};
|
|
|
|
const MamiAudioContext = function() {
|
|
const pub = {};
|
|
|
|
let volume = null,
|
|
isMuted = false;
|
|
|
|
const ctxArgs = { latencyHint: 'playback' };
|
|
let ctx = null,
|
|
mainGain = null;
|
|
const init = function() {
|
|
const audObj = window.AudioContext || window.webkitAudioContext;
|
|
try {
|
|
ctx = new audObj(ctxArgs);
|
|
} catch(ex) {
|
|
ctx = new audObj;
|
|
}
|
|
mainGain = ctx.createGain();
|
|
|
|
if(volume === null) {
|
|
volume = mainGain.gain.defaultValue;
|
|
isMuted = false;
|
|
} else
|
|
mainGain.gain.value = isMuted ? 0 : volume;
|
|
|
|
mainGain.connect(ctx.destination);
|
|
};
|
|
|
|
init();
|
|
pub.getContext = function() { return ctx; };
|
|
pub.resetContext = init;
|
|
|
|
pub.useGain = function(callback) {
|
|
callback.call(pub, mainGain.gain);
|
|
};
|
|
|
|
pub.getVolume = function() {
|
|
return volume;
|
|
};
|
|
pub.setVolume = function(vol) {
|
|
volume = vol;
|
|
if(!isMuted)
|
|
mainGain.gain.value = volume;
|
|
};
|
|
pub.isMuted = function() {
|
|
return isMuted;
|
|
};
|
|
pub.setMuted = function(mute) {
|
|
mainGain.gain.value = (isMuted = mute) ? 0 : volume;
|
|
};
|
|
|
|
pub.createBuffer = function(url, callback) {
|
|
$x.get(url, { type: 'arraybuffer' })
|
|
.then(resp => {
|
|
try {
|
|
ctx.decodeAudioData(
|
|
resp.body(),
|
|
buffer => callback.call(pub, true, new MamiAudioBuffer(pub, buffer)),
|
|
error => callback.call(pub, false, error)
|
|
);
|
|
} catch(ex) {
|
|
callback.call(pub, false, ex);
|
|
}
|
|
})
|
|
.catch(err => callback.call(pub, false, err));
|
|
};
|
|
|
|
const createSource = function(buffer) {
|
|
const gain = ctx.createGain();
|
|
gain.connect(mainGain);
|
|
|
|
const source = ctx.createBufferSource();
|
|
source.buffer = buffer;
|
|
source.connect(gain);
|
|
|
|
return new MamiAudioSource(source, gain);
|
|
};
|
|
pub.createSource = createSource;
|
|
|
|
return pub;
|
|
};
|