Implementing VST Extensions


#1

Taking a look through JUCE’s VST wrapper there seem to be a couple extensions handled by JUCE. Since extensions are non-standard it wouldn’t make much sense to try and start supporting them all out-of-the-box from JUCE.

It appears we do have the VSTCallbackHandler class available for handling specific vendor extensions. Would it be possible to extend it to also allow custom “pluginCanDo” returns as well?

struct VSTCallbackHandler
{
    virtual ~VSTCallbackHandler() {}

    virtual pointer_sized_int handleCanPluginDo (int32 index,  
                                                 pointer_sized_int value, 
                                                 void* ptr, 
                                                 float opt) = 0;

/** This is called by the VST plug-in wrapper when it receives unhandled
        vendor specific calls from the host.
    */
    virtual pointer_sized_int handleVstManufacturerSpecific (int32 index,
                                                             pointer_sized_int value,
                                                             void* ptr,
                                                             float opt) = 0;
};

and in juce_audio_plugin_client/VST/juce_VSTWrapper.cpp:

pointer_sized_int handleCanPlugInDo (VstOpCodeArguments args)
{

    ...

    if (matches ("hasCockosExtensions"))
            return (int32) 0xbeef0000;

    // similar to what dispatches handleManufacturerSpecific()
    if (auto callbackHandler = dynamic_cast<VSTCallbackHandler*> (processor))
        return callbackHandler->handleCanPluginDo (args.index, args.value, args.ptr, args.opt);

    return 0;
}

#2

Yes, would be useful for NKS


#3

#4

Awesome, thanks @t0m! :slight_smile:


#5

Hi!
The callback handler appears to be a good solution for vendor specific vst host->plugin requests, so this is covered.
At the moment I’m trying to find an elegant solution for going the other way round, and send vendor specific data from my plugin to the vst host. So far I haven’t found a solution for that which doesn’t involve changing the JUCE code. I basically need access to the VstHostCallback object that is given to the plugin right at the vst plugin entry point. Apparently AudioProcessor is completely detached from the wrapper.
I need to a) get canDo information from the host and b) send arbitrary vendor specific data to the host.

Maybe I am overlooking something? Is modifying the JUCE code the only solution at the moment?

Thanks!


#6

Unfortunately that appears to be the case. (I have had to do that in order to be able to use the Cockos Reaper extension API from VST plugins.)


#7

Can you recommend a way of doing this with the least possible amount of maintenance pain? :wink:


#8

Unfortunately not really. :disappointed:


#9

Thanks! I’ll figure something out. Since this might be an issue affecting several users at the moment, maybe the JUCE devs can figure something out for the future. :slight_smile:


#10

I’m interested in a solution too since i also want to add NKS support…


#11

Would it be possible to add NKS support if the host callback was supplied to the plug-in after the plug-in’s constructor was called? I’m not familiar with what needs to be done.

I could add another callback along the lines of

void hostCallbackAvailable (VSTHostCallbackPtrType hostCallback) = 0

which would be called immediately after the constructor finishes.


#12

That would cover only VST2 though, right?


#13

Correct.

What’s needed from the other SDKs?


#14

In VST3, I have needed the FUnknown* hostContext pointer passed for the JuceVST3Component::initialize method. (That’s for using the Reaper API, I don’t know if that would be useful for NKS etc.)


#15

I’ve made VST3 Extension as an example:

VST3 uses some Steinberg COM-ish way.
It seems currently there isn’t an elegant way to implement specific format features without modifications.


#16

Hello!

I’m using JUCE 5.2.1 and I have cherry-picked the commit

Added a “plug-in can do” callback to the VSTCallbackHandler interface

so I can handle vendor specific vst host->plugin “can do” callbacks.

I have implemented (override) the virtual methods of the VSTCallbackHandler ( handleVstPluginCanDo and handleVstManufacturerSpecific ) as public methods of my PluginProcessor.

When the handleCanPlugInDo method of the JuceVSTWrapper class receives unhandled plug-in “can do” calls from the host, the

auto callbackHandler = dynamic_cast<VSTCallbackHandler*> (processor)

returns a NULL pointer, so the

if (auto callbackHandler = dynamic_cast<VSTCallbackHandler*> (processor)) return callbackHandler->handleVstPluginCanDo (args.index, args.value, args.ptr, args.opt);

doesn’t call the handleVstPluginCanDo method.

Any idea why? Maybe I’ve missed some other commits after the tag 5.2.1 that I need to cherry pick before the Added a "plug-in can do" callback to the VSTCallbackHandler interface commit?

Thanks!


#17

Hello!

I found the problem! My code was:

PluginProcessor.h:
Inheriting from VSTCallbackHandler:
class MyAudioProcessor : public AudioProcessor, VSTCallbackHandler

and it needs to be:

PluginProcessor.h:
Inheriting from VSTCallbackHandler:
class MyAudioProcessor : public AudioProcessor, public VSTCallbackHandler


#18

I’ve enabled access to the host callback for VST2:


#19

That is awesome! When get we expect a new JUCE release? It has been a while now and a few things like this in the official release would be VERY welcome.


#20

We’ve not got anything scheduled for the near future. There’s a significant HiDPI scaling improvement coming soon that we want to give a good long run on the develop branch before the next release.