From 13369e40852b4e38b7b1f240aaad4a80979f1350 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm <mail@robbertvanderhelm.nl> Date: Wed, 2 Feb 2022 15:39:55 +0100 Subject: [PATCH] Reinitialize the plugin after restoring state This lets you use the parameters to set fields on the plugin struct during `initialize()`. --- src/plugin.rs | 6 ++++-- src/wrapper/vst3.rs | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/plugin.rs b/src/plugin.rs index 2c8e4295..53771cb9 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -87,7 +87,9 @@ pub trait Plugin: Default + Send + Sync { /// Process audio. To not have to worry about aliasing, the host's input buffer have already /// been copied to the output buffers if they are not handling buffers in place (most hosts do - /// however). All channels are also guarenteed to contain the same number of samples. + /// however). All channels are also guarenteed to contain the same number of samples. Depending + /// on how the host restores plugin state, this function may also be called twice in rapid + /// succession. /// /// TODO: Provide a way to access auxiliary input channels if the IO configuration is /// assymetric @@ -117,7 +119,7 @@ pub struct BusConfig { } /// Configuration for (the host's) audio buffers. -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct BufferConfig { /// The current sample rate. pub sample_rate: f32, diff --git a/src/wrapper/vst3.rs b/src/wrapper/vst3.rs index d25a9312..550cf6d8 100644 --- a/src/wrapper/vst3.rs +++ b/src/wrapper/vst3.rs @@ -107,6 +107,9 @@ struct WrapperInner<'a, P: Plugin> { is_processing: AtomicBool, /// The current bus configuration, modified through `IAudioProcessor::setBusArrangements()`. current_bus_config: AtomicCell<BusConfig>, + /// The current buffer configuration, containing the sample rate and the maximum block size. + /// Will be set in `IAudioProcessor::setupProcessing()`. + current_buffer_config: AtomicCell<Option<BufferConfig>>, /// Whether the plugin is currently bypassed. This is not yet integrated with the `Plugin` /// trait. bypass_state: AtomicBool, @@ -195,6 +198,7 @@ impl<P: Plugin> WrapperInner<'_, P> { num_input_channels: P::DEFAULT_NUM_INPUTS, num_output_channels: P::DEFAULT_NUM_OUTPUTS, }), + current_buffer_config: AtomicCell::new(None), bypass_state: AtomicBool::new(false), last_process_status: AtomicCell::new(ProcessStatus::Normal), current_latency: AtomicU32::new(0), @@ -520,6 +524,15 @@ impl<P: Plugin> IComponent for Wrapper<'_, P> { .params() .deserialize_fields(&state.fields); + // Reinitialize the plugin after loading state so it can respond to the new parmaeters + 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(&bus_config, &buffer_config, self.inner.as_ref()); + } + kResultOk } @@ -894,6 +907,9 @@ impl<P: Plugin> IAudioProcessor for Wrapper<'_, P> { .as_raw_vec() .resize_with(bus_config.num_output_channels as usize, || &mut []); + // Also store this for later, so we can reinitialize the plugin after restoring state + self.inner.current_buffer_config.store(Some(buffer_config)); + kResultOk } else { kResultFalse