I’m moving from JUCE 5.4.7 to JUCE 6, and have a question about using the various ParameterAttachment classes (ButtonParameterAttachment, etc.).
I have created parameters that I don’t want published for host automation, and want to attach them to my controls. So I added the attachments, and connected them in the view classes. In my processor class, I added the processor as a listener to the parameters.
Unfortunately, when I move a slider that is connected in this manner, I get an assertion in this code:
// This method can't be used until the parameter has been attached to a processor!
jassert (processor != nullptr && parameterIndex >= 0);
The assertion fails because processor is NULL and parameterIndex is -1.
Since the parameter has not been added to the APVTS, I’m confused as to why the parameter expects the processor to be connected and there to be an index with which to access the parameter list in the processor. I thought the whole purpose of this new ParameterAttachment class was to allow a complete disconnect from the APVTS, right?
Is there some step I’m missing? Or should I not be using param->addListener(this) to add the processor as a listener?
As you rightly said, the APVTS is not a requirement for the new attachments. However, to function correctly the attached parameters must be owned by an AudioProcessor, which can be achieved by passing the parameter to AudioProcessor::addParameter. To disable host automation on a particular parameter, you can derive a new parameter type and override isAutomatable to return false.
Ok, well, that’s not going to help, then. Some hosts simply ignore that flag, and show every parameter. So, in 5.4.7, I changed all my non-automatable parameters to atomic values, and added explicit code to request changes to them, and respond to changes in them. But now that we’re moving to 6, the hope was that we could have parameters that hosts never see, but which automatically update the UI controls (and vice-versa). I thought that was the entire reason for the new ParameterAttachment class.
I see that the problem has nothing to do with adding my processor as a listener. It comes simply by having a parameter attached to via one of these ParameterAttachment objects.
The code in that function already checks at runtime whether the processor and parameterID are valid, and skips the related code if not. So why won’t it work without setting those? All I need is a way to easily attach UI controls to processor-based values in a thread-safe manner. If not by using ParameterAttachments, then how? Do I have to go back to manually-managed atomics?
I think you mean this. It would be nice to have something like it but with a NormalisableRange and a default value, specialized for button and slider. Like, the other side of the old attachments, without a parameter behind.
Even with a parameter, something like that could work. After all, the parameter has a ParameterID and a value, both of which are normally passed to parameterChanged(). If it just used the ParameterID, then it could call back to parameterValueChanged() instead, but using the ParameterID instead of getting its index and passing that.
Guess I have to go back to my old method of managing these with atomics myself.
Last time I checked a few years ago, none of the hosts that I tried cared about if a parameter is atuomatable or not , they were exposing everything to the user. Maybe it’s better now, I don’t know but back then I also set up my own parameter handler system, that wraps the parameters and registers only those in the processor that I want to expose to the host.
I think Ableton Live with VST2, and Studio One and Reaper for Audio Unit plugins, at least. It seems to me that there were more AU hosts that did this until I modified the auwrapper I was using (prior to JUCE) to set a “read-only” flag whenever the automatable flag was not set. (In Studio One, that just made the name appear as blank in the parameter list, but didn’t affect the ability to automate them.)