playback.js — Audio Playback & Export

Manages the AudioContext lifecycle, buffer playback with VU metering, and WAV download.

AudioContext Lifecycle

The AudioContext is created at module load time (eager initialisation) so the browser's audio subsystem has time to warm up. It starts in suspended state.

On the first user click anywhere on the page (capture-phase listener), resume() is called to wake the pipeline. Actual playback uses a start-before-resume pattern: AudioBufferSourceNode.start() is called while the context is still suspended (queuing the start), then resumeAudio() flips the pipeline on. This ensures the first click always produces sound.

var _audioCtx = new AudioContext();   // created at module load (suspended)
window.addEventListener('click', ... resume() ..., { capture: true, once: true });

function playBuffer(buffer) {
  src.start();            // queued on suspended context
  resumeAudio();          // wakes the pipeline — queued start plays
}

Functions

getAudioContext() → AudioContext | null

Returns the singleton AudioContext (or null if creation failed).

resumeAudio()

Calls resume() on the AudioContext if it's suspended. Safe to call multiple times.

playBuffer(buffer, vuCanvasId)

Plays an AudioBuffer through the shared AudioContext. Sets up an AnalyserNode for VU metering. The VU meter canvas shows a peak-level bar that updates via requestAnimationFrame for the buffer's duration, then clears.

downloadWAV(blob, filename)

Triggers a file download from a Blob. Creates a temporary <a> element, clicks it, and revokes the object URL after 60 seconds.