Passing audioBuffer/array from a background gui thread to audio thread

I have a component that paints a wavetable from user input (drawing on the screen) but at the same time with that info it generates audio data. It runs on it’s own thread since it makes some calculus and a decent amount of path stroking, so I wanted to offload the main thread. Since it has various options to be set from the main GUI, It’s set as a child component of AudioProcessorEditor.

The simplified schematic would be like:

AudioProcessor <-- AudioProcessorEditor <-- Background Thread (paints and generates data)

Should I set up a timer in the Editor to check for new data and grab it with a lock free queue (stored in the Background Thread to be able to access it instead of child to parent acess?) and then do the same with the Processor checking the Editor?
Should I just pass a pointer alas FileBuffer example (which also realies on timers) and then make a local copy of the data in the Processor?
Once I receive it in the Processor i have to pass it to all my oscillators in my voices, so it’s kinda a long route from the source to the final destination and I’m afraid it could be done in a much more efficient way.
Any insights?

I‘m also interested in what‘s the best practice to do this - anybody?

I “succesfully” implemented it using fast lock-free queues. I use brackets since I have to fully test and profile it but the preliminar tests came ok and the cpu counter doesn’t spike at all.
I did somethink like:

Background Thread (owns Q1) -> draw = enqueue array at Q1 -> AudioProcessorEditor dequeue from Q1 (timer) -> AudioProcessorEditor enqueue to Q2 -> AudioProcessor (owns Q2) dequeues it’s own Q2 (timer)

Please someone correct me if the AudioProcessor queue should be stored in the AudioProcessorEditor instead, but I preferred the audio thread not to access any AudioProcessorEditor function at all just in case, and have a better data locality.

The most robust solution for me was for both queues to be owned by the object with the longest lifetime (in vst3 for e.g. the ‘controller’ has the longest lifetime, I provided to the audioprocessor only a pointer to the queue). This prevented crashes caused by one object attempting to write to the queue after it had been deleted.

3 Likes