What is required to receive output events from a plugin?

in a VST3 host, I can successfully load a sequencer plugin, which emits MIDI notes;
getBusInfo(MediaTypes::kEvent, BusDirections::kOutput, i, info) returns kResultOk; so output events should be produced by the plugin.
That bus is then activated by:
component->activateBus(MediaTypes::kEvent, BusDirections::kOutput, i /*index*/, true /*TBool state*/);

But always processData.outputEvents=0h is returned.
The plugin automatically emits notes, when loaded into another DAW.
Another test with using a chord-plugin, which also emits MIDI-notes gave the same result.
What could be wrong?

Thank you.

Which host are you using? Cubase should work for Note output.
It seems that the host you are using does not support note output…

Thank you for your answer.
I’m building my own VST3 host from the VST3 SDK. How do I implement Note Output? I did not find any examples within the SDK how to setup processData.outputEvents
within the “process” function of the host.
My host already can process separate-component plugins using the IComponentHandler interface. I can successfully send program change parameters to assign presets from my host. And I can send in vst events into a plugin from my host producing correct audio output in case of soft synths. Also parameter automation (input) is implemented and works great. There the parameter automation output also yet is not implemented, cause I yet also did not understand how to do that and for what I need that.
The processData.outputEvents I need for Sequencer/Chord plugins; Those plugins work fine for example in Cakewalk for Bandlab, but not in my own host. Cause processData.outputEvents is always NULL, although getBusInfo(MediaTypes::kEvent, BusDirections::kOutput, i, info) returns kResultOk, which indicates, that the plugin supports output events.
Thank you.

the host has to implement the outputEvents list implementation: check the example in the SDK:
public.sdk/source/vst/hosting/eventlist.cpp
which is a VST 3 event list implementation, you could use it for processData.outputEvents

Thank you for the answer.
public.sdk/source/vst/hosting/eventlist.cpp is already compiled as part of my project.
So how do I access it?
FUnknownPtr<IEventList> events(App_editController);
like this?
And where do I need to add it? Within the “process” function ?

you have to create it as member of your host class calling the process method:

class myHostPlugProcessorWrapper
{

Vst::EventList mEventList;
}

myHostPlugProcessorWrapper:: process ()
{
ProcessData data;
// data.inputs = …

data.outputEvents = &mEventList;

plugProcessor->process (data);

// if the plugin generates output events they should be in the mEventList
}

Thank you very much! The output events are now finally recognized.

How about the automation parameter outputs?
I used Vst::ParameterChanges mParameterChanges; from public.sdk/source/vst/hosting/parameterchanges.cpp
in my “myHostPlugProcessorWrapper” audio client class the same way you explained for the output events.
And it compiles correctly. Please tell me, in which situation a plugin would create such optional automation parameter outputs?
EDIT: I found an answer in this post
it; ok got it; so the processData.outputParameterChanges is for writing the automation parameters. And I found this examle .
So my host now always writes back all the outputParameterChanges (if any) back into the paramTransferrer.addChange by calling AudioClient::setParameter after audioClient->process returned.

I do not know what is your AudioClient, but note that

  • the PlugProcessor->process (may) happen in RealTime thread…
  • the host puts in a queue the parameter changes (returned in the process call)
  • in a UI Thread this queue is parsed and send the parameter change to the PlugController at the right time.

thank you for the advice;
my audio client simply runs on the same thread as the UI of the plugin; (each plugin has its own thread and so also its own audio client) ; the host is not using any external ports; it simply processes the inputs and outputs virtually within my host DLL/EXE module, without any ASIO or other access. The main UI of my app runs either in a different EXE process or at least in a different thread (if the host is loaded as DLL). Since I yet use the default implementation for parameter changes, I cannot use multi-threading yet, cause as you pointed out in this post that implementation is not thread-safe itself.