GUI Freezing in Reaper when using setValueNotifyingHost? Bug in juce? Don't usually like to say it but...?

Hello all,

EDIT: I will say that I am on Windows first and foremost, and it is a VST3. Just to put that out there.

Essentially my VST plugin is for storing presets for rigs of other plugins. So each patch has a bunch of parameter values, that when changed between patches will update the parameters in the apvts, which I can then link to parameters in the other plugins, in the host - REAPER. I have a bunch of on screen buttons to select through 8 different patches, and then buttons for bank up and bank down, just for testing and editing the patches. Then I have exposed parameters in Reaper, that I can midi learn to buttons on my midi controllers to actually toggle them when performing.

I posted another thread entitled Changing a parameter value when another is changed?

Here I talked about how I found a solution in using juce::MessageManager::callAsync in the parameterChanged method. But someone called kamedin replied and told me this was a bad idea because of… reasons. The short of it is, kamedin advised me to look at a timer based solution and sent me a link to eyalamir’s posts.

I decided to look into this, and I have now changed my toggle method to set variables (such as what bank / patch should be selected) and then I have a timer in the audio processor which when a boolean variable called “hasToggled” becomes true, will perform the actual switching. This does seem to work a lot better, and now the parameterChanged() does not directly affect other parameters.

But I noticed that the more banks that I added, the GUI became less and less responsive. It actually hangs sometimes for… what feels like a second in the worst case. There are ways I could optimise various things, but there doesn’t seem to be anything that jumps out as obvious to me at this point. Apart from maybe some kind of data race between the audio processor and the editor which is causing it to lag.

EDIT: It seems all of my issues relate to calling setValueNotifyingHost(). If I comment these lines out then the problem disappears. Also if I close the editor, the problem disappears. The editor seems to steal GUI updates away from Reaper when it comes to doing anything with notifications. If I go into Reaper’s settings I can set an option to ignore processing notifications. If I select this then pressing the buttons in the GUI do not cause lag anymore, but pressing buttons on my midi controller still will (while the GUI is open).

Now… In my editor code I am getting references to data in the audio processor in various methods, such as the banks of patches, for displaying etc. This is basically a 2d vector with 16 banks of 8 patches per bank.

So many questions, not sure how to even begin attacking this problem. I have been looking at lectures , some by David Rowland, about real time audio programming design patterns. These videos:-

and

But at this point it has left me with even more questions about how to begin tracking down exactly what this problem is… or could be. So I am now starting to think that I could be going down the completely wrong rabbit hole. Can anyone point me in the right direction? Any help would be appreciated.

Thanks.

EDIT: I have tried to edit this post to reflect what I believe the problem to be or related to, as I have been testing and commenting out functionality. As such, the original title of this post has been changed as well as some of the contents of it.

Doesn’t sound like a data race to me, as this would lead to undefined behaviour, not lagging. It sounds more likely that you’re overloading the GUI thread, perhaps with repaint calls or something similar.

I’d suggest peppering your code with DBG messages (or setting a bunch of break points which don’t actually break but just print out a message). If you see some message printing out a thousand times in a split second, this will help you find the problem.

Question: how many Timers do you have running at once? If you have a lot (i.e. one per bank), then that’s going to scale up quite badly. Better to pool all of your pending updates in an array and have one central timer to deal with them.

I just have 2 timers - One in the audio processor, the other in the editor. The banks are just collections of patches, and the patches are essentially just a collection of data that is used when you switch to them to set all of the parameters using setValueNotifyingHost(), if their value is not already set.

EDIT: All the timerCallback() in the audio processor really does, is check if you have toggled patches. If you have, it then performs the actual toggle. Which involves updating any parameters that have changed, and also switching audio outputs if neccessary.

Btw… I will take a look at that debug message thing now.

I cannot see any massive amounts of paint calls.

It seems to be tied to when parameters are changed using setValueNotifyingHost(). If I comment out those lines then the GUI doesn’t lag anymore. Also, if the Editor is closed then it doesn’t lag anymore… as in, Reaper doesn’t lag anymore. It seems the plugin is stealing GUI updates away from the host. It is easy to see when I leave a silly little melody looping and can see the audio meters lag when I change a patch with the editor open.

But obviously, I need to be able to notify the host of these parameter changes or all is lost.

Assuming it happens in debug builds too, if you pause the debugger when it is frozen, what is the message thread doing?

I think I have paused it while it is lagging. Which wasn’t easy to do. Which thread is the message thread? how can I identify it? All I see is the main thread and a bunch of non-descript worker threads.

Okay I deleted my rambling because they were just that.

When it lags it seems to sometimes not count me pressing any midi controller button. It doesn’t toggle sometimes.

I see 3 threads. The main thread, a timer thread, and a pool thread.

It seems that the problem is tied to having lots of parameters. If I reduce it down to 8 then it is fine, but I need like… 32. Lol. What could be blocking the GUI? Is it entirely on Reaper’s end? Well… it can’t be can it? Other plugins I have used don’t have this problem. :S.

If I call anything such as beginChangeGesture(), setValueNotifyingHost(), or endChangeGesture(), upon an audio parameter pointer to the parameter in the audio processor value tree state, the problem begins. It doesn’t have to be just setValueNotifyingHost() itself.

32 is not much at all!

Well exactly, this is what is confusing me. But I have seen other people complain about similar behaviour and various DAWs. But I have also seen plugins that have suffered from these kinds of issues get fixed up and work fine since. So… there must be a way. Very odd.

There must be some kind of bug in the juce framework. It has to be the case. I can recreate the problem by just making a new project and adding parameters. There is literally nothing my code is doing that I shouldnt be able to do… is there? setValueNotifyingHost not correct?
EDIT: I also think a lot of devs either give up and stop posting about it, or move onto another DAW. At least, every thread I have seen that talks about this ends in them either never getting a response, or giving up on their project… or just making concessions. But I don’t see why that would be a good idea. I am never going to stop using Reaper. So there must be an answer to this, otherwise reaper wouldn’t work with any plugins at all. Surely?

If only Jules or someone could appear and tell me its all my fault, i should be doing this… and that is why. lmao. awww damn!

Generally it’s not a bug in the framework. We do a lot of complicated stuff and about one bug in every hundred is a JUCE one.

Have you tried running it in the profiler? 32 parameters doesn’t sound like many…

1 Like

literally… all i have done is added a bunch of parameters and then call that method on them. i dont really know what to run in the profiler for it. i mean… it aint my code. I understand what you are saying… but other people have told me elsewhere they have had the same issues with the framework and just gave in.

I invite people to just download reaper, and try it themselves. honestly… i am at a complete loss.

EDIT: Unless of course… i shouldn’t ever call that method (setValueNotifyingHost)??

Try specifically what though - have you got some example code? I use reaper all the time for testing.

well… i just created a bunch of parameters in the APVTS… 40 to 45… then it lags when I call that method on any of them. If i have just a few… its fine.
EDIT: I say 40-45… because I have a few extra. Theres 10 just for the 8 patches and the bank up and bank down… but i am not even using those half the time. The problem happens whenever setValueNotifyingHost is called. or… beginChangeGesture() / endChangeGesture() even.

Make a very simple example that shows the bug and that I can compile and I’ll test it here.

Sound okay… I deleted the last (test) project but I will make a new one, add parameters to the apvts and send it over.

Yep that’d be a good way to get some support on this.

The advice from the C++ channel on freenode is good when it comes to getting help with bugs:

" I have a problem with my code, how should I share it for people to review?

First of all, your code should exhibit the problem you are having and should be a ‘‘self-contained’’, and ‘‘reproducing’’ example (see “The Short, Self Contained, Correct, Example” page). If the code is too large, please consider reducing it to a more minimal example that still exhibits the problem (see the bisection method ).

Please don’t share non-runnable pieces and fragments of your code, see “Show Us The Whole Code” .

If you have more than one file in the project, then you should put it in a self-contained version control repository on a code sharing site such as GitHub , Bitbucket , or GitLab , so we can easily clone or checkout it."

Don’t worry. I will strip it back to the basics. It’ll be a fresh project with just the offending code. And if this doesn’t do it now… I am going to lose my mind. Lmao.

You want me to share it on git? It is going to be basically no code at all. lol.