clarify responsibilities on plugin latency change
In latency.h it says that a currently activated plugin that wishes to change its latency needs to request the host to restart the plugin. However, to me it's not entirely clear how the fact that latency has changed is meant to get to the host in that case:
- should the host
getthe latency every time a plugin is activated, or - should the plugin call
changedwhile being re-activated in order to inform the host of the latency change?
Doing the former doesn't really hurt either way, but it'd be nice to clarify what's intended.
My interpretation is that it is fine for the host to call clap_plugin_latency::get() every time, but doesn't need to unless clap_host_latency::changed() has been called by the plugin first. From within the activate() call, the plugin should call clap_host_latency::changed(), and be prepared that the host might call back clap_plugin_latency::get() immediately from within the same call.
During normal plugin processing, the steps would be as follows:
- Plugin detects that a new latency is needed for some reason, but we can't use this latency yet.
- If plugin is already activated, call request_restart(). Otherwise we are deactivated, so we just wait for activate() to be called by the host.
- In activate(), new latency is calculated and then changed() is called. The host is then free to call clap_plugin_latency::get() either from inside the changed() call, or at any time after activate() has returned.
The problem with this is that depending on which parameters affects latency, some parameter changes will become "stale" and won't affect the plugin's output. It is only after the host has acknowledged the request_restart call, which "may be delayed by the host".
The same problem occurs with clap_plugin_state::load(), if the new state means the plugin should use new latency. But until being re-activated, the plugin has to continue to use the old latency, which means in practice it can't update any parameters that affects latency. This means you might get glitches or unexpected sound output if the host doesn't react to request_restart quickly enough.
For cases like these, I think the recommendation should be that the plugin uses a fixed latency, so that the latency never needs to be reported to the host. The fixed latency should be high enough to be able to handle all possible plugin settings, and for example implemented with a delay buffer that adjusts itself based on the internal latency, so that the external latency that the host sees never changes.
A similar problem exist with render mode. Changing render mode to CLAP_RENDER_OFFLINE might trigger some plugins to use a higher oversampling rate, with a higher latency. At least one host used to first call activate and start_processing, and then call clap_plugin_render::set(). So what happens is that you get a couple of audio buffers processed with the plugin's old settings, and only after some time the host will react to the request_restart call and re-activates the plugin with the new oversampling and latency. So the beginning of the rendered audio might have some glitches. For this reason, I think the recommendation for clap_plugin_render::set() should be that it is preferably called when the plugin is deactivated, because it is likely it might affect latency.