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 )