Web-audio-api: Why AudioWorklet disables Atomics.wait?

Created on 4 Apr 2019  路  2Comments  路  Source: WebAudio/web-audio-api

I didn't test on other browser but only Chrome and it might only matter on Chrome.

As AudioWorklet SharedArrayBuffer model example shows, a separate Worker thread produce audio data and AudioWorklet thread consumes the produced data continuously.
But this sample code has race condition issue when producing audio data on Worker thread takes heavy time for some reason and Worklet thread tries to consume before the data is produced.
Which means Worklet should check whether data is ready or not. Two possible solutions are (as written on here

  1. Send message when output buffer is ready via MessagePort
  2. Block AWP until output buffer is ready (Atomics.compareExchange or spin-lock)

But both of them seems to have a problem.

  1. Main UI thread must get involved as a relay in message passing between AWP and DWG. As a result, there might be a delay issue when UI thread is kinda busy.
  2. Performance issue

Glitching is not a problem in here since glitching has already happened when consumer suffers lack of data. Rather than, this such unnatural solution to solve this situation makes me feel bad. If Atomics.wait can be used in Worklet thread, it can just wait using Atomics.wait until data is ready and everything will looks fine.

Or, is there any technical / design issue which prevents Atomics.wait to be enabled on AudioWorklet?

Most helpful comment

http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing is the classic reference for this kind of question, but the bottom line is: one should never ever ever wait in a real-time audio callback, so we disabled Atomic.wait, because there is no good reason to have it, and not having it clearly sends a message to authors, they if they are trying to wait on anything, they are doing something wrong (of course they can busy-wait, etc., it's not foolproof).

All 2 comments

By design, AudioWorkletProcessor must be synchronously processed by "rendering thread". If the user code in the processor blocks the thread (like Atomics.wait), it will stall the entire graph rendering loop affecting the other processors' progress. That's why AudioWorkletGlobalScope does not have Atomics.wait.

For real-time audio use case, synchronously blocking the thread is generally not a good idea. I'll update my example with a better shared memory model.

http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing is the classic reference for this kind of question, but the bottom line is: one should never ever ever wait in a real-time audio callback, so we disabled Atomic.wait, because there is no good reason to have it, and not having it clearly sends a message to authors, they if they are trying to wait on anything, they are doing something wrong (of course they can busy-wait, etc., it's not foolproof).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mounirlamouri picture mounirlamouri  路  10Comments

cyrta picture cyrta  路  17Comments

Korilakkuma picture Korilakkuma  路  4Comments

juj picture juj  路  19Comments

kickermeister picture kickermeister  路  18Comments