I’ve got an issue related to parameter automation which seems a bit weird. Maybe someone with better knowledge of the AudioPatameter classes can give me a hint here.
I’m using the AudioParameterFloat class as well as on-screen sliders and a graphic GUI that needs updating when parameters change. To adapt to parameter changes I’m implementing a timer callback that updates sliders and GUI in function of the parameters, as described in various tutorials.
What I’m observing is the following: if in the timer callback I only adjust the sliders (with dontSendNotification, so I don’t trigger things I might not want), automation works flawlessly.
However if I also redraw the GUI in the timer callback, the host (Beatmaker 3 in this case) seems to loose automation steps from time to time while recording is on. It is as if a previous value of the parameter gets written back to the host after a while, even though I have no clue whatsoever how this can happen, as I’m not changing any parameters in my GUI drawing routines. So the only difference with the case where it works is that I spend more time in the timer callback.
Any ideas what could be happening behind the scenes here? What would be a good way to debug in this case? It might help to monitor the communication between host and plugin (reading/writing parameters), but since that is all handled by the AudioParameterFloat class, I don’t see how I could do that from my own code.
Thanks a lot in advance for any hints that could solve this problem.
Thanks for the link. That is very similar to what I’m doing already (check if a value has changed and update only what needs to be updated, and don’t send notifications for that update). However, as soon as I start changing the positions of some Drawable objects that are linked to the parameters that were modified, messy things start to happen. And if I don’t call repaint() on these Drawable objects, the GUI doesn’t update (for example changes in orientation of the Drawable objects).
That makes me suspicious, what you do in your paint: anything that changes the state, that could potentially trigger something?
IMHO paint() should have been const, but as it isn’t you have to treat it as if it was…
Another option, if the new position of the drawable triggers something?
I think at this point we need to see some code… otherwise it is guessing.
BTW. I moved to using AudioProcessorValueTreeState and the ::SliderAttachment.
The parameters in the AudioProcessorValueTreeState are AudioProcessorParameterWithID, so the rest of your code needs minimal changes only. And it solves a lot of problems…
Thank you all for your replies. In principle, nothing related to the parameters should happen, except reading from them (no writing). Basically I have a virtual sound stage set up where I can drag sources and the listener, and all the parameters also have their sliders. Parameters and sliders only get updated when the icons on the sound stage are actively dragged (mouseDrag()). So when I update the sound stage because parameters have changed, the only thing I do is to update some Drawable objects and I read out the parameters in this process. But I don’t write to them.
I’ll first try to find out what is happening by debugging. If that doesn’t work, I’ll try to come up with a simple example that illustrates this problem, as I don’t want to post hundreds of lines of code here.
I found some time to do some debugging and found out the following:
The dropping of automated parameter values seems quite clearly to be related to timing issues: even if I remove all the drawing stuff, it’s enough to add some printf() calls in the parameter-related methods in juce_AUv3_Wrapper.mm to have the automation loose values. Also when drawing is enabled, the size of the plugin UI has an influence on the rate at which values are lost.
Furthermore, it seems that the host (Beatmaker3) is also reading out values that were written (JuceAudioUnitv3::getValue() gets called in a way consistent with the value changes). Could it be that if there are delays (due to the printf() calls or the draw calls in the timer callback), the read out still provide old values and this will lead the host to assume that a parameter was changed to a previous value (hence dropping the value that was just written)?
However, I couldn’t see everything. In particular the host’s parameter changes during automation, do not seem to lead to calls to audioProcessorParameterChanged nor to valueChangedFromHost. Any ideas how this works? Or are the automation calls completely handled in a thread of the host application (and therefore I don’t see my debugging output)?
I see, you are using the AudioProcessorListener.
I got hit by that as well, see this thread:
Basically it is not meant to be used for that purpose. Better use the AudioProcessorValueTreeState and the suitable AudioProcessorValueTreeState::Listener.
Hi Daniel,
Thanks for your reply. It took me some time to get back to this issue, so please excuse my late answer. I’m not using any listener class, but get these observations by putting NSLog calls in juce_AUv3_Wrapper.mm, yet I still just see calls to getValue(). Any idea through which methods are used to write parameters to the plugin? It doesn’t seem to be audioProcessorParameterChanged() nor valueChangedFromHost(). That said, analyzing when the host reads which parameter is already quite interesting (it happens much more often than one would expect).