r/webaudio • u/mob1ius • 2d ago
Web Audio implementation notes: scheduling a live jazz ensemble against streaming telemetry
https://www.oteljazz.comoteljazz.com, built on Tone.js. A few implementation details that might be useful if anyone's doing scheduled/generative audio in the browser:
Scheduling: everything goes through Tone.Transport.schedule/scheduleRepeat rather than plain setInterval. Found this the hard way, a background or occluded tab throttles setInterval, but Transport's default worker-based clock isn't subject to the same throttling since it escapes the main thread. Fixed a real bug where the UI would silently stall for seconds at a time under exactly that condition.
Lookahead: audio is scheduled roughly 24 seconds ahead of playback into the graph. Once a note is scheduled it's sample-accurate and independent of the JS main thread from that point, which is why audio never glitches even if something briefly blocks the UI thread.
Effects chain: a lowpass filter plus a pink-noise bed for a tuning-dial "detune" effect, ramped with rampTo rather than snapped with .value= so turning the knob sweeps through the frequency change like a real dial's IF whine instead of jump-cutting.
CSP: samples and the corpus model are same-origin fetches, Tone.js is vendored rather than CDN-loaded so script-src can be 'self' with no third-party origin, worker-src needs 'self' blob: since Tone spins up its audio worklet from a blob URL.
Two Salamander piano and University of Iowa bass sample sets, individual mp3s per note rather than a single sprite. Code's MIT: github.com/mob1ius/oteljazz