New Parameter API: potential big problems arising

Hi,

i use several wrapper types for AudioProcessor, which wrap one AudioProcessor into another. With the old API-Level this was easy and no problem because of the structure of the API, like:

   float getParameter (int parameterIndex) override
   {
        	return wrappedProcessor->getParameter(parameterIndex);
   }

I guess a lot of people doing similar things, because of the “virtualness” of the methods which is some kind of “insurance” of the structure.

If new versions of plugin-wrappers use AudioProcessorParameter directly, how to deal with this situation? Removing virtual functions is fundamental breaking change.

The old way of doing things will still work (albeit it will hit you with an assertion). The new way of doing this would be something like this:

class WrapperProcessor
     : public AudioProcessor
{
public:
    WrapperProcessor (AudioPluginInstance* processorToUse)
        : AudioProcessor (getBusesPropertiesFromProcessor (processorToUse)),
          plugin (processorToUse)
    {
        updateParameter();
    }
    
    //==============================================================================
    .
    .
    .
    //==============================================================================
    class AudioParameterWrapper : public AudioProcessorParameter
    {
    public:
        AudioParameterWrapper (AudioProcessorParameter& paramToWrap)
            : wrap (paramToWrap)
        {}
        
        float getValue() const override                          { return wrap.getValue();        }
        void setValue (float newValue) override                  { wrap.setValue (newValue);      }
        float getDefaultValue() const override                   { return wrap.getDefaultValue(); }
        String getName (int maxLen) const override               { return wrap.getName (maxLen);  }
        String getLabel() const override                         { return wrap.getLabel();        }
        int getNumSteps() const override                         { return wrap.getNumSteps();     }
        bool isDiscrete() const override                         { return wrap.isDiscrete();      }
        
        String getText (float v, int len) const override         { return wrap.getText (v, len);        }
        float getValueForText (const String& t) const override   { return wrap.getValueForText (t);     }
        String getCurrentValueAsText() const override            { return wrap.getCurrentValueAsText(); }
        bool isOrientationInverted() const override              { return wrap.isOrientationInverted(); }
        bool isAutomatable() const override                      { return wrap.isAutomatable(); }
        bool isMetaParameter() const override                    { return wrap.isMetaParameter(); }
        Category getCategory() const override                    { return wrap.getCategory(); }
    private:
        AudioProcessorParameter& wrap;
        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AudioParameterWrapper)
    };
    
    void updateParameter()
    {
        auto& params = plugin->getParameters();

        for (auto* param : params)
            addParameter (new AudioParameterWrapper(*param));
    }
    
    ScopedPointer<AudioProcessor> plugin;
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(WrapperProcessor)
};
3 Likes

That’s an awful lot of boilerplate just to forward a method… is it possible for you guys to not deprecate getParameter/setParameter so we don’t have to use the Parameter class all the time?

It’s not forwarding a method.

It’s forwarding about 15 methods, and is a totally reasonable amount of boilerplate for that job.

And it’s pretty much the same amount of code you’d write if you were using the old methods to do the forwarding. I remember writing a similar wrapper class a couple of years ago for NOISE and it was much bigger than this.