Sending midi CCs in VST3

Is it possible for a plug-in to output midi CC data in VST3?

Basically, this is not possible, because Control Change events are not directly passed to the plug-in. So, the plug-in cannot directly know if a Control Change event happened and which control has been modified. But there is a workaround: You can create 128 “hidden” parameters and override IMidiMapping::getMidiControllerAssignment(). There you can force the host to map each of the 128 MIDI controllers to a parameter. As soon as the host calls IEditController::setParamNormalized() you can override that callback function in order to react to a modification of a MIDI controller.

Hi Oli,
what’s your use case ?


bx_joscha - thanks, in this case I’m interested in outputting midi ccs - I took exactly the approach you describe for my plug-in VirtualCZ, with incoming CCs

Arne - Although I know it’s not ideal from a resolution perspective, sometimes people like to generate MIDI CC modulation for other devices, or make plug-ins that manipulate CC values. I’m actually doing this for a client (adding the functionality to IPlug). I know you have VST-MA, but that seems to have very little support. Being able to do the equivalent of “Audio Unit MIDI FX” with VST3 would be preferable.

Sorry, Oli, now I understand that you want the plugin to generate MIDI Control Change events and output them to the DAW. I guess this is completely impossible, isn’t it Steinberg? But this is an interesting question, indeed.

I think you can just make a parameter and change its value in the process method and the host should be able to use this as VC source. At least every modular host should be able to do this. You can also use the midi mapping interface to set a default midi CC value for that parameter. So a host is free to generate MIDI CC for external devices.


Hi @Arne_Scheffler ,

How is this supposed to work for output events when IMidiMapping explicitly states it’s for Input event busses?

class IMidiMapping: public FUnknown

	/** Gets an (preferred) associated ParamID for a given Input Event Bus index, channel and MIDI Controller.
	*	@param[in] busIndex - index of Input Event Bus
	*	@param[in] channel - channel of the bus
	*   @param[in] midiControllerNumber - see \ref ControllerNumbers for expected values (could be bigger than 127)
	*	@param[in] id - return the associated ParamID to the given midiControllerNumber
	virtual tresult PLUGIN_API getMidiControllerAssignment (int32 busIndex, int16 channel,
															CtrlNumber midiControllerNumber, ParamID& id/*out*/) = 0;

	static const FUID iid;

What do you mean exactly?

Hi @Arne_Scheffler,

Sorry if I wasn’t clear, perhaps I’m misunderstanding how this API works. What I’m trying to figure out is how a host is supposed to map parameters to outgoing (from the plugin) MIDI CC values.

The way I understand it is that the IMidiMaping interface provides a mapping between a MIDI Controller for an input bus and a parameter id. This lets the host map MIDI events on a particular input event bus to plugin parameters.

What about the other way though - mapping parameters to output event busses.

TL;DR: why does the getMidiControllerAssignment method have a busIndex but not a busDirection?


PS: To put this in context, I was recently contacted by Native Instruments because their plugin Kontakt can generate MIDI events in user defined scripts but CC events weren’t working in my host (Cantabile) with the VST 3 version of Kontakt. I can’t find any information on how such mapping is supposed to work.

eg: Kontakt comes with a built-in utility script “6 Controllers” that’s supposed to mimic MIDI CC controllers. VST 2 version of the plugin works fine. VST 3 version I can’t figure out how to map it.

since this topic came out 3 years ago, we have added the possibility for a plug-in to generate MIDI-CC Output events. See [3.6.12] Legacy MIDI CC Out Event - VST - Steinberg Developer Help

Ah ok, thanks. Figured I must have been missing something.