audio-context-timers
Version:
A replacement for setInterval() and setTimeout() which works in unfocused windows.
105 lines (98 loc) • 4.81 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('fast-unique-numbers'), require('standardized-audio-context')) :
typeof define === 'function' && define.amd ? define(['exports', 'fast-unique-numbers', 'standardized-audio-context'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.audioContextTimers = {}, global.fastUniqueNumbers, global.standardizedAudioContext));
})(this, (function (exports, fastUniqueNumbers, standardizedAudioContext) { 'use strict';
var createCallFunction = function createCallFunction(functions, type) {
return function (id) {
if (functions.has(id)) {
var func = functions.get(id);
if (func !== undefined) {
func();
if (type === 'timeout') {
functions["delete"](id);
}
}
}
};
};
var createClearFunction = function createClearFunction(functions) {
return function (id) {
functions["delete"](id);
};
};
var createScheduleFunction = function createScheduleFunction(callFunction, createAudioBuffer, createAudioBufferSourceNode, createMinimalAudioContext, performance) {
var audioBuffer = null;
var minimalAudioContext = null;
var _scheduleFunction = function scheduleFunction(id, delay, type) {
var now = performance.now();
if (minimalAudioContext === null) {
minimalAudioContext = createMinimalAudioContext();
}
var _minimalAudioContext = minimalAudioContext,
destination = _minimalAudioContext.destination,
sampleRate = _minimalAudioContext.sampleRate;
if (audioBuffer === null) {
audioBuffer = createAudioBuffer(2, sampleRate);
}
var audioBufferSourceNode = createAudioBufferSourceNode(minimalAudioContext, audioBuffer);
audioBufferSourceNode.onended = function () {
var elapsedTime = performance.now() - now;
if (elapsedTime >= delay) {
callFunction(id);
} else {
_scheduleFunction(id, delay - elapsedTime);
}
audioBufferSourceNode.disconnect(destination);
};
audioBufferSourceNode.connect(destination);
audioBufferSourceNode.start(Math.max(0, minimalAudioContext.currentTime + delay / 1000 - audioBuffer.duration));
};
return _scheduleFunction;
};
var SCHEDULED_INTERVAL_FUNCTIONS = new Map();
var callIntervalFunction = createCallFunction(SCHEDULED_INTERVAL_FUNCTIONS, 'interval');
var clearInterval = createClearFunction(SCHEDULED_INTERVAL_FUNCTIONS);
var SCHEDULED_TIMEOUT_FUNCTIONS = new Map();
var callTimeoutFunction = createCallFunction(SCHEDULED_TIMEOUT_FUNCTIONS, 'timeout');
var clearTimeout = createClearFunction(SCHEDULED_TIMEOUT_FUNCTIONS);
var createAudioBuffer = function createAudioBuffer(length, sampleRate) {
return new standardizedAudioContext.AudioBuffer({
length: length,
sampleRate: sampleRate
});
};
var createAudioBufferSourceNode = function createAudioBufferSourceNode(minimalAudioContext, audioBuffer) {
return new standardizedAudioContext.AudioBufferSourceNode(minimalAudioContext, {
buffer: audioBuffer
});
};
var createMinimalAudioContext = function createMinimalAudioContext() {
return new standardizedAudioContext.MinimalAudioContext();
};
var scheduleIntervalFunction = createScheduleFunction(callIntervalFunction, createAudioBuffer, createAudioBufferSourceNode, createMinimalAudioContext, performance);
var setInterval = function setInterval(func, delay) {
var id = fastUniqueNumbers.generateUniqueNumber(SCHEDULED_INTERVAL_FUNCTIONS);
SCHEDULED_INTERVAL_FUNCTIONS.set(id, function () {
func();
scheduleIntervalFunction(id, delay, 'interval');
});
scheduleIntervalFunction(id, delay, 'interval');
return id;
};
var scheduleTimeoutFunction = createScheduleFunction(callTimeoutFunction, createAudioBuffer, createAudioBufferSourceNode, createMinimalAudioContext, performance);
var setTimeout = function setTimeout(func, delay) {
var id = fastUniqueNumbers.generateUniqueNumber(SCHEDULED_TIMEOUT_FUNCTIONS);
SCHEDULED_TIMEOUT_FUNCTIONS.set(id, func);
scheduleTimeoutFunction(id, delay, 'timeout');
return id;
};
Object.defineProperty(exports, "isSupported", {
enumerable: true,
get: function () { return standardizedAudioContext.isSupported; }
});
exports.clearInterval = clearInterval;
exports.clearTimeout = clearTimeout;
exports.setInterval = setInterval;
exports.setTimeout = setTimeout;
}));