Search code examples
javascriptweb-audio-apiaudio-worklet

Scheduling playback of AudioWorkletNode


I'm working with soundtouchjs-audio-worklet in order to change the tempo/pitch of audio files that have been read into a buffer. The library creates a worklet that can process these buffers, and gives me an AudioWorkletNode to control it. What I need to do is schedule the playback of multiple AudioWorkletNodes so that different audio files can be on a "timeline" of sorts.

I know the AudioBufferSourceNode has a when parameter in it's start() function that you can use to schedule the playback of the node. But AudioWorkletNode doesn't seem to be scheduleable; it just immediately begins playback upon connect()ing it.

I could use setTimeout() to delay calling connect(), but I don't think the timing will be accurate enough. Does anyone know of a way to schedule playback of an AudioWorkletNode? Or an accurate way to connect it at the exact right time?


Solution

  • There is no built-in way to schedule an AudioWorkletProcessor but it's possible to use the global currentTime variable to build it yourself. The processor would then look a bit like this.

    class ScheduledProcessor extends AudioWorkletProcessor {
        constructor() {
            super();
    
            this.port.onmessage = (event) => this.startTime = event.data;
            this.startTime = Number.POSITIVE_INFINITY;
        }
    
        process() {
            if (currentTime < this.startTime) {
                return true;
            }
    
            // Now it's time to start the processing.
        }
    }
    
    registerProcessor('scheduled-processor', ScheduledProcessor);
    

    It can then be "scheduled" to start when currentTime is 15 like this:

    const scheduledAudioNode = new AudioWorkletNode(
        audioContext,
        'scheduled-processor'
    );
    
    scheduledAudioNode.port.postMessage(15);