How can i set a certain parameter not Automatable?

It looks to me like you would need to create a class which inherits from AudioProcessorParameter (or from another class which itself inherits from AudioProcessorParameter, such as AudioParameterFloat) and overrides the virtual method AudioProcessorParameter::isAutomatable() to return false. Then pass an instance of your new class to AudioProcessor::addParameter.

I see, So we have to create new classes in which we have set IsAutomatable() to false, and at the end we have something like the following, or am i lost?

New_addParameter (Param2 = new New_AudioParameterFloat (“Param2”, “Param2”, 0.0f, 1.0f, 0.03f));

Is this all necessary?

Maybe a silly question, but what is the purpose of a non automatable parameter?
I would have thought float x; is a non automatable parameter :wink:

3 Likes

That would be a parameter that you want to save/load/set/get like other parameters, but you don’t want it to be automated or recorded by the host. For example a menu with some list to choose from. Maybe you want it only to be accessed from the UI.
I don’t know about other DAWs but FL Studio only lists a parameter that is automatable, so other parameters are hidden from user, which is nice.

I understand.
So the solution would be still to ignore AudioProcessorParameter and instead you can save that in the void AudioProcessor::getStateInformation ( juce::MemoryBlock & destData). You can write anything into the MemoryBlock and when a session is restored, you get exact that MemoryBlock back in AudioProcessor::setStateInformation, so you can use it in your plugin or gui.

There is also a nice solution to set the AudioProcessorValueTreeState::state. You can store that complete tree in that MemoryBlock with (almost) one line of code. I did a demo here:


and the saving you see here:
https://github.com/ffAudio/ffTapeDelay/blob/master/Source/PluginProcessor.cpp#L224

1 Like

The custom class can allow you to set the “isAutomatable” parameter indeed, but there is a problem with this appraoch : some hosts like Ableton Live don’t care about that property, even if it is something than can be found in the VST format API for a few years. So you need to use another solution whatever.

1 Like

Thanks Daniel. I’m using xml in my set/get stateinfo, and when i don’t use addParameter i’m getting into other troubles and working around them may not worth the effort since you said some hosts don’t use automatable flag at all.
Just wanted to prevent the user from doing something stupid hehe. Looks like I’m gonna leave it for now.

so if you are already using xml in your get/set state information, would be easy to add a xml leaf or a property to store your parameter in there…
In the getXmlProperty simply use a default value or use a getOrCreateChildNode to access the leaf, then you are even backwards compatible with older sessions… just a thought…

Although you might want the parameter to appear in the generic parameters list but still not be automatable (another example would be a relatively CPU heavy re-initialisation that is triggered when this parameter changes like recalculating an impulse response).

The overriding of AudioProcessorParameter::isAutomatable() to return false seems the way to go. Plus you would need to be calling AudioProcessorParameter::beginChangeGesture() and AudioProcessorParameter::endChangeGesture() in order to record the automation from the UI. So of course you would avoid doing this too in your non-automatable parameter.

Can someone explain this to me. Does isAutomatable() is being directly called by host or there is something else going on? Can’t we get the parameter id that is being checked? so we can do this:

bool isAutomatable(paramID) { if param1 retun true; if param2 retun false;}

I mean we don’t need to flag all the parameters at once.

Yes, it’s called directly by the host on the individual parameter, so you have to change it within the parameter.

The AudioProcessorParameter::isAutomatable() implementation just returns true always, so you have to derive from APP and override it manually. I just did it myself, which is how I found this thread in the first place. The change is trivial:

bool isAutomatable() const override { return canAutomate; }
virtual void setIsAutomatable(bool inBool) noexcept { canAutomate = inBool; }
protected:
bool canAutomate;
1 Like

Okay this makes it easy to set isAutomatable() , but whats the point? how can you apply it for individual parameters?

You just call that setIsAutomatable method with true/false from the parameter you want to change, like any other parameter method. It’s not special in any way. Here’s example code from my AudioProcessor constructor that uses my above setIsAutomatable to make gainParam report false and targetGain report true (true is the default). DecibelParameter is my derived class containing the above code and “params” is a derived class based on AudioProcessorValueTreeState

targetGainParam = params->createAndAddDecibelParameter(targetGainParamID, "TargetGain", -96.0f, 18.0f, -18.0f);
gainParam = params->createAndAddDecibelParameter(gainParamID, "Gain", -96.0f, 18.0f, 0.0f);
gainParam->setIsAutomatable(false);

Now my plugin reports to the host that targetGainParam is automatable and gainParam is NOT automatable, ie at the individual parameter level.

Be careful though! As @IvanC pointed out above, Ableton Live (at least) ignores this flag. Just because you can override AudioProcessorParameter::isAutomatable() doesn’t mean it’ll do you any good.

I get it but its not working for me. By following your instructions, I can still automate the parameter. I don’t have a deep programming experience though might be missing something.

You’re not missing something, you’re just encountering what those people above are pointing out. The SDK does NOT require a host to honor your parameter’s isAutomatable() value, or to even check it at all. Having a parameter respond with False for isAutomatable is at best a suggestion to the DAW. The DAW is free to behave however it wants with regards to automation – it’s perfectly likely that the host sees your plugin report that a parameter isn’t automatable, but the host says “Nope, too bad, I’m letting people automate it anyway.” and completely disregarding your preference.

If you don’t want any DAW to have the ability to potentially automate a parameter, you simply have to not expose that parameter to the DAW by NOT adding it to the parameter list, IE from your example:

addParameter (Param1 = new AudioParameterFloat ("Param1", "Param1", 0.0f, 1.0f, 0.03f));
Param2 = new AudioParameterFloat ("Param2", "Param2", 0.0f, 1.0f, 0.03f);

Ah your’re absolutely right, even by changing IsAutomatable to true for all parameters it doesn’t make a difference.
When i don’t add a parameter to the list then i think using setValueNotifyingHost() in editor causes an error:

processor.Param2->setValueNotifyingHost(0);

Also what happens with saving and loading state information? Does it still work considering we didn’t add some parameters to the list?

for (int i = 0; i < getNumParameters(); ++i)
if (AudioProcessorParameterWithID* p = dynamic_cast<AudioProcessorParameterWithID*> (getParameters().getUnchecked(i)))
xml.setAttribute (p->paramID, p->getValue());

Well yeah, it’s supposed to cause an error. Using setValueNotifyingHost is doing the precise thing you’re trying to keep from happening. What exactly are you trying to notify the host of? You’re hiding the parameter from it on purpose, why would you be trying to notify it of changes so it can handle automation when your entire purpose here is to PREVENT the host being notified of anything or allowing automation? If you’re going to explicitly avoid adding these parameters to the host’s list, you absolutely do not want to use setValueNotifyingHost with them…

State information is exactly what you ask it to do. That code snippet you pasted handles parameters that have been added to the host and nothing else. So no, your non-automatable parameters won’t be saved/restored with that code. You’ll have to add to it in order to handle your non-added parameters. The most robust way is to add them all to a state ValueTree. daniel gave a pretty thorough explanation of doing so up above.

Okay i don’t wanna waste anybody’s time here, but i don’t see any other way to change the parameter value. well i can’t use setValue() for some reason. So i’m not sure how to set a value for that parameter.

The host saves the parameters it is aware of. And that’s the parameters you called addParameter for. Anything else you store yourself in setStateInformation and getStateInformation.
If you want to notify the host that something in the state has changed, which is not an parameter, then you can call AudioProcessor::updateHostDisplay(), so it knows it needs to call getStateInformation and write it’s session.
So there is really no need to use a AudioProcessorParameter if you don’t want the host to automate it.

1 Like