Hi all. What is the best way to access and manipulate GUI elements in the MainComponent from within an AudioDeviceCallback? Currently my MainContentComponent constructor creates an AudioIODevice, and passes a custom AudioIODeviceCallback to it when it starts. But how can the AudioIODeviceCallback know about and communicate with the MainComponent. If it helps, I want to create VU meters for the audio streams. Also, if it helps, here is the code in MainContentComponent()
You will probably need to use a forward declaration in the callback class’s header file and include your maincomponent header only in the callback’s cpp file.
(You could also do things more complicatedly with some kind of an observer pattern, which would get rid of the direct dependency between your audio callback and the main component class.)
When you have managed to do that, you will have the problem of how to notify the GUI of the changes in the audio so that you won’t be using the GUI directly from the audio thread. And also how to do that efficiently, since the audio thread should not be made to wait for long.
Quick question about using ff_meters. Audio data “enters” audioDeviceCallback() as const float ** but to create an AudioBuffer I need a float *const* pointer. Any advice around how to safely/properly create an AudioBuffer to use as an argument to meterSource.measureBlock?
It’s working well now and looks great. I’m seeing a significant increase in process usage ~18% when running the meter at full speed. If I lower to 1Hz refresh rate I get only ~1% increase. Might there be a way to trade level accuracy for speed? I don’t mind if the level reporting is a bit off, but I’d like it to feel quick.
what is your “full speed”? I usually run at 30 FPS, it is not video, so IMHO everything above is overkill.
Also, there is the RMS window that you can resize, I have this line in my prepareToPlay:
I did a number of speed experiments and it seems like the performance is directly tied to the refresh rate and the number of LevelMeters. The drawing thread uses the most processing.
I have some questions. (1) When we call repaint() does it call paint() on all the child components? (2) Is ff_meter calling a general repaint of all components? (3) It appears that each LevelMeter has its own timer. I plan to have an arbitrary number of meters. Would it improve performance to create one master timer for all meters?
I’m pretty new to JUCE graphics, so I apologize if I’m getting anything wildly wrong here. And also, sorry for harping on the performance. I’m just trying to understand what factors affect it. Delving into the code has been a pleasure! It’s very well-written and I’m learning quite a bit.
No, it only calls repaint for the meter component. But there might be optimisations in JUCE I am unaware of.
I actually was just gonna suggest this. I had problems in the past (not with the meters), when I have a repaint timer for the whole GUI and another for a single component inside that, I got them fighting and even stalling the host’s drawing… Maybe you have a similar situation?
The meters paint is completely decoupled, so there are no side effects. It can just repaint together with the parent, if that fits your setup.