Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changing a NonAutomatedParameter will not mark the plugin state as dirty #33

Closed
rsjbailey opened this issue Jan 15, 2021 · 8 comments · Fixed by #67
Closed

Changing a NonAutomatedParameter will not mark the plugin state as dirty #33

rsjbailey opened this issue Jan 15, 2021 · 8 comments · Fixed by #67
Labels
bug Something isn't working

Comments

@rsjbailey
Copy link
Contributor

If e.g. the routing is changed in a just saved project and the project is then closed, REAPER will not ask the user if the project changes should be saved.

From gitlab issue 121

@rsjbailey rsjbailey added the bug Something isn't working label Jan 15, 2021
@ial-sebastian
Copy link
Collaborator

This seems to be just the (bad) default behaviour of non automated parameters and requires a workaround. Unfortunately there doesn't seem to be a way to actively mark the plugin's state as dirty from the processor. Some JUCE forum posts also indicate this. A potential workaround would be to re-set the current value of one of the automated parameters. This works with the objectVST, but in the DirectSpeakersVST there are no automated parameters. So this would require adding an additional dummy (e.g. custom bypass) parameter. From the host's / user's view this shouldn't change anything, since the Bypass parameter is always added by default (you just don't have access to it if you don't provide your own). Still this feels a bit convoluted - do you think it would be acceptable?

@chrispike-bbc
Copy link
Collaborator

Hi Sebastian. I chatted to Matt about this. Is there a risk that adding the custom bypass parameter would break an existing project built before this new parameter was added? That seems the main risk.
Besides that, in our opinion, this would be an acceptable solution despite not being as neat. Thanks!

@ial-sebastian
Copy link
Collaborator

Hi Chris, I did some investigation and it doesn't seem to be an issue, at least not in Reaper.
Reaper adds its own additional bypass parameter (and also a "wet" parameter).
This is the one that is connected to all the visible host bypass controls.
The mandatory VST3 bypass automatically added by JUCE is only accessible by the user through the generic VST controls and the automation envelopes. Usually nobody will touch this. My plan is to replace this one with a custom one, naming it also "Bypass" and adding it after all the others, which should eventually create the exact same parameter list as before.
If the parameter is set to true, Reaper will not call processBlock() anymore, but processBlockBypassed(), which is implemented in the base class and does nothing. This doesn't change, if the custom bypass parameter is added. But to avoid issues in other hosts, we should still check for the bypass value in processBlock().
But i am not sure if there are hosts which identify the parameters by index rather than its name, which could of course lead to issues. In Cubase for example, the added custom bypass will then be the one exposed in all the host controls (mixer..). I could do some tests with Cubase/Logic, or is the support of hosts other than Reaper not important?

@chrispike-bbc
Copy link
Collaborator

Thanks for investigating. Reaper is our primary DAW, especially since the ADM I/O extension is only for Reaper. I also don't expect much use in other DAWs right now, so breaking changes are less of an issue in Cubase/Logic etc. When you say that identifying parameters by index "could of course lead to issues", do you mean issues beyond old projects no longer working?

@ial-sebastian
Copy link
Collaborator

No, i think breaking old projects would be the only potential problem, e.g. because a wrong order of the parameter list could be assumed by the host.

@chrispike-bbc
Copy link
Collaborator

Ok great. In that case I think we should proceed.

@ial-sebastian
Copy link
Collaborator

        bool vst3WrapperProvidedBypassParam = false;
        auto* bypassParameter = audioProcessor->getBypassParameter();

        if (bypassParameter == nullptr)
        {
            vst3WrapperProvidedBypassParam = true;
            ownedBypassParameter.reset (new AudioParameterBool ("byps", "Bypass", false, {}, {}, {}));
            bypassParameter = ownedBypassParameter.get();
        }

        // if the bypass parameter is not part of the exported parameters that the plug-in supports
        // then add it to the end of the list as VST3 requires the bypass parameter to be exported!
        bypassIsRegularParameter = isBypassPartOfRegularParemeters();

        if (! bypassIsRegularParameter)
            juceParameters.params.add (bypassParameter);

        int i = 0;
        for (auto* juceParam : juceParameters.params)
        {
            bool isBypassParameter = (juceParam == bypassParameter);

            Vst::ParamID vstParamID = forceLegacyParamIDs ? static_cast<Vst::ParamID> (i++)
                                                          : generateVSTParamIDForParam (juceParam);

            if (isBypassParameter)
            {
                // we need to remain backward compatible with the old bypass id
                if (vst3WrapperProvidedBypassParam)
                    vstParamID = static_cast<Vst::ParamID> ((isUsingManagedParameters() && ! forceLegacyParamIDs) ? paramBypass : numParameters);

                bypassParamID = vstParamID;
            }

            vstParamIDs.add (vstParamID);
            paramMap.set (static_cast<int32> (vstParamID), juceParam);
        }

Looking at the JUCE wrapper code, first there is a check if a custom bypass is provided, and if not, one is added at the end of the list. So if we provide one with the same name at the end of the list, at this point in the code there will be no difference to the state before. The ID handling for legacy parameters is done after that, essentially working on the exact same parameter list as before. I'll proceed implementing this.

@chrispike-bbc
Copy link
Collaborator

Great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants