Juce 4.2 broke VST3 over-shadows VST2 (Cubase)

Happy Holidays!
It seems that somewhere on the way something got broken for VST2/VST3 layouts.

Expected behavior:
Usually Cubase ONLY shows and uses the VST3 plug-in version when/if available.

Current regression behavior:
Cubase shows both.

They’re still interchangeable (no harm done). when VST2 unavailable it’ll load VST3 and vice-versa.

I’ve yet to throughly bisect/investigate this but I can reproduce it since 4.2.0 tag.
v4.1.0 doesn’t suffer from this issue.

I’ve tested:


Another observation,
Since monolithic plug-ins DOES exists (for Windows…) I’ve checked latest master (#1066a). and on Windows this is working as expected.
So this is a Mac issue*?

Friendly 2017 bump :wink:

So it seems that it got broken when switching to newer JUCE Shared Code.

Again this is a Mac issue.
I’ve also made sanity of Cubase with non-JUCE VST3/VST2 plug-ins. the expected behavior is VST3 will show while VST2 will hide (If Cubase consider them such).

Fun long commit to check:

So as it seems the switch to separated (non-polymorphic) plug-in build has the following bug:
Such logic:
#if JucePlugin_Build_VST3 && JUCE_VST3_CAN_REPLACE_VST2
(juce_VST_Wrapper.cpp) wouldn’t work as JucePlugin_Build_VST3 is explicitly set to 0 for VST!

This should be fixed asap. as any plug-in released since 4.2 would have this ugly behavior under Cubase.

1 Like

For other folks needing this fixed, we now have this problem fixed in the SR branch

Cheers, Yair

We’ll look into this…

This is now fixed on the develop branch.

1 Like

I am sorry, but the committed solution breaks some code of mine. I’ll explain:

What I need to do is forward a vendorSpecific() call received by my VST2 to the underlying AudioProcessor, which implements the proper response to it.

For that purpose, I asked a feature to be added a while back: Forward unhandled VST vendorSpecific() calls to AudioProcessor?)

Since nothing came out of that request, I have resorted to changing the JUCE code in a minimal way myself: added a virtual callback to AudioProcessor, and called it from the handleManufacturerSpecific() method that was part of the VST2 wrapper, instead of immediately returning 0 from it (this is described in my second post in the topic linked above).

Your fix has now delegated the handling of that opcode to a free function (handleManufacturerSpecificVST2Opcode()) that is completely outside of the wrapper.

While I understand your reason for doing so, this strips away that callback from its intended context, and it doesn’t even receive a pointer to the underlying AudioProcessor, which makes it completely impossible for me to call that virtual callback I added to AudioProcessor for my purpose.

Now, I’d like if you could solve this in one of the following ways (preferred way comes first):

  1. Provide a way for AudioProcessor to receive and respond vendorSpecific() calls that are not handled by the VST2 wrapper internally, which was my original request.
    After much fiddling I don’t think there is a good cross-format way to do that, so I think that adding a virtual callback to AudioProcessor like I did, possibly guarded by #ifdef JucePlugin_Build_VST2, is acceptable.

  2. Bring the handleManufacturerSpecific() method back into the wrapper, and call from there your free function handleManufacturerSpecificVST2Opcode(). This will at least allow me to rebase my code with minimal changes.

  3. Add to your free function an additional AudioProcessor& argument, that I can use to call my virtual callback.

See the other topic for a resolution.

1 Like