#if JUCE_VST3_CAN_REPLACE_VST2 && ! JUCE_FORCE_USE_LEGACY_PARAM_IDS && ! JUCE_IGNORE_VST3_MISMATCHED_PARAMETER_ID_WARNING
...
#error You may have a conflict with parameter automation between VST2 and VST3 versions of your plugin. See the comment above for more details.
#endif
It appears to be regarding mismatched parameter IDs between VST2 and VST3 plugins when JUCE_VST3_CAN_REPLACE_VST2 is true.
The problem is: JUCE_VST3_CAN_REPLACE_VST2 is defined as 1 by default in juce_audio_plugin_client.h for any plugin which doesn’t explicitly define it (see here) but that definition is not included in juce_audio_plugin_client_VST3.cpp until after the earlier check (see here).
Thus, the intended compilation error doesn’t happen, and my plugin happily compiles with all JUCE_VST3_CAN_REPLACE_VST2 functionality, but apparently with some compatibility issue I need to be aware of?
So…
Can this block of code be moved later in the file, such that it does its intended job?
Where does this parameter compatibility issue manifest? Was it a problem before this commit by where it was added? What DAW / repro steps can I use to confirm correct functionality in my plugin?
The issue is also present in the GainPlugin demo compiled from the latest tip of develop, FYI.
I’m not at my computer right now to take a look but in answer to question 2. Yes it was a problem before the commit. The problem manifests with a session containing parameter automation. Create a session containing the VST2 plugin, add some parameter automation, save the session. Now install the VST3 (and possibly remove the VST2), open the session. You should see that the VST3 plugin opens fine but parameter automation doesn’t work as expected on playback.
Yep, looks like I can repro with a version of my plugin built on JUCE 7 and also with JUCE 8.0.6. I’ll take a look at implementing VST3ClientExtensions::getCompatibleParameterIds().
If I move that error block below all of the includes in juce_audio_plugin_client_VST3.cpp, it seems to work correctly and cause a compilation error.
Thanks for taking a look, maybe I moved things around while cleaning up and forgot to double check the error was still triggering. I did wonder if more people would be hitting this so maybe the reason I haven’t heard much is just that the check was in the wrong place .
Do let me know how you get on with getCompatibleParameterIds(), hopefully it’s easy enough for you to implement. Note that Cubase may be the only DAW that supports this feature right now, I believe I was testing with Cubase 13 at the time. That being said, I think I recall Reaper was already managing to be fairly smart, I’m not sure if it was maybe based on parameter order or parameter names possibly? Your experience may vary with other DAWs though.
Thanks for the additional info - I’ve given getCompatibleParameterIds() a try this afternoon and have run into a few things:
It is only called if I implement getCompatibleClasses(), despite the notes in the documentation indicating otherwise:
getCompatibleClasses()'s docs say it doesn’t need to be overridden if JUCE_VST3_CAN_REPLACE_VST2 is enabled.
getCompatibleParameterIds()'s docs say it may be called with compatibleClass being the identifier for the current plugin, but it will seemingly only be called with values listed in getCompatibleClasses().
Seems like either the VST3 wrapper code or the documentation need to be updated?
The function signature in the @code snippet in getCompatibleParameterIds()'s docs doesn’t match the actual function signature.
The getCompatibleParameterIds() documentation is a little confusing about what to use for the key. What seems to work for my case (going from a VST2 to VST3 where JUCE_VST3_CAN_REPLACE_VST2 is enabled in both) is using the parameter index as the key, but the documentation seems to imply I should use convertJuceParameterId() since it’s a JUCE VST3 plugin with JUCE_FORCE_LEGACY_PARAM_IDS disabled. I guess this is key is the parameter ID of the plugin that we are “replacing”? Maybe the documentation could clarify this a bit further?
Also just to confirm, there is no mechanism for going from VST3 to VST2 and keeping the mapping, correct? Just VST2 → VST3?
Thanks for all the feedback, I’ll chat with the team to see what improvements we can make.
The index is correct in your case. VST2 doesn’t have a concept of parameter IDs, parameters are always identified by the index. The docs are trying to also allow for a more general case where you might be migrating parameters from one VST3 plugin to another. We’ll likely review the wording to see if we can make clearer.
Correct I’m not aware of a way to go back in this instance. Although thinking about it again I guess you could release an updated VST3 version with JUCE_FORCE_USE_LEGACY_PARAM_IDS enabled and then implement getCompatibleParameterIds() to migrate from your existing parameter IDs, the session could be updated to this new version of VST3 and I think at that point it would be backwards compatible with VST2.
The problem with this approach unfortunately is that there will be lots of DAWs in which the new VST3 won’t be able to playback automation recorded using the existing VST3 plugin as I doubt all hosts support the parameter migration features just yet.
I guess it’s worth noting that if you didn’t have JUCE_FORCE_USE_LEGACY_PARAM_IDS enabled already then there is no compatibility in either direction. Our thinking was that not having parameter compatibility from VST2 → VST3 will become more of a problem as Cubase users move to Apple Silicon as VST2 is no longer supported in Cubase running natively on Apple Silicon. If those users need to share sessions with users using a VST2 version, probably the best option is to try and get those VST2 users upgraded to VST3.
I’ll chat with the team to see what improvements we can make.
Sounds good - my main request is either updating getCompatibleParameterIds() to work without needing to override getCompatibleClasses(), or at least updating the documentation to state you need to update the latter when implementing the former.
The index is correct in your case. VST2 doesn’t have a concept of parameter IDs, parameters are always identified by the index. The docs are trying to also allow for a more general case where you might be migrating parameters from one VST3 plugin to another. We’ll likely review the wording to see if we can make clearer.
Updating the wording would do the trick, IMO. Even knowing that VST2 doesn’t have parameter IDs, I was still scratching my head a bit.
Regarding VST3 → VST2 migration, it’s not really an issue IMO. The intent is to get users onto VST3.
Thanks for reporting these issues. We’ve now published some updates.
The parameter migration warning has been moved, as you suggested, so that all the relevant preprocessor defs are visible:
We’ve attempted to clarify the wording in the docs:
Finally, we now automatically include the VST2 plugin’s ID in the set of compatible IDs, which means that getCompatibleParamIDs() will be called without needing to manually override getCompatibleClasses().