AudioProcessorValueTreeState Improvements


#21

Could your AnotherProcessorClass have a method that returns an array of AudioProcessorParameters (or perhaps a group of them) which you could then pass to the ParameterLayout constructor after you’ve initialised?

Something roughly along the lines of:

struct MainProcessor : public AudioProcessor
{
    MainProcessor()
        : state (*this, nullptr, "state", anotherProcessorClass1.getParameters(), 
                                          anotherProcessorClass2.getParameters()), 
    {
    }

    AudioProcessorValueTreeState state;
    AnotherProcessorClass anotherProcessorClass;
};

#22

not really, because my “AnotherProcessorClass” constructor is expecting the AudioProcessorValueTreeState as parameter.

Of course I could change that, do things differently, but I wanted to stress the point that the new way can imply quite a few changes.

I just hope you will keep the old constructor around for a while… (I’m really not against the latest changes, which are most likely an improvement, but it’s quite some work to stay up to date with changes and depreciations lately)


#23

Hi All,
I am playing around tutorial Cascading plug-in effects using processors which already use APVTS, similar like @lalala mentioned.

For now I had implementation more or less like @t0m proposed, but I wondering if each processor could have its own APVTS. Then in main processor methods getStateInformation and setStateInformation would be a little more complicated. But I think AudioPluginHost has such implementation already. There is static function createNodeXml in FilterGraph which calls
node->getProcessor()->getStateInformation (m);

Is there anything against using own APVTS object in all “anotherProcessorClass-es”?
Does it sounds reasonable?

Kindly regards,
Mateusz


#24

I think it’s good that you’ve got the AudioParameterX classes back into the APVTS stuff. However, the best practice method seems to make it hard (impossible?) to use NormalisableRange::setSkewForCentre().

To grab an existing chunk of code as an example:

auto bwp_range = NormalisableRange<float>(MINUS_THIRTY_SIX_DB, 1.0f); bwp_range.setSkewForCentre(Decibels::decibelsToGain(-8.0f)); brick_wall_param = parameters.createAndAddParameter(std::make_unique<Parameter>("limit", "Target Max Signal", "dB", bwp_range, 1.0f, db_to_text, db_from_text));

Using parameters.getParameterRange("limit").setSkewForCentre(Decibels::decibelsToGain(-8.0f)); after the constructor block doesn’t work because getParameterRange returns a copy of the NormalisableRange.

parameters.getParameter("limit")->getNormalisableRange().setSkewForCentre(Decibels::decibelsToGain(-8.0f)); doesn’t work because this time it returns a const.

Any recommendations?


#25

I haven’t tried it, but I would expect something like this to work:

juce::AudioProcessorValueTreeState::ParameterLayout makeParameters() {
  auto param = std::make_unique<juce::AudioParameterFloat>(...);
  param->range.setSkewForCentre(...);
  return { std::move(param), /* any extra parameters go here */ };
}

// When constructing your apvts
MyAudioProcessor()
  : apvts { *this, nullptr, "state", makeParameters() }
{
}

#26

Thanks, that seems so obvious now. :thinking: