Using AudioProcessorValueTreeState

(I’m very new to this so please pardon my ignorance)

I’m trying to follow along with this tutorial:

And I’m having trouble getting the Audio ProcessorValueTreeState to actually work. It seems like a few things he’s using have been deprecated, in particular:

ScopedPointer<AudioProcessorValueTreeState::SliderAttachment> filterCutoffValue;
ScopedPointer<AudioProcessorValueTreeState::SliderAttachment> filterResValue;
    
ScopedPointer<AudioProcessorValueTreeState::ComboBoxAttachment> filterMenuChoice;

So I can’t figure out how to declare the tree attachments.

It also looks like

createAndAddParameter()

Is going to be deprecated and google has not yielded an alternative that I can understand.

I also seem to be getting a ton of errors with the AudioProcessorValueTreeState header file itself even though I haven’t touched it.

My questions are twofold:

  1. How do I fix my current issue?
  2. Can someone point me towards a video or something on using AudioProcessorValueTreeState so I can get a better handle on it?

The attachment classes are not deprecated, ScopedPointer is. Use std::unique_ptr instead.

The errors you’re seeing could be a number of things, you’ll have to be more specific. Which errors, on which platform?

The current way of creating parameters is passing a ParameterLayout to APVTS’ constructor. This usually involves having a free function that returns a ParameterLayout. The layout is filled with unique_ptrs containing each of your parameters, so your function may return a braced list with calls to std::make_unique:

juce::AudioProcessorValueTreeState::ParameterLayout createParameters()
{
    return { std::make_unique<juce::AudioParameterFloat> (/***/),
             std::make_unique<juce::AudioParameterChoice> (/***/),
             /* etc */ };
}

Alternatively, you could create a vector, add your parameters there, then return the begin/end iterators:

juce::AudioProcessorValueTreeState::ParameterLayout createParameters()
{
    std::vector<std::unique_ptr<juce::RangedAudioParameter>> parameters;
    parameters.reserve (/* nr of parameters */);
    parameters.push_back (std::make_unique<juce::AudioParameterFloat> (/***/));
    /* or */
    parameters.emplace_back (new juce::AudioParameterFloat (/***/));
    /* etc */
    return { parameters.begin(), parameters.end() };
}

Then in your processor:

class MyAudioProcessor : juce::AudioProcessor
{
    juce::UndoManager undoManager; // if you're using one
    juce::AudioProcessorValueTreeState apvts{ *this, &undoManager, "my plugin",
                                              createParameters() };
    /* etc */
}

Because this is all quite verbose, instead of a free function I use a function object with some helpers, so the code that actually adds the parameters gets a little more concise.

I seem to be getting these errors on even brand new projects now (using xcode):

/Users/mbarbara/JUCE/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h
/Users/mbarbara/JUCE/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h:45:53 Unknown type name 'StringFro'

/Users/mbarbara/JUCE/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h:45:74 Expected ')'

/Users/mbarbara/JUCE/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h:45:118 No member named 'attributes' in 'juce::AudioProcessorValueTreeStateParameterAttributes'

/Users/mbarbara/JUCE/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h:45:130 Use of undeclared identifier 'attributes'

/Users/mbarbara/JUCE/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h:45:181 Use of undeclared identifier 'x'

/Users/mbarbara/JUCE/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h:47:19 Expected member name or ';' after declaration specifiers

/Users/mbarbara/JUCE/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h:500:76 No member named 'withLabel' in 'juce::AudioProcessorValueTreeStateParameterAttributes'

Did I break JUCE or something?

As for the rest of it, I’m going to try and wrap my head around that over the next day or so and poke you if I have any questions.

I seem to have resolved the errors by re-installing JUCE. I don’t quite understand why the following code is giving me an “error, no overloaded ‘=’” error though.

.cpp:

filterCutoffValue = new juce::AudioProcessorValueTreeState::SliderAttachment (audioProcessor.tree, "cutoff", mCutoffDial);
filterResValue = new juce::AudioProcessorValueTreeState::SliderAttachment (audioProcessor.tree, "resonance", mResdial);
filterMenuChoice = new juce::AudioProcessorValueTreeState::ComboBoxAttachment (audioProcessor.tree, "filterMenu", mFilterMenu)

.h:

std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> filterCutoffValue;
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> filterResValue;
std::unique_ptr<juce::AudioProcessorValueTreeState::ComboBoxAttachment> filterMenuChoice;

Again, super new to JUCE and CPP in general so I’m definitely doing something dumb.

There’s no implicit conversion to std::unique_ptr<T> from T* (a plain pointer, which is the return of new). That constructor (2) is marked explicit, precisely to avoid this kind of thing. You have these alternatives:

filterCutoffValue = std::make_unique<juce::AudioProcessorValueTreeState::SliderAttachment> (audioProcessor.tree, "cutoff", mCutoffDial);

filterCutoffValue.reset (new juce::AudioProcessorValueTreeState::SliderAttachment (audioProcessor.tree, "cutoff", mCutoffDial));