Plugin parameters not recalling correctly...Sometimes


#1

So when I load up a session in Reaper with my reverb plugin instantiated, it works perfectly. I have a recording of me snapping my fingers, and the reverb loads up and all of the settings work just fine.

However, when I have a virtual instrument (default Reaper ones) inserted on a track, and then my reverb inserted after that, my plugin doesn’t recall the parameters correctly. The GUI is all set to the same value, but the actual values need to be reset by moving the GUI sliders and such.

The thing is if my plugin is on a track by itself, the parameters all get recalled perfectly, no matter how I load it or try to break it. Even when inserted after an EQ on the same track my plugin will recall parameters just fine. It just seems to be virtual instruments, and for now Reaper’s default is the only ones I can try.

I’m wondering if anyone else experienced this or if I just don’t understand Reaper. I usually use Pro Tools or Sonar but I haven’t had them installed on my new machine.

Solved - Added Listener for tree parameters.


#2

Looks like a timing issue. The messages with the parameter changes maybe are delayed when other plugins or instruments are loaded too. I use listener classes that receives the parameter change notifications. I read and set the default values when i create that listener class and do this after i created the parameters with the default values. I had no issues so far this way.


#3

So how exactly would that look?
I create the listener with AudioProcessorValueTreeState::addParameterListener()
and then use .parameterChanged to set the values to whatever was set in the createandaddparameter in the treestate?

Could you give a small example by chance? I think I understand.


#4

I don’t have any code available at the moment. But you have to set the default values when you create the parameters. After that i read the default values in my listener class from the valueTree and set them directly in the constructor. Then i register the listener to get notified when a param changed. I hold floats for each parameter value in the listener class. This way i haven’t to access the value tree in the DSP code.


#5

I’m having some issues actually creating the listener.

I have this in my constructor:

//create and add parameters for automation(id,name,label,value range, default value, not sure, not sure).
treeState.createAndAddParameter("Dry/Wet Level", "Dry/Wet Level", "Dry/Wet Level", reverbSliderRange, 100.0f, nullptr, nullptr);
treeState.createAndAddParameter("Room Size", "Room Size", "Room Size", reverbSliderRange, 50.0f, nullptr, nullptr);
treeState.createAndAddParameter("Gain", "Gain", "Gain", gainRange, 0.0f, nullptr, nullptr);
treeState.createAndAddParameter("Damping Level", "Damping Level", "Damping Level", reverbSliderRange, 0.0f, nullptr, nullptr);
treeState.createAndAddParameter("Width Level", "Width Level", "Width Level", reverbSliderRange, 0.0f, nullptr, nullptr);
treeState.createAndAddParameter("Room Scale", "Room Scale", "Room Scale", roomScalerange, 0.0f, nullptr, nullptr,false,false,false);
treeState.createAndAddParameter("HF Cut", "HF Cut", "HF Cut", hfCutRange, 20000.0f, nullptr, nullptr);
//treeState.createAndAddParameter("Bypass Button", "Bypass Button", "Bypass Button", buttonRange, 0.0f, nullptr, nullptr);

//create parameters for xml storing and retrieval of user settings. Uses getStateInformation and setStateInformation functions.
treeState.state = ValueTree("savedParameters");

treeState.addParameterListener("Dry/Wet Level", treeStateListener);
}

What do I do with the listener from there?


#6

Any object can be a Listener by multiple inheritance. You inherit from the listener, so it will satisfy the addListener() argument:

class MyEditor : public AudioProcessorEditor, public AudioProcessorValueTreeState
{
// ...

    void parameterChanged (const String &parameterID, float newValue) override {
        // do something with the values
    }
};

myState.addParameterListener ("myParamID", myEditor);

or in the editor’s constructor it is even easier:

processor.state.addParameterListener ("myParamID", this);

HTH


#7

You’ve lost me. I understand the inheritance.

When you say to add that into the editor’s constructor, you mean the constructor in plugineditor.cpp? Because “this” doesn’t work there.

I thought I was supposed to add the parameter listeners in the plugin processor.cpp? And I have to create a listener like:

ScopedPointer<AudioProcessorValueTreeState::Listener> treeStateListener; //attachment for slider automation parameters.

Right?

I mean the main issue is that when other plugins, in this case any virtual instrument I’ve tried, are instantiated before my plugin, the GUI is updated with the proper parameters but the processor doesn’t get set with the right parameters. However it works perfectly when my reverb is on its own track or even using an EQ before the plugin. Even with 6 other plugins before my reverb my reverb is functioning fine, it just seems to be with virtual instruments.

I’ve tried Reaper’s default virtual instruments and play Goliath instruments.


#8

Sorry, I don’t know enough about, what you want to achieve.
But all listeners work the same, the object you want to receive callbacks have to inherit the listener class, in this case AudioProcessorValueTreeState::Listener.

Now this new object fits as argument to the state.addParameterListener() call, because it implements the callback.

And the last addition was to mention, that you can also register yourself as Listener, if you have a reference/pointer to the thing you are listening to in the constructor.

I am sorry, I was just answering your last question. But what your original problem is, I don’t know, as I don’t know enough about your project. There shouldn’t be any side effects of other plugins on that track…
Maybe double check your getStateInformation() implementation, if you are reading outside your data?


#9

Thanks so much for your help.

I can reproduce the error by having a virtual instrument send its signal to a track with my plugin on it too apparently, however it only happens with virtual instruments and not anything else.

My getStateInformation only consists of:

ScopedPointer <XmlElement> xml (treeState.state.createXml()); //creates Xml tree based on treeState.state
    copyXmlToBinary(*xml, destData); //Copies Xml element to memory block (*element,memblock)

#10

Sorry, my bad… the other one I meant, which restores the state from the MemoryBlock… :wink:


#11
ScopedPointer<XmlElement> xmlParameters(getXmlFromBinary(data, sizeInBytes));//sets parameters based on xml treeState.state
    
    //error checking
    
    //if xmlParameters is not empty
    if(xmlParameters != nullptr){
        //if xmlParameters has same tag name of treState.state
        if(xmlParameters->hasTagName(treeState.state.getType())){
            
            treeState.state=ValueTree::fromXml(*xmlParameters);//set treeState to xmlParameters
        }
    }

I’m downloading a trial of Ableton to see if I can reproduce the error in there, or if it’s some weird thing with Reaper as well.


#12

Ok, so this reads from the XML, but you have to propagate that new state to your controls I guess.

And double check using breakpoints, that your XML is actually valid, or add a logging if it failed at least (or for both cases)
Good luck!


#13

Okay so I don’t think it’s a problem with my plugin I think it’s an issue with Reaper. My plugin functions fine in every other DAW. It must be something strange happening in Reaper. I think I should head on over to their community to see what may be happening.


#14

The chance is very small that this is a reaper issue. I think reaper helps you in this case to find the source of the problem :slight_smile: It maybe also happens in other DAW’s on other systems or in combination with other plugins.


#15

Yeah I’m sure you’re right. I’m going to keep looking for a fix, however I’m unsure what else I can do for the moment.

Should I just find a work around? I guess my question is how can I make absolutely sure the parameters are set when loading? Where should I be setting my reverb parameters besides preparetoplay or the constructor?


#16

Note that parameterChanged() won’t be called for the initial default value, so perhaps you’re in a case where you have to call it manually to initialize your plugin state. cf :


#17

Debugging or output log information is the fastest solution in this case. You need to know what’s going on.
I would need more information about your implementation to give some tips. Maybe you have another look at the juce demo plugin. Make sure you create a class that listens to the parameters. You have to create that class in the constructor before loading a preset to be sure that you get all change events. Also make sure the state of the listener class (your parameter float values you use for processing) sets the default values in the constructor.


#18

I did some debugging and just tried to see what was being set. The sliders were, the reverb parameters were not for some reason in this case. They were being set to the default values.

As far as creating a class that listens, do you mean the AudioProcessorValueTreeState Listener? I then do addParameterListener(“Parameter ID”, listener) on all of my parameters right? And then I use this listener to set the state of the values in my treeState?


#19

Okay that actually seems to have worked. The state is being correctly loaded when instantiating my plugin after a virtual instrument in reaper, as well as any other time (that I know of).

So I created a listener and added the listener to each parameter before calling what was already in my constructor.

Thank you all so much!

For some reason this problem only occurs in .vst, but not AU or VST3.


#20

Great to hear that it worked. Such problems often happen randomly. Maybe it just does not happen on your system. You can be sure that every weak point in your plugin shows up as soon as you release the plugin :slight_smile: