From 70d3b5d5573fd3e820d87a96bda7d33e8b75c767 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Tue, 8 Mar 2022 00:35:55 +0100 Subject: [PATCH] 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. --- src/plugin.rs | 8 ++++++++ src/wrapper/clap/wrapper.rs | 17 +++++++++++++---- src/wrapper/vst3/wrapper.rs | 10 ++++++++-- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/plugin.rs b/src/plugin.rs index 4bb54cf8..7c093739 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -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 diff --git a/src/wrapper/clap/wrapper.rs b/src/wrapper/clap/wrapper.rs index 98a09fb9..89a39103 100644 --- a/src/wrapper/clap/wrapper.rs +++ b/src/wrapper/clap/wrapper.rs @@ -721,11 +721,15 @@ impl Wrapper

{ 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 Wrapper

{ 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 Wrapper

{ // 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 diff --git a/src/wrapper/vst3/wrapper.rs b/src/wrapper/vst3/wrapper.rs index 41f3b80e..92c8505c 100644 --- a/src/wrapper/vst3/wrapper.rs +++ b/src/wrapper/vst3/wrapper.rs @@ -234,13 +234,15 @@ impl IComponent for Wrapper

{ // 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 IAudioProcessor for Wrapper

{ 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