Event Scheduler for Web Audio API
npm install web-audio-scheduler> Event Scheduler for Web Audio API
This module is developed based on the idea of this article.
- https://www.html5rocks.com/en/tutorials/audio/scheduling/
###### npm
```
npm install web-audio-scheduler
###### downloads
- web-audio-scheduler.js
- web-audio-scheduler.min.js
`js
const audioContext = new AudioContext();
const sched = new WebAudioScheduler({ context: audioContext });
let masterGain = null;
function metronome(e) {
const t0 = e.playbackTime;
sched.insert(t0 + 0.000, ticktack, { frequency: 880, duration: 1.0 });
sched.insert(t0 + 0.500, ticktack, { frequency: 440, duration: 0.1 });
sched.insert(t0 + 1.000, ticktack, { frequency: 440, duration: 0.1 });
sched.insert(t0 + 1.500, ticktack, { frequency: 440, duration: 0.1 });
sched.insert(t0 + 2.000, metronome);
}
function ticktack(e) {
const t0 = e.playbackTime;
const t1 = t0 + e.args.duration;
const osc = audioContext.createOscillator();
const amp = audioContext.createGain();
osc.frequency.value = e.args.frequency;
osc.start(t0);
osc.stop(t1);
osc.connect(amp);
amp.gain.setValueAtTime(0.5, t0);
amp.gain.exponentialRampToValueAtTime(1e-6, t1);
amp.connect(masterGain);
sched.nextTick(t1, () => {
osc.disconnect();
amp.disconnect();
});
}
sched.on("start", () => {
masterGain = audioContext.createGain();
masterGain.connect(audioContext.destination);
});
sched.on("stop", () => {
masterGain.disconnect();
masterGain = null;
});
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") {
sched.aheadTime = 0.1;
} else {
sched.aheadTime = 1.0;
sched.process();
}
});
document.getElementById("start-button").addEventListener("click", () => {
sched.start(metronome);
});
document.getElementById("stop-button").addEventListener("click", () => {
sched.stop(true);
});
`
- context: AudioContext
- interval: number _default: 0.025 (25ms)_
- aheadTime: number _default: 0.1 (100ms)_
- timerAPI: object _default: window || global_#### Instance properties
-
context: AudioContext
- interval: number
- aheadTime: number
- timerAPI: object
- playbackTime: number
- currentTime: number
- state: string
- events: object[]#### Instance methods
-
start([ callback: function, args: any ]): self
- Start the timeline.
- The callback is inserted in the head of the event list if given.
- stop([ reset = true: boolean ]): self
- Stop the timeline.
- The event list is cleared if reset is truthy.
- insert(time: number, callback: function, [ args: any ]): number
- Insert the callback into the event list.
- The return value is schedId. It is used to .remove() the callback.
- nextTick([ time: number ], callback: function, [ args: any ]): number
- Same as .insert(), but this callback is called at next tick.
- This method is used to disconnect an audio node at the proper timing.
- remove(schedId: number): number
- Remove a callback function from the event list.
- removeAll(): void
- Remove all callback functions from the event list.
- process(): void
- process events immediately (this is useful when transition to background tabs)#### Events
-
"start"
- emitted when the scheduler started.
- "stop"
- emitted when the scheduler stopped.
- "process"
- emitted before each scheduler process.
- "processed"
- emitted after each scheduler process.#### Callback
A callback function receives a schedule event and given arguments at
.insert().A schedule event has two parameters.
-
playbackTime: number
- args: any`js
sched.insert(0, callback, [ 1, 2 ]);function callback(e) {
assert(e.playbackTime === 0);
assert(e.args[0] === 1);
assert(e.args[1] === 2);
}
`Customize
$3
`
time(ms) 0----25---50---75---100--125--150--175--200---->
=====|====|====|====| | | | |
| =====|====|====|====| | | |
| | =====|====|====|====| | |
| | | | ===|====|====|====|== |
| | | | | ===|====|====|====|==
: : : : : : : : :
|<-->| : : |<------------------>|
interval (25ms) aheadTime (100ms)
= range of execution to events
`The below example is the same configuration as defaults.
`js
const sched = new WebAudioScheduler({ interval: 0.025, aheadTime: 0.1 });
`$3
TimerAPI is used instead of the native timer API. TimerAPI should have two functions,
setInterval and clearInterval.- mohayonao/worker-timer
- A timer that is stable in any situation. e.g. tabs in background, the invisible state page.
- mohayonao/tickable-timer
- Manual ticking
setTimeout / setInterval (for test CI)The below example uses stable-timer instead of the native timer API.
`js
const WorkerTimer = require("worker-timer");
const sched = new WebAudioScheduler({ timerAPI: WorkerTimer });
``MIT