How the plugin can tell to the host the project state became dirty?

The hosts are not registering a change inside the plugin as a change in the projects if it’s not based on a parameter change (how would they, obviously). So if you make any changes to your patch that would be saved with the project but not exposed with a parameter to the host, then the host will show the project as saved and that can be misleading for the user, thinking their project is saved. Live even greys out the “Save” option in the file menu, so you have to use “Save as” to overwrite the file with the latest changes. Is there a best practice how to handle this situation, when you want to tell to the host, it should mark the project modified because something was changed inside the plugin?

I hoped maybe the AudioProcessor::updateHostDisplay() function can help with this (despite its GUI related name), but it seems it doesn’t help in Live.

hmm that’s strange, in my version of live I’m running, I always have the option to save the session. I guess the only thing would be to perhaps call setValueNotifyingHost() on a parameter with it’s current value in the condition which is causing you the problem : /

Not a great solution but not sure I can think of anything else. You could perhaps create a dummy parameter you use specifically for this?

1 Like

Hey Jake, what Live are you using? On 10.1 if I load up any project the Save functionality is disabled until I make a change (like tweaking a parameter knob in any plugin or change the mixer, etc)…

And yes to use a dummy parameter or resetting a non-dummy one can be a solution but that just sounds too bad. (Also I didn’t check but if I set an existing parameter to the exact same value, maybe the host won’t recognize it as a change and won’t make the project dirty. So I thought maybe I’ll need to change it then change back for proper notification. This thought discouraged me even to try it as it sounds so bad I thought better to ask here maybe someone has a proper solution :slight_smile:

Ahh yes, so I’m on 10.1 as well. I had a bunch of plugins in my default template. I removed them all, and I’m seeing the same issue as yourself in my plugins as well : /

Never noticed before! please share if you find a not disgusting solution! lol

1 Like

The same things happens with AAX plugins on Pro Tools. So far my solution was to add a dummy parameter. Note that on Pro Tools, changing a parameter to a value, and then setting it back to its original value was not enough as Pro Tools was smart enough to see that the value was back to its saved state.

1 Like

So I did a bit more digging on this, and for VST3 plugins, you have the EditController::setDirty() method (https://sdk.steinberg.net/viewtopic.php?f=4&t=313), that can be used to do just that.

I’ll have a look to see if there is something equivalent for AAX.
Question for the Juce team, how can I invoke VST3 methods from my AudioPluginProcessor instance ??

2 Likes

So do we have anything other than using a dummy parameter to notify host about internal parameter changes?

4 Likes

Bump! Still no solution to this?

We modified our AAX wrapper to include this:

		AAX_Result GetNumberOfChanges (int32_t * oNumChanges )  const override
		{
			*oNumChanges = pluginInstance->getNumAAXChanges();
			return AAX_SUCCESS;
		}

Then, we added the function getNumAAXChanges() to juce_AudioProcessor.h, returning a counter that we bump up every time parameterChanged() is called in the processor, and any other time we want to notify the host of a state change.

Ok, that’s nice, thanks for sharing!
I was wondering if anyone from JUCE is working on a solution which is not dependent on the plugin format and works without forking our own JUCE version. I’ve avoided this so far and an issue like this shouldn’t be the reason to start this I guess.

1 Like

Bump again, is there really no way to do this without forking JUCE?

1 Like

Could one not use the dummy parameter, and set a random valuem or add 0.01f each time wrapping at 1.f?

It’s still a fudge, but it would override any ‘intelligence’ on the host side, and should work across all formats. Create your own function ::NotifyHostOfChange() and call that as needed…

Hey JUCE team! This has just come up for us too.

Can I suggest you add another type to updateHostDisplay(…) called nonParameterDataChanged and it for the VST3 SDK calls setDirty etc. etc.

Now you’ve added a parameter to updateHostDisplay this seems like an excellent and easy improvement.

3 Likes

Hi,
we are running into the same issue.
Therefore I wonder:

Does anyone have a comprehensive list of hosts, where updatHostDisplay() works vs where we have to fall back to the dummy parameter?

I can’t provide you with a list but we are using the dummy parameter solution successfully everywhere because it just works. A list needs to be updated when hosts are updated and I just didn’t want to think about this anymore :grinning_face_with_smiling_eyes:

Yes, we are currently using the “dummy parameter” solution.
Unfortunately our testers complained that it looks ugly. Therefore I was hoping for a better solution. At least for those DAWs, which JUCE supports it for.

Unless they show the automation track they can’t see it, you don’t need to show it on the GUI to make this work :wink:

Yeah, I don’t show it in the UI. Unfortunately our testers did check their automation tracks. They were like: “What is this strange extra automation lane I see in my DAW?”

I have done a few tests so far with the DAWs I have access to. Here is my result (for anyone interested):

These DAWs work fine with updateHostDisplay:

  • Logic X
  • GarageBand
  • Cubase 8 (VST2)
  • Studio One 5 (VST2)

These DAWs need the “dummy parameter” workaround:

  • Ableton Live 11. NOTE: even with the workaround, it does not work 100% correctly.
  • Cubase 8 (VST3)
  • Studio One 5 (VST3)
  • FL Studio
  • Reaper

you can set the parameter to be non automatable (cf AudioProcessorParameter::isAutomatable()) so that it doesnt appear into this list.

NOTE: even with the workaround, it does not work 100% correctly.

calling beginParamChange end endParamChange before and after changing the param value may fix that

1 Like

Hi Lalala,

thanks for your ideas.

That does indeed work. Thanks! Ableton now directly picks up the change.

Interesting. So… seems this parameter is implemented differently in the hosts. For Reaper it works fine in VST2. But in VST3 it results in the host no longer realising it is dirty.
In Ableton Live 11, it does nothing for VST2. But for VST3 it works well.
So I guess this means even more testing! :rofl: