Infinite loops with callbacks

audiovaluetreestate

#1

Hello,

I’m trying to handle my AudioParameters in a AudioProcessorValueTreeState because I need to have them in the place. But when I modify one the parameter with a SliderAttachment, I also need to modify the others parameters in function of the new value of this parameter. Example : I have a bandwidth defined by a start frequency and a stop frequency. When I modifiy one those parameters, I need to modify the other in line with the new value. Actually I have the callback of the AudioProcessorValueTreeState “parameterChanged” called, but I create an endless loop because modifying one parameter in this callback function will call it again, and again, and again. Does someone have a solution ?


#2

Do you want to update each other on automation too?
In this case you have to mark the parameters as meta parameter to make auval happy.
If not, I would probably update in the sliderValueChanged() method on the GUI side, where you can set using dontSendNotification.

But I would check the maths, since the change should not be propagated, if it is the same as the already set value. Either you have a rounding problem here, or the maths is unstable.


#3

It’s not a problem with the maths, it’s just that in my function, when the callback “parameterChanged” is called, I modify the ValueTree depending of the new value of the parameter. And because I modify the value in the callback that is called when a value of the ValueTree is modified, I start calling it indefinitely. The SliderAttachment is working good, and it usefull to separe GUI from the process. Actually I handled it with a comparison of the previous value, but it’s a lot of wasted time and memory.


#4

Especially since the juce code does the same thing here:


#5

But you’re right, I’m stubborn to continue using the SliderAttachment, it’s not appropriated in my problem. So I’ll create my own class retrieving the value of the slider, calculating the new values of each parameters and push everything in the same time. Thank you !


#6

Oh no, that’s not what I meant, sorry. I might have been a bit sloppy in my answers.
I think the SliderAttachment is the best way to connect the Slider to the AudioProcessorValueTreeState. I was wondering, if the change of the other parameter was meant as a result of the first one, or if it is always to be synced, no matter where the change was issued.

But another thought, if these two values are always resulting from each other, why having two parameters in the first place?


#7

Not sure if it’s a good coding style, but I would solve those problems by setting a flag to figure out whether the user is changing the parameter or the other parameter is.
bool updatingParameter;
And prior to updating you set updatingParameter = true;, afterwards to false and in the parameterChanged()-Callback you simply do nothing when updatingParameter == true.


#8

The change of the other parameter is always a result of the first one.
What is your solution if it’s not using two parameters ?


#9

The parameters can modify each others. So do I have to have a flag for each parameter ?


#10

So in your example you have actually three parameters: start, end and bandwidth.
What I understood so far is, that when you change the start, and the bandwidth was assumed constant, you change the end accordingly, which in turn tries to change the start.
If the end is always start+bandwidth, you don’t need a parameter for that.

If I were to design that, I probably would go for bandwidth and centre frequency, since that is often used in EQ plugins.

Does that make sense?


#11

One flag should be enough as both callbacks can‘t happen concurrently. But as I said, I am not sure if it‘s a good coding style :slight_smile:
Furthermore, Daniels solution might fit even better with a bandwidth and center frequency parameter which are completely independent. However, that of course depends on your specific application


#12

We solved a similar problem by using a timer to update our ui. In the timer callback each ui element checks if anything relevant has changed and repaints itself with the new data if necessary. This simplified a lot of confusing flag setting. It’s much easier to maintain works like a charme.


#13

I think that the problem is located on the fact that the ValueTree compares ranged values with unranged values, and that provides, infinite calls.
My example was only in the purpose to fix-it, what I have to do is a bandpass filter with 4 parameters. So my problem still remains.