Replicating Kontakt's parameter hiding behaviour?

There is a lot of threads here about how to make a parameter non-automatable and that Ableton Live is ignoring that call. But still, somehow Kontakt has a way around it, as they are exposing only 1 parameter when you load the plugin and you can expose more from their GUI if you click the elements…

My guess is they are registering hundreds of dummy parameters in the system when the plugin loads and when they need to expose any of those, they can set visible somehow.

Also, I found that if you delete the instrument from Kontakt, they are unable to remove those exposed parameters, and they can be only overwritten by new names if you expose more…

Here is a little video I recorded to show its behavior:
Kontakt Parameter Demo

Anybody has any idea how to do it? It could be super useful for more moduler plugin architectures.

5 Likes

We did some experiments with this but ended up not needing it. We got some way but gave up when realising we didn’t need it.

Below is some simple code you can add to a fresh Projucer plug-in project.

Basically, you can change the name of the parameter so just override getName(). For example:

struct FlexyParameter : public AudioProcessorParameterWithID
{
    FlexyParameter (const String& paramID) : AudioProcessorParameterWithID (paramID, {}) {}
    String getName (int maximumStringLength)   const override { return name.substring (0, maximumStringLength); }
    float getValue()                           const override { return value; }
    void setValue (float newValue)                   override { value = newValue; }
    float getValueForText (const String& text) const override { return text.getFloatValue(); }
    float getDefaultValue()                    const override { return 0.0f; }

    float value = { 0.0f };
    String name;
};

Then add some parameters in the Processor constructor.

const String prefix = "param_";

for (int i = 0; i < 6; ++i)
    addParameter (new FlexyParameter (prefix + String (i)));

Then to test it out you can have a UI something like this:

class FlexyParamsAudioProcessorEditor  : public AudioProcessorEditor,
                                         public Label::Listener
{
public:
    FlexyParamsAudioProcessorEditor (FlexyParamsAudioProcessor& p)
    :    AudioProcessorEditor (&p), processor (p)
    {
        const auto& params = processor.getParameters();
        
        for (const auto* param : params)
        {
            const auto* flexyParam = static_cast<const FlexyParameter*> (param);
            
            auto* const label = new Label();
            label->setEditable (true);
            label->setColour (Label::outlineColourId, Colours::white);
            label->setText (flexyParam->name, dontSendNotification);
            label->addListener (this);
            labels.add (label);
            addAndMakeVisible (label);
        }
        
        setSize (400, 300);
    }

    void paint (Graphics& g) override
    {
        g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
    }
    
    void resized() override
    {
        auto rect = getBounds().reduced (20);
        
        for (auto* label : labels)
            label->setBounds (rect.removeFromTop (30).reduced (2));    
    }
    
    void labelTextChanged (Label* labelThatHasChanged) override
    {
        const auto& params = processor.getParameters();
        const int index = labels.indexOf (labelThatHasChanged);

        if (auto* flexyParam = static_cast<FlexyParameter*> (params[index]))
        {
            flexyParam->name = labelThatHasChanged->getText();
            processor.updateHostDisplay();
        }
    }

private:
    FlexyParamsAudioProcessor& processor;
    OwnedArray<Label> labels;
};

The key is to use AudioProcessor::updateHostDisplay() after you change the name.

Notice that if the parameter name is empty then at least in Logic Pro as an AU doesn’t list it. Live using a VST2 just gives a default name if it’s empty:

But Kontakt is able to hide parameters in Live using VST2:

That looks like similar behaviour to what you have with Kontakt in Cubase (?)

Reaper using VST2 also hides parameters with empty names:

But using VST3 in Reaper doesn’t update when the parameter names are updated (so using this test plugin no parameters are ever shown).

This is all using the unmodified JUCE. Even hacking around with the VST3 SDK we couldn’t find a way to get it to update the parameters names.

4 Likes

Hi,
processor.updateHostDisplay() appears to be the key, but any tips for reseting when using AudioProcessorValueTreeState?

1 Like

Really appreciate the comprehensive answer. I have to get back to this topic the next weeks, so definitely will try out these! Thank you!

I’m pretty sure the APVTS would need some modification to support this. Even though changing the parameter name only got me so far in the above, the parameter name is const in APVTS

Yes,
The ValueTree state must be initialised after all calls to createAndAddParameter(). It is on my to do. I am really happy that the first half kinda works.
Thanks for the posts.

APVTS appears to only store the Param ID and value. So changing the name does not change the valuetree. If I change

Provides access to the parameter's name. */
/*const*/ String name;

, is this really any different to what you are doing above?

Yes that would also work, if you are happy to modify your copy of JUCE. I would always try to find a solution that avoids that wherever possible.

I now have a script to modify my copy of JUCE, including replacing some privates with encapsulated direct access via a friend class.
Did you get close to getting the automatable toggling on and off to hide params?
APVTS appears to be a step away from dynamic allocation. Having an updateable name and isAutomatable would be great additional options for the APVTS valuetree, at least while first getting StateInformation would work for me.

No, we didn’t need it in the end. And we just manage a fork of JUCE and apply our changes when we merge. I was just saying I prefer to avoid changes unless there is no option.

Cool.
Alternatively, I would love to get access to the preset data in the constructor. Has anyone achieved this?
Thank you

There is a shortcoming in the VST3 wrapper that prevents name changes to be communicated to the host. I had reported this problem before, but don’t know about the current state. See this post:

1 Like

Brilliantly helpful.
Thank you martinrobinson and wkundrus

I know this is an old post, but after struggling with how to auto-hide parameters in Ableton for a while and not finding any resources online, I managed to figure out the solution and it’s very simple: If you have more than 128 parameters, Ableton will hide them all and only show parameters whose values are modified. So to make your new parameters appear, just set them to a new value. I suspect this is the trick used by Kontakt - once parameters appear, they can only be renamed and don’t disappear.

To dynamically change the names of parameters, the solution proposed above (i.e. override getName in a custom parameter class) works fine now with VST3. To make it work with a Value Tree State, just make sure you’re inheriting a RangedAudioParameter as the VTS will not accept a straight AudioProcessorParameterWithID.

Hopefully this helps out anyone that’s trying to do modular effects.

1 Like