get/saveStateInformation is not recalling my parameters


#1

Hello!

I must be doing something obvious and simple wrong, but I’ve read the API regarding get/save state and looked through the forums and nothing has been able to solve my problem.

I am creating a distortion/delay plugin from some sample juce files I have found online. All of my parameters are communicating with the rest of my plugin correctly, yet when I close the gui window and reopen it, all of the parameters return to their default values EXCEPT for my feedbackD parameter which is functioning properly and recalling without a problem. I’m completely confused because my delayT, dryD, and wetD are setup exactly the same as my feedbackD parameter, but those parameters always recall to their default values.

I have been attempting to debug this problem for the past 3 days. My attempt to recreate this recall to default in the feedbackD parameter has not been successful. I’ve commented it out in every function that it is called in and I cannot simulate the same problem my other parameters are facing. I have also commented out my entire get/saveStateInformation functions and my feedbackD will still recall correctly. This just completely baffles me because I was under the impression that without those functions the host would not be able to recall the plugin to its former state.

Below are my state information functions in case anyone notices anything out of place. Also, here is a link to my source files (https://drive.google.com/folderview?id=0B0apODgduuOUeGFwdC1MTkpJSHc&usp=sharing)

Thanks in advance for any help you can provide this JUCE noob. If you need any additional information please let me know!

void TgcapstoneAudioProcessor::getStateInformation (MemoryBlock& destData)
{
// Outer XML element
XmlElement xml (“PLUGINSETTINGS”);

// add attributes to it
xml.setAttribute("delayOnOff", delayOnOff);
xml.setAttribute("delayT", delayT);
xml.setAttribute("dryD", dryD);
xml.setAttribute("wetD", wetD);
xml.setAttribute("feedbackD", feedbackD);

xml.setAttribute("distortionID", distortionID);
xml.setAttribute("gain", distortion);

copyXmlToBinary(xml, destData);

}

void TgcapstoneAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
ScopedPointer xmlState (getXmlFromBinary(data, sizeInBytes));

if (xmlState != 0)
{
    // make sure that it's actually our type of XML object
    if (xmlState->hasTagName("PLUGINSETTINGS"));
    {
        // pull out parameters
        delayOnOff = (bool)xmlState->getIntAttribute("delayOnOff", delayOnOff);
        delayT = (float)xmlState->getDoubleAttribute("delayT", delayT);
        dryD = (float)xmlState->getDoubleAttribute("dryD", dryD);
        wetD = (float)xmlState->getDoubleAttribute("wetD", wetD);
        feedbackD = (float)xmlState->getDoubleAttribute("feedbackD", feedbackD);
        
        distortionID = xmlState->getIntAttribute("distortionID", distortionID);
        distortion = (float)xmlState->getDoubleAttribute("gain", distortion);
    }
}

}


#2

Be aware, that getStateInformation are used by the host to read the plugins state when saving the project and setStateInformation when opening a project/session. Then the state is in your AudioProcessor (aka PluginProcessor). But it is your responsibility, when the editor is opened to transfer the actual values from the processor into the editor’s widgets.

Especially the methods you use getNumParameters etc. are or will become soon deprecated. If you are starting you should definitely use either subclasses of AudioProcessorParameter and create them with AudioProcessor::addParameter() or even better an AudioValueTreeState, see e.g. thread: How to use AudioProcessorValueTreeState's SliderAttachment?

You can either call setValue for each widget in the editor’s constructor, or you create an e.g. SliderAttachment, which will keep your slider in sync with a processor parameter. To use this use the AudioProcessorValueTreeState.

HTH


#3

Ah!! Thank you so much!

My problem was that I was using the setValue function in the editor’s constructor like you said. I assumed that it only called the constructor the first time you load up the plugin and after that if you closed the plugin and opened it back up it would call the get/setStateInfo functions. Obviously this wasn’t the case. I’ll be sure to look into the new methods, but for now I’m just glad that my plugin is functioning correctly.

I really appreciate the advice!


#4

BTW. there may be hosts, that don’t destroy the editor component when the window is closed to optimize speed at the cost of memory, so better don’t rely on the lifecycle of the editor.
I always check in the setStateInformation if the editor is instanciated ( AudioProcessor::getActiveEditor()) and propagate the loaded state to the editor. But that is not necessary if you use the *Attachment classes…