Are beginChangeGesture/endChangeGesture optional?

Are beginChangeGesture and endChangeGesture optional, when setting a parameter?

I don’t see them used in the JUCE examples. If I’m just setting a parameter once, rather than repeatedly changing it while a control is being moved, do I need to wrap it in these calls?

I’m mostly asking because I have some code for saving/loading presets, that changes all parameters at once, and I’m not sure if I need to wrap each assignment statement separately.

Thanks,
Jacob

These calls are not optional. They are required to make automation work in hosts are able to record parameter automation and tell the host when and for what parameters to record automation.

Thanks @pflugshaupt!

They’re handled for you if you use the APVTS class which is why you don’t see them explicitly called in the demos.

Check out the AudioProcessorParameter class.

Rail

@railjonrogut Do you just mean that they’re handled when I’m changing them from controls that use attachments? I see that happening in ParameterAttachment::setValueAsCompleteGesture.

But I don’t see anything in AudioProcessorValueTreeState itself that calls these gesture functions.

I store my parameters in an APVTS, but I sometimes need to change them programmatically, e.g. I have a “randomize” button that changes various parameter values. In that case I’m just getting the AudioProcessorParameters and calling their assignment operators. Should I be doing this through AVPTS somehow?

Right - when you use an attachment. Otherwise you should handle the notifications to the host.

I personally have a ParameterReferences class with getters and setters and each parameter is referenced by a RangedAudioParameter pointer which is the base class of the AudioParameter~ classes. So when I set a parameter using my ParameterReferences class’ setter… it uses the AudioParameter~ classes to set the values… which notify the host.

ParameterReferences::ParameterReferences (AudioProcessorValueTreeState& state)
{
gain = state.getParameter (g_GainID);
phase = state.getParameter (g_PhaseID);

:

}

and in my main AudioProcessor’s ctor the first thing I call in the body of the ctor is:

m_pParams.reset (new ParameterReferences (state));

since the state is initialized in the AudioProcessor’s initializer list.

For things like using draggable nodes in the UI I do have class members…

void ParameterReferences::beginGainChangeGesture (int iBandNum)
{
    if (isPositiveAndBelow (iBandNum, NUM_OF_BANDS))
        {
        BandParams*  bandParams = m_BandArray.getUnchecked (iBandNum);
        
        if (bandParams != nullptr)
            bandParams->gain->beginChangeGesture();
        }
}

void ParameterReferences::endGainChangeGesture (int iBandNum)
{
    if (isPositiveAndBelow (iBandNum, NUM_OF_BANDS))
        {
        BandParams*  bandParams = m_BandArray.getUnchecked (iBandNum);
        
        if (bandParams != nullptr)
            bandParams->gain->endChangeGesture();
        }
}

which I call when the nodes are started to be dragged and when they’re no longer being dragged.

Rail

@railjonrogut Thanks! Appreciate you taking the time. I have a similar wrapper class where I store state parameter references, so maybe I’ll also add some setters that call the begin/=/end methods.