VstHostCallback() a class function or flat or both?

For a test, with the current JUCE 6.x, I did a VST2 plugin that calls VstHostCallback().

In fact I use a variable “hostcb” of type std::function (VstHostCallbackType) && which is set in the function handleVstHostCallbackAvailable (std::function (VstHostCallbackType) && callback) that I override from JUCE. (I needed to write “(” instead of “<” here to avoid bad formatting…)

std::function(VstHostCallbackType) denotes a function of five parameters defined in “juce_VSTCllbachHandler.h” and in the documentation:
typedef pointer_sized_int (VstHostCallbackType) (int32 opcode, int32 index, pointer_sized_int value, void* ptr, float opt);

Appropriately, I call it with these five parameters (the meaning of those don’t matter here) such as:

result = hostcb(0xdeadbeef, 0xdeadf00d, 0, (void* ) funcname, 0.0);

and it works just fine when running the VST in a host.

Now I found two older source code snippets for JUCE 5.x or earlier and here that function is called with six parameters:

var cbvar = getProperties()[“audioMasterCallback”];
hostcb = (VstHostCallback)(int64)cbvar;
result = hostcb(NULL, 0xdeadbeef, 0xdeadf00d, 0, (void*)funcname, 0.0);

and in another location:

var aevar = getProperties()[“aeffect”];
ae = (VstEffectInterface*)(int64)aevar;
result = hostcb(ae, 0xDEADBEEF, 0xDEADF00E, 2, 0, 0.0);

Now I seem to suppose that “ae” (i.e. “aeffect”) might be a pointer to the instance of “this” effect plugin, hence the “this”-pointer of the instance of the JUCE “AudioProcessor” class.

Hence the first parameter in the (“flat”) six parameter version might be the “this” pointer that is automatically added by the compiler in for the class function, anyway, and the VST-host will see the same in both variants.

Is this assumption right and my code will work as expected ?

Did JUCE at some point in time update to have VstHostCallback() be a class function instead of flat ?

Thanks for any pointers,
-Michael

That old code looks like something I implemented at some point. It required changing the Juce internal code. (In order to get access to the internal VST2 pointers.) It is obsolete now. The new way to handle the VST callback internally deals with the needed pointers.

In the VST wrapper, handleVstHostCallbackAvailable is used like this:

callbackHandler->handleVstHostCallbackAvailable ([audioMaster, aEffect] (int32 opcode,
                                                                         int32 index,
                                                                         pointer_sized_int value,
                                                                         void* ptr,
                                                                         float opt)
{
    return audioMaster (aEffect, opcode, index, value, ptr, opt);
});

The host callback function and aeffect instance are automatically captured and used. In an implementation of handleVstHostCallbackAvailable, you don’t need to worry about passing the aeffect pointer - you can just call the callback parameter with the other five arguments.

I haven’t checked too carefully, but it looks like handleVstHostCallbackAvailable has always taken a 5-argument function as an argument. I also couldn’t see anywhere in JUCE’s history where the aeffect/audioMasterCallback pointers were stored in the properties of a component. I suspect that the example you’ve found is very old, or it is using a modified version of JUCE.

The code looks like the one I did at some point, I added a getProperties method and an internal NamedValueSet or equivalent to AudioProcessor.

That old code looks like something I implemented at some point.

One of the two snippets I found sees to be yours, another one was hinted to me, by the guy who does the (great) “ReaLearn” Plugin, which also attaches to the Reaper API but is not done in C++, nor uses JUCE.

OK, from your comment I understand what “getProperties” is all about.

Anyway, the other snippet seems to use just what the VST API provides , and uses the six parameter version, nonetheless.

-Michael

In an implementation of handleVstHostCallbackAvailable , you don’t need to worry about passing the aeffect pointer - you can just call the callback parameter with the other five arguments.

That is great.
Int never passes NULL, but supposedly that is not a problem.

(As this is my first decent project done in C++, I am amazed what this code can do…)
-Michael

Great to see that the encapsulation for the VST API is this nicely done ! Thanks to the JUCE Team.

Now it would be very desirable if VST3 would be supported in a compatible way, allowing for unmodified user code,.

I’d be happy to decently beta-test this with Reaper. Of course other VST-Hosts would need to be checked, as well.
-Michael

The host callback function and aeffect instance are automatically captured and used…

Unfortunately. This does not seem to work for me.
I did

ReaProject * ReaperGuiembed_testAudioProcessor::getReaperProject()
{
return (ReaProject*)hostcb( 0xDEADBEEF, 0xDEADF00E, 3, 0, 0.0);
}

Regarding the appropriatre Reaper docs
REAPER | Extensions to VST SDKHost Context
this should return a pointer to the Reaper project class.

but I get NULL.

Same with "retrieve channel count " and “MediaTrack”. (I did not check “MediaItem_Take” as I did not use this VST as a take effect).

Thanks for any help…-
-Michael

Are you doing that from a VST2 plugin? (For the millionth time : none of this stuff works with VST3 plugins and Juce at the moment.)

Update:

I tried different places for doing this:

  1. in the constructor of the AudioProcessor class → Plugin can’t be loaded.
  2. in handleVstHostCallbackAvailable → setting up the Reaper API works, but getting the track parameters, I always get zero (described in detail below)
  3. in a timer callback → seems to work !
    getReaperTrack → seemingly a pointer to the track the VST is loaded in. I can get the ssame pointer via the API using the track number.
    mediaItem_Take → Zero (seems correct)
    reaperProject → the pointer to the project I also can get by numProjects(0,0,0).
    getReaperTrackChannelCount → something looking like a pointer. using this as a pointer, I get 0 (64 bits). Need to check what I am doing wrong. I can get the correct count by GetMediaTrackInfo_Value()

What is the correct place in the initialization to get the “Reaper Project” ?

Thanks !!!
-Michael

===========================================================

Of course I do this only with a VST2 for now !!!

The code I debug is:

int errcnt = REAPERAPI_LoadAPI(getfuncaddr);  // get API -> works
ShowConsoleMsg("hallo");                                    //  works

MediaTrack *     mediaTrack     = getReaperTrack();                     //  mediaTrack -> 0
MediaItem_Take * mediaItem_Take = getReaperTake();              // mediaItem_Take -> 0
ReaProject *     reaperProject  = getReaperProject();                    // reaperProject -> 0
int    reaperTrackChannelCount = getReaperTrackChannelCount();  // reaperTrackChannelCount -> 0

the “get” functions called are using the scheme (only dffering in the type conversion)

MediaTrack * ReaperGuiembed_testAudioProcessor::getReaperTrack()
{
return (MediaTrack*)hostcb(0xDEADBEEF, 0xDEADF00E, 1, 0, 0.0);
}

This is done in the initialization of the AudioProcessor. Maybe that is not the

-Michael