Hello, I’m sending parameter changes from my plug-in to an InterprocessConnection server, which distributes the changes to all the other instances. I check that a plug-in is not sending changes to itself, but I can’t tell the others to not re-send the change (exponentially filling memory! )
I need a way of distinguishing between the server sent parameters and user changed parameters. The only way I think I can do that is to make a direct copy of all the possible parameters and add a token to the name to tell the parameterChanged function not to resend it. It’s a bit unwieldy but it will work.
I’m fine doing it that way but I wonder if I missed a more elegant way of doing this, because I don’t know the parameter value tree process very well.
Edit
I might try time stamping the messages to identify repetition.
Sounds like you’re using a mechanism to update the parameters that the plugin can’t distinguish from a normal parameter change, such as from automation? Why not just add a function in the plugin that will accept notifications from the server and in that function, simply update the parameter without notifying your server whenever the change is from that local function?
Thanks for the suggestions, it’s making my head hurt today.
I’m sending parameter changes from ‘parameterChanged’ which I thought was the only location to grab the changing values but then it sends the same values around and back into parameterChanged in the other instances again.
I’m currently look at storing the current values in a simple unordered map, and stopping it for repeating the same parameters and values. A few bugs aren’t helping me today.
@JeffMcClintock : Yes, a source never sends itself data but all the other instances become the source when they get the values, so the source changes. I need to not resend the same data around, which is what I’m currently trying to do with the server, debugging is not easy with multiple instances, and I think I may have a bug or two at the moment.
I’ll get back with progress.
We do that, and what we do is have parameterChanged() call a function we named doParameterChanged(), which has the same function parameters but adds a default “bool doBroadcast = false” at the end of the parameter list. Then we pass true for that parameter when we want to broadcast a change, but all other calls default it to false, so it’s not re-broadcast.
HowardAntares
Interesting, I think I understand, but how does it know the parameter was broadcasted to it if it’s an automatically called parameter change Juce function?
Because when broadcasting to the other plugins, my broadcaster calls my new public doParameterChanged() with false as the last function parameter. This is instead of calling parameterChanged() from the broadcaster.
My parameterChanged() function simply calls my new doParameterChanged(), with true for the last function parameter, while the broadcaster calls it with false there. That way, when called from my broadcaster, nothing is further broadcast, but when called from within the plugin (automation, attachment, whatever), it does broadcast to my broadcaster class.
Thanks, I need all the GUIs to update as well as the parameters though, I don’t want it to
just change internal values. All the instances have to behave like the user is changing a knob etc, I can’t do that if I just call parameterChanged, can I?
I thought I had to go through setValueNotifyingHost to set values correctly for each instance.
edit
I’m using a callback timer to grab changes, but the values change too quickly, speeding up the timer helped enormously but it still can’t catch up sometimes, so I’m going to store only changed values since the last timer callback rather than feed changes straight from parameterChanged as it piles up too much, potentially slowing down everything along the way.
Something to try tomorrow anyway…
Very nice, thanks Howard. But it gives me more questions…
What calls handleParameterNotification?
Where is the gesture sent from?
sendValueChangedMessageToListeners calls my parameterChanged anyway and loops my message, so you can’t send it from there.
I guess I’m even more confused now.
Oh, you’re using a pre-made broadcaster? Is that the InterprocessConnection server you mentioned? We have our own custom broadcaster, so we are in charge of what calls it makes. Ours calls a specific public callback function we added to our Processor class, which allows us sending parameter changes or other changes, using a message type of our own design. That callback function then calls the function I posted above, when it’s a parameter change message. If you can’t modify your broadcaster (such as by deriving from it and overriding the function that sends the notification to call some other callback function), then my solution won’t work for you. But most classes can be derived from in Juce. I’d be surprised if you couldn’t customize that code to call whatever you want.
Hmm, yes I have full control over the server, but what sends the gesture to it? I had almost the same code as you, but the problem is when the user changes a control, the control gets sent back to all the others which in turn send it again.
Can you tell me where the actual control turn is sent from? Is it sent from the GUI itself? I need to escape the feedback loop.
We send the message to our broadcaster at the end of the Processor’s new doParameterChanged() function, whenever that extra bool flag is set to true. Since our actual parameterChanged() function simply calls doParameterChanged(), passing it true, that means all automated parameter changes or changes form control surfaces or from parameter attachments will send the message to the broadcaster. But when receiving a parameter message via the code I posted, false is passed to that parameter, so it doesn’t re-send the parameter change notification. Also, the code I posted only sets the parameter to its new value IF it has changed, and sets the parameter directly, not through the setParameterNotifyingHost() function, so it doesn’t lead to a call to parameterChanged() behind the scenes.
From my tests sendValueChangedMessageToListeners() calls parameterChanged() internally so I can’t escape the resend thing. I have another bug with checking resent blocks though, so I’ll refrain from asking anything else until I get that fixed.
Thanks for your time.
Okay, sorry if my idea won’t work for you. A couple more thoughts…
If these are all automatable parameters, then a number of DAWs allow linking the parameters between instances. That way, you don’t need to broadcast to them yourself. I don’t know which DAWs, though. Pro Tools for sure.
And make sure whatever method you choose, it is handled in the Processor, not the Editor, because the Editor of a given plugin instance may or may not exist at any given time.
I don’t get you. What listeners are you referring to? It’s fine if my UI listens to changes. That function only calls the listeners’ parameterValueChanged() function, not the processor’s parameterChanged() function. Different callback.
for (int i = listeners.size(); --i >= 0;)
if (auto* l = listeners [i])
l->parameterValueChanged (getParameterIndex(), newValue);
HowardAntares
Hello again. It’s only dumb old me!
Can you or anyone show me how to create my own listener with it’s own parameterValueChanged?
I need it to intercept the calls like Howard mentions above.
I’m going around in circles here, I would post some of my code but it’s always hopelessly wrong, and gets deleted every five minutes. ( I would tear my hair out if I had any )
I think I need to inherit a ParameterAttachment but every way I try ends in failure, also with my own version of SliderParameterAttachment. I just need a direction.
Is there an example demo anywhere? A Web search is turning up nothing directly relevant, just more complications.