How can i set a certain parameter not Automatable?

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

is this still the case? Are there any other Hosts with this issue?

It is not an issue, it is the DAW creators either ignoring you or say for the best user experience we expose everything we know of straight to the user. It won’t change, some hosts will continue to do that, others don’t.
Couldn’t explain it better than SonicZentropy did:

1 Like

For anyone who wants 100% threadsafe, 100% non automatable parameters and all attachment stuff from apvts, just create another apvts for hidden parameters and give it a dummy audioProcessor that does nothing at all.

4 Likes

@moritzsur Could you please show an example of how to setup 2 audioProcessors and 1 editor?
I don’t really understand how to do it.

  1. create a subclass of juce::AudioProcessor that isnt abstact (override all pure virtual functions). This the dummy processor class
  2. create 2 apvts.
    For the automatable apvts supply the main audio processor in constructor.
    For the hidden parameter apvts supply the dummy processor in constructor.

why not use the same apvts?

Hosts tend to ignore the isAutomatable flag, so every audioparameter in the apvts could be automated. Using the underlying valuetree doesnt give you all the apvts stuff or threadsafety.

the state could be saved in the valueTree as something else than a parameter. thread-safety then depends on the way the state is accessed

Thank you @moritzsur for the feedback I will try it this way :slight_smile:

However don’t you notice any bug or weird behavior using this method?
I’m working on a production app and worried about having issue with the users after launching it.

@reuk you seems to have a lot of knowledge regarding everything related to parameters. I would appreciate if you give your feedback on this :slight_smile:

@Mrugalla you could use ValueTree to hide parameters from the automation. I’m currently doing this and I can tell you that it’s a lot of code to write and you’re responsible of the thread-safety…

you could also just consider non-automatable parameters to not be parameters at all. for example you might just add a property to your parameter apvts’ state called “Oversampling” and it can be “enabled” or “disabled”. your serialization code would load and save that with the parameters but without making it automatable. it’s a good example of a thread-safety issue as well because oversampled audio needs longer audio buffer for a given blocksize. in response to such a change of state you could either let processBlock directly resize those buffers or use an elaborated system with fifos or release pools and stuff like that to sneak the updated oversampler in between the process calls. i don’t see how having a seperated apvts would solve such issues tho. does anyone have an example for that?

didnt found any problems yet :slight_smile:

1 Like

I only used the isAutomatable() flag in our latest product. It works in most hosts for VST3 (Ableton Live) and also Logic X filters out the parameters. I noticed no problems so far.

The best solution would be if juce does not register parameters to the host that has this flag set. I think every bigger plugin project has some “hidden” parameters that we don’t want to share with the host.

1 Like

@kunz This behavior seems to be new. For few years I still hear that the isAutomatable flag was ignored by host :thinking:

To repeat what I said here and in other conversations about that topic:
The AudioParameter interface has the only purpose to communicate values to and from the host.
Adding a parameter but then excluding it again doesn’t make much sense to me.

If the expectation is to get away from threading issues, you might as well use a std::atomic and you have even the benefit that you can choose the underlying type that fits your purpose best.

It is rather trivial to write a ValueAttachment that allows components like Slider to update an atomic value.

template<typename T>
struct AtomicValue : private juce::Value::Listener,
                     private juce::Timer
{
    AtomicValue()
    {
        proxy.addListener (this);
        startTimerHz (20);
    }

    juce::Value        proxy;
    std::atomic<T> value;

    void timerCallback() override { proxy.getValue() = value.load(); }
    void valueChanged (juce::Value& v) override { value.store (proxy.getValue()); }
};

And from here use proxy.referTo()

At least that’s how I would do it.

1 Like

That’s true, but its simpler to use the same infrastructure for all parameters. There are a lot of features in the RangedAudioParameters and in the attachments.

In our case we had to reduce the number of automatable parameters because some hosts couldn’t handle them. We had too many.

2 Likes

Exactly!

Also I wanted to be able to produce “Lite” versions of an existing product by using presets I made and exposing a different parameter layout to the host (while maintaining existing audio parameters, so our modulation system is not affected).
I wrapped 2 APVTSs into one new class and used a dummy AudioProcessor for the second one. Works like a charme!

Hi guys!
Not sure if this is the right place… anyway.
I have no problems making some parameters nonautomatable, however now my host (Reaper) doesn’t consider changes of those parameters as important. E.g. when you close the window it doesn’t ask you whether you want to save your changes. I guess I should send some kind of signal to the host, like ‘hey, something has changed!’ but I don’t know how to do it.

The AudioProcessor::getStateInformation() callback asks your plug-in to store its state into a MemoryBlock object.

So whatever changes made with your “custom parameters” make sure the state also reported when getStateInformation being called.