App-MHFS
view release on metacpan or search on metacpan
share/public_html/static/music_inc/music_inc_module.js view on Meta::CPAN
//import {default as NetworkDrFlac} from './music_drflac_module.js'
import {default as NetworkDrFlac} from './music_drflac_module.cache.js'
// times in seconds
const AQMaxDecodedTime = 20; // maximum time decoded, but not queued
const AQStartLookahead = 0.100; // minimum time to buffer before starting playback
const AQLookahead = 5; // buffer as long as less than AQLookahead is buffered
let MainAudioContext;
let GainNode;
let AQID = -1;
let AudioQueue = [];
let Tracks_HEAD;
let Tracks_TAIL;
let Tracks_QueueCurrent;
let FACAbortController = new AbortController();
let SBAR_UPDATING = 0;
let NWDRFLAC;
function DeclareGlobalFunc(name, value) {
Object.defineProperty(window, name, {
value: value,
configurable: false,
writable: false
});
};
class Mutex {
constructor() {
this._locking = Promise.resolve();
this._locked = false;
}
isLocked() {
return this._locked;
}
lock() {
this._locked = true;
let unlockNext;
let willLock = new Promise(resolve => unlockNext = resolve);
willLock.then(() => this._locked = false);
let willUnlock = this._locking.then(() => unlockNext);
this._locking = this._locking.then(() => willLock);
return willUnlock;
}
}
function CreateAudioContext(options) {
let mycontext = (window.hasWebKit) ? new webkitAudioContext(options) : (typeof AudioContext != "undefined") ? new AudioContext(options) : null;
GainNode = mycontext.createGain();
GainNode.connect(mycontext.destination);
return mycontext;
}
let lastMALtime;
function MainAudioLoop() {
if(lastMALtime) {
const MALDelta = MainAudioContext.currentTime - lastMALtime;
if((MALDelta) > 0.100) {
console.log('MAL called super late ' + MALDelta);
}
}
lastMALtime= MainAudioContext.currentTime;
AQ_clean();
if(AudioQueue.length === 0) return 0;
// advanced past already scheduled audio. bufferTime is the last endTime
let bufferTime;
let acindex = 0;
for(; acindex < AudioQueue.length; acindex++) {
if(!AudioQueue[acindex].startTime) break;
bufferTime = AudioQueue[acindex].endTime;
}
// adjust / assign bufferTime if needed
let timeadjusted = false;
if(!bufferTime || (bufferTime < MainAudioContext.currentTime)) {
bufferTime = MainAudioContext.currentTime+AQStartLookahead;
console.log('adjusting time to ' + bufferTime);
timeadjusted = true;
}
// queue up to 5 secs ahead
const lookaheadtime = MainAudioContext.currentTime + AQLookahead;
while(bufferTime < lookaheadtime) {
// everything is scheduled break out
if(acindex === AudioQueue.length) return;
let toQueue = AudioQueue[acindex];
let source = MainAudioContext.createBufferSource();
source.buffer = toQueue.buffer;
source.connect(GainNode);
source.start(bufferTime, 0);
InitPPText();
toQueue.source = source;
toQueue.startTime = bufferTime;
if(source.buffer.duration !== (toQueue.duration / toQueue.track.sampleRate)) {
console.log('duration wrong');
}
toQueue.endTime = toQueue.startTime + source.buffer.duration;
( run in 1.178 second using v1.01-cache-2.11-cpan-5a3173703d6 )