# Where to put initial startup parameter values for AAX?

**URL:** <https://forum.juce.com/t/where-to-put-initial-startup-parameter-values-for-aax/41600>\
**Category:** General JUCE discussion\
**Created:** [September 4, 2020, 3:55pm UTC](https://forum.juce.com/t/where-to-put-initial-startup-parameter-values-for-aax/41600 "2020-09-04T15:55:23Z")\
**Posts on this page:** 1\
**Showing post:** 18

<div class="post-metadata">

**Author:** ![StefanS](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@StefanS](https://forum.juce.com/u/StefanS)\
**Post date:** [September 11, 2020, 10:22am UTC](https://forum.juce.com/t/where-to-put-initial-startup-parameter-values-for-aax/41600/18 "2020-09-11T10:22:52Z")

</div>

I think here is the answer!!

> [@AAX / ProTools - plugin states persistent over multiple sessions?](https://forum.juce.com/t/aax-protools-plugin-states-persistent-over-multiple-sessions/29977/20):
>
> Hey, thanks for the ideas - I actually wound up getting deeper into Pro Tools parameter saving/loading in this thread: Short answer - yes, when Pro Tools loads a session, it does its own recall (like automation, but not dependent on the parameters being armed for automation) of parameter values. It does this first, and then calls the setStateInformation method (passing it back whatever chunk of data, presumably some XML, that you might have given it from getStateInformation). So you have the…

Pro Tools is reacting differently when you have automateable parameters. Just tried the same gain demo with my `NonAutomatableAudioParameterFloat` class.

The Generic Editor won’t even show you the slider but you can have a look at the console. Problem is, the gain value still gets overwritten somewhere between `prepareToPlay()` and `processBlock()` …

```
#pragma once

class NonAutomatableAudioParameterFloat : public AudioParameterFloat {
    
public:
    
    NonAutomatableAudioParameterFloat(const String& parameterID,
                                    const String& parameterName,
                                    NormalisableRange<float> normalisableRange,
                                    float defaultValue,
                                    const String& parameterLabel = String(),
                                    Category parameterCategory = AudioProcessorParameter::genericParameter,
                                    std::function<String(float value, int maximumStringLength)> stringFromValue = nullptr,
                                    std::function<float(const String& text)> valueFromString = nullptr)
    : AudioParameterFloat(parameterID, parameterName, normalisableRange, defaultValue)
    {}
    
    NonAutomatableAudioParameterFloat(String parameterID,
                                      String parameterName,
                                      float minValue,
                                      float maxValue,
                                      float defaultValue)
    : AudioParameterFloat(parameterID, parameterName, minValue, maxValue, defaultValue)
    {}
    
    
    bool isAutomatable() const override {
        return false;
    }
    
};

//==============================================================================
class GainProcessor : public AudioProcessor
{
public:

    //==============================================================================
    GainProcessor()
        : AudioProcessor (BusesProperties().withInput ("Input", AudioChannelSet::stereo())
                                           .withOutput ("Output", AudioChannelSet::stereo()))
    {
        addParameter (gain = new NonAutomatableAudioParameterFloat ("gain", "Gain", 0.0f, 1.0f, 0.5f));
        
    }

    ~GainProcessor() {}

    //==============================================================================
    void prepareToPlay (double, int) override {
        float randomValue = Random::getSystemRandom().nextFloat();
        gain->setValueNotifyingHost(randomValue);
        DBG("PREPARE TO PLAY - Random Val: " << randomValue << " Gain Value: " << *gain);
    }
    void releaseResources() override {}

    void processBlock (AudioBuffer<float>& buffer, MidiBuffer&) override
    {
        DBG("PROCESSBLOCK - Gain: " << *gain);
        buffer.applyGain (*gain);
    }

    //==============================================================================
    AudioProcessorEditor* createEditor() override { return new GenericAudioProcessorEditor (*this); }
    bool hasEditor() const override { return true; }

    //==============================================================================
    const String getName() const override { return "Gain PlugIn"; }
    bool acceptsMidi() const override { return false; }
    bool producesMidi() const override { return false; }
    double getTailLengthSeconds() const override { return 0; }

    //==============================================================================
    int getNumPrograms() override { return 1; }
    int getCurrentProgram() override { return 0; }
    void setCurrentProgram (int) override {}
    const String getProgramName (int) override { return {}; }
    void changeProgramName (int, const String&) override {}

    //==============================================================================
    void getStateInformation (MemoryBlock& destData) override
    {
        DBG("GET STATE - Value: " << *gain);
        
        MemoryOutputStream (destData, true).writeFloat (*gain);
    }

    void setStateInformation (const void* data, int sizeInBytes) override
    {
        MemoryInputStream mis {data, static_cast<size_t>(sizeInBytes), true};
        float value = mis.readFloat();
        gain->setValueNotifyingHost(value);
        DBG("SET STATE - Value: " << value);
    }

    //==============================================================================
    bool isBusesLayoutSupported (const BusesLayout& layouts) const override
    {
        const auto& mainInLayout = layouts.getChannelSet (true, 0);
        const auto& mainOutLayout = layouts.getChannelSet (false, 0);

        return (mainInLayout == mainOutLayout && (! mainInLayout.isDisabled()));
    }

private:
    //==============================================================================
    NonAutomatableAudioParameterFloat* gain;

    //==============================================================================
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GainProcessor)
};

```

---

_[View the full topic](https://forum.juce.com/t/where-to-put-initial-startup-parameter-values-for-aax/41600)._
