I've received reports from customers and confirmed them here. In Cubase and Nueundo, there's a little bypass button in the GUI wrapper. This button appears in VST 2.4 but doesn't show up in VST3. I've spent a frustrating day in VST3 documentation and in the Juce wrapper trying to figure it out. But no luck. There doesn't seem to be an equivalent in VST3 to the CanDo interface in VST2.4, but there must be something. But I'm going down blind alleyways trying to figure out what to do.
Iirc, when I implemented the VST3 client and hosting stuff, there was a parameter that was optional to add for bypassing. It was a bit awkward, because JUCE allows the flexibility to set/get your plugins parameters by index - and we would need to reserve one for bypassing (which the only plugin formats don't support, I think... can't remember). Setting an index that a user-programmer can't use could make for a headache to work around - though I guess an integer value for parameter index that's "std::numeric_limits<int>::max() - 1" could do it.
I've spent some time the VST3 SDK documentation and also going through the VST3 wrapper. In the old VST2.4 stuff, the bypass business appears to have been taken care of with the CanDo call. I can't find any sort of equivalant in VST3, and the word bypass doesn't even appear in the VST3 docs. From the best I can tell (and I don't feel really confident about this), an extra parameter is needed in VST3 to handle bypass. This would seem to break the otherwise smooth ability to take a session back and forth between VST2 and VST3. For that reason, I think I'm probably missing something.
Well.. I can't add it like that, but I can add another virtual method to the AudioProcessorParameter class, which is the new way that all this stuff works. Seems like a sensible plan!
That's too implicit, and doesn't deal with translations (what if you want to display the parameter name? you would have to hack your code to workaround/check and see if the name is/contains bypass to be able to translate it later...)
In a plug with a dedicated bypass control, I've indicated to VST3 which on/off control is the bypass by setting info.flags for that control in juce_VST3_Wrapper.cpp, at the end of Param struct constructor:
info.flags |= Vst::ParameterInfo::kIsBypass;
And now in Cubase 7 the bypass button appears in the VST3 plug-in header and toggles along with the UI... hooray!
But on session restore, the bypass button in the header is always off, even though the UI control restores state properly.
which I overrode that method in my plugin's parameter class, derived from AudioProcessorParameter.
// return true if this is the bypass parameter
bool MyAudioParameter::isBypass() const
{
return (getParameterIndex() == PARAM_BYPASS);
}
I have verified that the kIsBypass bit gets set only on the paramater I have reserved. The little bypass button now appears in the frame and I can toggle it off and on, and I can even control it via automation. However, there are still a couple of issues. First is that the VST3 wrapper doesn't check the flag, so it still calls processBlock instead of processBlockBypassed regardless of the bypass state. I can work around that by implementing my own bypass but it should really be taken care of automatically by the framework so I don't need to code a special case just for VST3. Second is that although MyAudioProcessor::setStateInformation correctly restores the bypass parameter on session restore, it also saves and restores the bypass state when saving and restoring presets. So if I save a preset with the bypass on, it will engage the bypass whenever I load the preset. This is because setStateInformation is used both for session restore and loading presets and I can't figure out if there is a way to distinguish one from the other in the code.
I'm interested in this solution. Have you found that sessions saved with this VST3 tweak will load and run properly when only VST2.4 is available (and vice versa)?
I would love to see someone figure out how to prevent the bypass state from being save/loaded in the presets. This is the only thing preventing me from releasing my plugin in VST3 right now.
"I only create a bypass parameter if running in VST3 mode so it should have no effect on VST and vice versa."
I think it actually might matter. If people take sessions back and forth between systems that have VST3 plugs and VST2.4 plugs, you need the sessions to be compatible in both directions. I have a few Pro Tools customers who do similar things, taking sessions back and forth between AAX and RTAS machines. There are no compatibility problems there.
It's easy enough to argue that once you go to VST3, you should never go back. But that's not what people do. If there turned out to be an unrelated issue in a VST3 version of a plug, you're basically telling the user to scrap any work he'd done with the plug. That user would be justifiably angry. You'd also be telling the user that any sessions created with VST2.4 plugs wouldn't quite port to VST3. That's really tough if he's got to revisit work that was completed a year or two earlier.
Isn't this all just theoretical anyway, since JUCE doesn't currently support VST3 bypass? I have implemented a workaround but there are still issues, like session restore vs preset and the fact that "processBlockBypassed" is not called in the VST3 wrapper. I currently plan on doing my first release in VST2 only because of this and also the lack of sidechain support.
Once VST3 is fully implemented in JUCE, it's unclear to me what will happen if I create a bypass parameter in VST2 mode, since bypass is implemented differently in VST2 and I still don't know how JUCE is going to handle this.