I am building an audio app based on the AudioUnit callback facility and a graph of audio processing nodes. I know that the callback is executed in a separate (high priority?) thread and therefore all interaction with my processing nodes, such as e.g. changing EQ parameters while playing, should be done in a thread safe manner. In other words, the nodes should be protected from modification while the audio callback chain is being executed.
The way I understand it in terms of more low-level multithreading is that, I need a lock either in each node or a single one for the entire graph, that prevents writes while audio buffers are being processed.
However, I would like the implementation to be more "Swifty" and use DispatchQueue
/DispatchGroup
which should provide the said functionality. I just can't quite understand how to do it in the most efficient manner.
So let's say all audio parameter modifications are done on a queue, like so:
audioQueue.async {
eqNode.setEqParameters(...)
}
How do I ensure this block is not executed until the AudioUnit callback completes? Using audioQueue.sync
is not an option because it means the system audio thread will depend on my audioQueue
, this is not great.
If I were to use DispatchGroup
what would be the best way to implement the said flow?