Search code examples
javascriptaudioweb-audio-api

Is the web audio api timing more precise than setTimeout


When pushing a sound in the web audio api you can set the time when the sound will start with source.start(startTime);. However I'm wondering how precise that is. I know setTimeout() just put the code to be executed in the event queu. I assume that it's what the Web audio api does as well but that's only a guess. Thus there would be no difference between the two of them.

I tried running some long running process before the sound is played and the sound is indeed delayed.

  //...
  source.start(startTime + 0.2);
  //....
 let i = 0;
 while( i < 100000){
   console.log("p" + i);
   i++;
 }

So does the web audio api uses setTimeout under the hood. If so could I make things more responsive by using a web worker ? I know a web worker has access to setTimeout but I'm not sure it can access the web audio api.

From the doc :

Audio workers provide the ability for direct scripted audio processing to be done inside a web worker context, and are defined by a couple of interfaces (new as of 29th August 2014.) These are not implemented in any browsers yet

This only adresses the point of audio processing, I'm not sure that includes just playing audio.


Solution

  • Is the web audio api timing more precise than setTimeout?

    Yes, by far! The audio timer implementation seek to reduce (accumulative) latency and to give real-time and precision timing capabilities down to sample level. It uses a precision scheduler for audio events.

    From MDN:

    Timing is controlled with high precision and low latency, allowing developers to write code that responds accurately to events and is able to target specific samples, even at a high sample rate. So applications such as drum machines and sequencers are well within reach.

    and from the W3C Editor's Draft 20 December 2016:

    [...] In particular, instead of using message queue, implementors can use memory that is shared between threads, as long as the memory operations are not reordered.

    The way setTimeout() works is not accurate enough for audio processing in general and its lower end time value can even be limited (for example, setting it to 1ms may be changed to 4ms by the browser). It may or may not fire at the target time depending on the event queue as well as other factors.

    Another thing to have in mind is that all scheduled times in the Web Audio API are relative to the value of the AudioContext's currentTime (ibid).

    So does the web audio api uses setTimeout under the hood?

    Sort of already answered, but no, absolutely no :)

    Audio Worker nodes will be used to process audio data (like the current but deprecated ScriptProcessorNode), but on separate threads and not to play audio themselves. All audio playback happens through the main audio thread. See more on Audio Workers Nodes here.