FL Studio 20 : VST 3 : getStateInformation called when plugin is being created

UPDATE Of course its a bug in our code, explanation at the bottom.

We’ve encountered an issue with our plugin on both Mac and Windows using FL Studio 20 and VST 3 where it is calling getStateInformation BEFORE setStateInformation when a plugin is being instantiated.
This means that any state we saved previously is lost, because this creation time getState is overwriting it with nothing.

Has anyone encountered anything similar? All other VST3 hosts appear to be acting normally and our state is saving / loading as expected.

From what I can see the getStateInformation call is coming directly from the VST 3 API in the juce VST 3 Wrapper :

tresult PLUGIN_API getState (IBStream* state) override
   if (state == nullptr)
       return kInvalidArgument;

    juce::MemoryBlock mem;
    getStateInformation (mem);

So I don’t think there is anything we can do lower down the chain to even stop this happening.

To verify I just created a new audio plugin from the projucer and only added DBG output to the getState / setState calls, then debugged it in FL Studio 20. First added instance to channel, saved project. When re-opening project in FL it outputs this

JUCE v5.4.1
Get State Information
Set State Information

Any ideas on the JUCE side? @ed95 @t0m @jules

Have I misunderstood something or do I need to pass this to Image Line?

To be perfectly sure, I would add a member Uuid and add it to the DBG statement.
I have a hunch, that it might call the getStateInformation on a different instance, for some kind of inquiry. That behaviour was observed on several hosts…
And after that print out the content of your setStateInformation, to see, if the contents are actually blank/default…

Thanks for the tip but there is no other instance, not of any plugin. This is happening with only one instance of either our actual plugin or with just one of the test plugin added to a blank project.

I wasn’t talking of instances you placed in the project, but of instances the host creates for inquiries and discards it right after, without the user ever seeing it. Hence the idea to have a Uuid to be able to distinguish debug output.
But you can also use a breakpoint in the getStateInformation and compare the memory address.

ah, right i get you. I don’t see any evidence of instances being spun up by the host as we’d see them in our logging, but i’ll double check anyway. thanks for the idea.

The AudioProcessor instance that it calls getState and setState on are the same one. Memory address is identical.

I can’t add anything substantive. As you’ve already discovered the getState and setState calls are coming straight from the host. Are other non-JUCE VST3 plug-ins behaving in the same way?

Just ran a test with U-He repro 5, Izotope Neutron, Softube Tube Delay and Surreal Machines Diffuse. They all recalled the state as I had left them. I made sure to make changes to all of them so they weren’t in default state.

I’m reading the VST3 docs and there is a page called VST 3 Workflow Diagram with the Audio Processor call sequence, which explicitly says that the call order is setState THEN getState.

How does the AudioPluginDemo cope? Have you checked that the setState is actually calling you with the information it retrieved in the previous getState? it could just be getting the default values on start up, before passing the correct information in setState.

Ok, we’re getting somewhere. The plugin demo handles state fine, even though the call order is still getState then setState.

For the demo plugin its not passing back the state from getState, but the one its supposed to restore.

So there must be a bug in our code somewhere. I’m guessing because we’re not expecting them to be called in that order something is getting messed up.

Thanks for the idea. Back to the debugger :slight_smile:

1 Like

So the different execution order of FL Studio for VST 3 exposed a bug in our code.

FL VST3 does getState -> createEditor -> setState which put our internal state into a weird position as the code assumed that a setState would be called before the createEditor, after all no need to have an editor to restore state. So the setState that followed immediately wasn’t handled properly.

Thanks everyone for you input and advice. Glad to get to the bottom of it.