Plugin not loading state in Reaper (noob questions part 2), but stand-alone

As a beginner, I am currently running into some serious problem when loading stored parameters:

One test plugin here uses the generic editor only and correctly loads its state using method setStateInformation. So far so good.

5

Now I made a second test plugin to see what kind of method is called in what situation using a normal (custom) editor. It looks like the state is not loaded, because setStateInformation is not called when reopening a Reaper session where the plugin is instantiated. I have no idea what prevents it to load. In the stand-alone version of this code, the state is correctly stored and loaded, but not in plugin mode.

PluginEditor.cpp (3.0 KB)
PluginEditor.h (956 Bytes)
PluginProcessor.cpp (2.5 KB)
PluginProcessor.h (2.6 KB)

The plugin has a counter as a state to be incremented each time the plugin is loaded (or started).
Also, I instantiate a parameterfloat and store it although it’s not used, just to avoid the case that no “official” parameter exists.

img1 is the plugin freshly opened, img2 is the plugin reopened in the same session. Destructor and Constructor are called. img3 is the Reaper session reopened: no call of setStateInformation. img4 is the stand-alone version which behaves correctly.

Does anyone have an idea what prevents the function to be called? Is it only called when there is some parameter linked to a slider? (attachment object actually exists). Those parameterfloats are only automatically shown when there is a generic editor. I dunno yet any way to make them visible in a custom editor, but that’s a different story.

Thanks




It looks like Reaper doesn’t bother calling get/setStateInformation if the parameter values haven’t actually changed. You are not changing the “dummy” parameter’s value anywhere in your code after you have constructed it. But if I change your prepareToPlay to the following, the setStateInformation call will happen

void JUCE_TESTAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
    n_prepare++;
    *dummy = 0.4;
}

Note that if you are attempting to do some kind of non-parameter state in your plugin, you may end up having to do this kind of thing anyway. There doesn’t seem to be a universally working solution to notify the host that non-parameter state has changed in the plugin.(*) You would have set the “dummy” parameter’s value to something else each time the non-parameter state has changed.

(*) The “official” solution that should work is to call the following in the audio processor when the non-parameter state has changed, but it doesn’t really always work

updateHostDisplay(juce::AudioProcessorListener::ChangeDetails().withNonParameterStateChanged(true));
2 Likes

Hi @xenakios ,

thanks a lot for your input!

Actually, the getstateinformation is called as shown before, only set… is not called. I checked your change (the explicit assignment of the dummy parameter to force a change) and for some reason, it doesn’t make a difference here. Maybe we have different Reaper versions. I will investigate further.

I made some example plugin. Also interesting that if I use new and delete, code will not pass Reaper plugin check, so I went with static storage for now.

EDIT:

I have to correct myself: I put it in prepareToPlay and now it’s working!!
100 thanks. I guess I had put it in the release function before.

1 Like

Hey there, thank you both for sharing your experience on this. I’ve been wrestling with this for a couple of days, purely with Reaper per the OP (Ableton Live 11 is completely fine).

In my experience just now, yes doing a dance in prepareToPlay just to dirty a parameter does seem to work - setStateInformation() does get called. Yay.

However I did also find that this updateHostDisplay also worked. @xenakios could share your thoughts behind saying “it doesn’t really always work” please? I’m trying to figure out what the gotchas might be.

Cheers!

You’d need to check it with every plugin format and host combination you want to support to be sure it really works in all those. The hosts are not really obligated to do anything in response to that updateHostDisplay call.

1 Like

I solved this issue back then, somehow.

Always use

xml->setAttribute

in getStateInformation

and stuff like

std::unique_ptr<juce::XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));

if ((xmlState.get() != nullptr) && (xmlState->hasTagName("PluginName")))
{
    for (int i = 0; i < NUM_PAR; i++)
        **par_vec[i] = (float)xmlState->getDoubleAttribute(par_tag_vec[i], par_def_vec[i]);
}
*bla = xmlState->getBoolAttribute("bla", false);

in setStateInformation

So basically, the xml-related functions, the others didn’t work.
Now it always works.

1 Like