I am implementing a feature in a VST3 plug-in that changes the latency of the processing. According to the IAudioProcessor documentation, I need to call IComponentHandler::restartComponent(kLatencyChanged). But I don’t see any way to access an IComponentHandler from my Processor component, only from the Controller component. Does that mean I have to pass that information to my Controller component (via a parameter change or a message), and then let the Controller tell the host? Or is there some way to get an IComponentHandler pointer from within the Processor component itself?
The controller has to call restartComponent(kLatencyChanged), you can send a message from the processor to the controller.
1- processor → send to controller a message
2- Controller gets the message → controller call restartComponent(kLatencyChanged)
3- host will call processor->setActive (false)
4- host will ask the new latency: processor->getLatencySamples ()
5- host will call processor->setActive (true) (the next process call should handle this new latency)
be sure that your plugin does not change too often its latency , the host has to recompute the processing graph for delay compensation, which lead to audio drop.
Hello! I have some follow-up questions to this post.
-
How does one get a message to the controller?
-
Does this mean we need to override processor->getLatencySamples() to return the amount of latency that we now wish to be induced?
-
Do we then, manually induce latency, or is this going to be the new size of the buffer passed to us when processor->process() is called? Would overriding processor->CanProcessSampleSize() affect this in any way?
-
If we are meant to manually induce latency, this means we will have to construct our own buffers and feed the buffers passed to us from PlugProcessor::process(Vst::ProcessData& data) into these new buffers?
Thank you!
- How does one get a message to the controller?
Read 3rd-Party Developers Support & SDKs | Steinberg
Does this mean we need to override processor->getLatencySamples() to return the amount of latency that we now wish to be induced?
Yes
- Do we then, manually induce latency, or is this going to be the new size of the buffer passed to us when processor->process() is called? Would overriding processor->CanProcessSampleSize() affect this in any way?
Yes, you induce the latency in your processor, the host will give you the same buffers as before.
- If we are meant to manually induce latency, this means we will have to construct our own buffers and feed the buffers passed to us from PlugProcessor::process(Vst::ProcessData& data) into these new buffers?
Correct.
You can have a look at the helper implementation of bypass:
public.sdk/source/vst/vstbypassprocessor.h
in the SDK, which supports the latency in case of bypass.
This is awful. And what if plugin does not provide controller or controller is inactive (for example, some hosts allow to launch generic UI instead of the vendor’s one)?
Can you be more specific, what do you mean by “This is awful”?
I mean, the solution is awful. The plugin can request the host for the update from the ‘Processor’ code. The host is not responsible to restart the plugin immediately but can mark the routing graph to be updated in the future. This allows to avoid unnecessary communications between ‘Processor’ and ‘Controller’.
Sorry, I still cannot follow your “awful” statement or what this has to do with a generic UI.
The host could instantiate the processor, set its state, activate the processor, ask for its latency…and process it… the controller is in this use case not necessary