1
0
Fork 0

Add a reset function to the plugin trait

This is used as part of CLAP 0.19/0.20, and we can just always call it
after the initialize function to stay consistent for VST3 plugins.
This commit is contained in:
Robbert van der Helm 2022-03-08 00:35:55 +01:00
parent 10ced981bd
commit 70d3b5d557
3 changed files with 29 additions and 6 deletions

View file

@ -83,6 +83,9 @@ pub trait Plugin: Default + Send + Sync + 'static {
///
/// Before this point, the plugin should not have done any expensive initialization. Please
/// don't be that plugin that takes twenty seconds to scan.
///
/// After this function [`reset()`][Self::reset()] will always be called. If you need to clear
/// state, such as filters or envelopes, then you should do so in that function inistead.
fn initialize(
&mut self,
bus_config: &BusConfig,
@ -92,6 +95,11 @@ pub trait Plugin: Default + Send + Sync + 'static {
true
}
/// Clear internal state such as filters and envelopes. This is always called after
/// [`initialize()`][Self::initialize(0)], and it may also be called at any other time from the
/// audio thread. You should thus not do any allocations in this function.
fn reset(&mut self) {}
/// Process audio. The host's input buffers have already been copied to the output buffers if
/// they are not processing audio in place (most hosts do however). All channels are also
/// guarenteed to contain the same number of samples. Lastly, denormals have already been taken

View file

@ -721,11 +721,15 @@ impl<P: ClapPlugin> Wrapper<P> {
param.update_smoother(buffer_config.sample_rate, true);
}
if wrapper.plugin.write().initialize(
let mut plugin = wrapper.plugin.write();
if plugin.initialize(
&bus_config,
&buffer_config,
&mut wrapper.make_process_context(Transport::new(buffer_config.sample_rate)),
) {
// As per-the trait docs we'll always call this after the initialization function
plugin.reset();
// Preallocate enough room in the output slices vector so we can convert a `*mut *mut
// f32` to a `&mut [&mut f32]` in the process call
wrapper
@ -766,8 +770,11 @@ impl<P: ClapPlugin> Wrapper<P> {
wrapper.is_processing.store(false, Ordering::SeqCst);
}
unsafe extern "C" fn reset(_plugin: *const clap_plugin) {
// TODO: Split `Plugin::intialize()` into an initialize and a reset function
unsafe extern "C" fn reset(plugin: *const clap_plugin) {
check_null_ptr!((), plugin);
let wrapper = &*(plugin as *const Self);
wrapper.plugin.write().reset();
}
unsafe extern "C" fn process(
@ -1642,11 +1649,13 @@ impl<P: ClapPlugin> Wrapper<P> {
// Reinitialize the plugin after loading state so it can respond to the new parameter values
let bus_config = wrapper.current_bus_config.load();
if let Some(buffer_config) = wrapper.current_buffer_config.load() {
wrapper.plugin.write().initialize(
let mut plugin = wrapper.plugin.write();
plugin.initialize(
&bus_config,
&buffer_config,
&mut wrapper.make_process_context(Transport::new(buffer_config.sample_rate)),
);
plugin.reset();
}
true

View file

@ -234,13 +234,15 @@ impl<P: Vst3Plugin> IComponent for Wrapper<P> {
// Reinitialize the plugin after loading state so it can respond to the new parameter values
let bus_config = self.inner.current_bus_config.load();
if let Some(buffer_config) = self.inner.current_buffer_config.load() {
self.inner.plugin.write().initialize(
let mut plugin = self.inner.plugin.write();
plugin.initialize(
&bus_config,
&buffer_config,
&mut self
.inner
.make_process_context(Transport::new(buffer_config.sample_rate)),
);
plugin.reset();
}
kResultOk
@ -591,13 +593,17 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
param.update_smoother(buffer_config.sample_rate, true);
}
if self.inner.plugin.write().initialize(
let mut plugin = self.inner.plugin.write();
if plugin.initialize(
&bus_config,
&buffer_config,
&mut self
.inner
.make_process_context(Transport::new(buffer_config.sample_rate)),
) {
// As per-the trait docs we'll always call this after the initialization function
plugin.reset();
// Preallocate enough room in the output slices vector so we can convert a `*mut *mut
// f32` to a `&mut [&mut f32]` in the process call
self.inner