diff --git a/src/wrapper/vst3/context.rs b/src/wrapper/vst3/context.rs index 68bed5a4..6b88b80c 100644 --- a/src/wrapper/vst3/context.rs +++ b/src/wrapper/vst3/context.rs @@ -58,6 +58,7 @@ impl GuiContext for WrapperGuiContext

{ .load() .map(|c| c.sample_rate), ); + self.inner.notify_param_values_changed(); } handler.perform_edit(*hash, normalized as f64); diff --git a/src/wrapper/vst3/inner.rs b/src/wrapper/vst3/inner.rs index e0148a0e..b4dd15ec 100644 --- a/src/wrapper/vst3/inner.rs +++ b/src/wrapper/vst3/inner.rs @@ -235,8 +235,22 @@ impl WrapperInner

{ } } + /// If there's an editor open, let it know that parameter values have changed. This should be + /// called whenever there's been a call or multiple calls to + /// [`set_normalized_value_by_hash()[Self::set_normalized_value_by_hash()`]. + pub fn notify_param_values_changed(&self) { + if let Some(editor) = &self.editor { + editor.param_values_changed(); + } + } + /// Convenience function for setting a value for a parameter as triggered by a VST3 parameter /// update. The same rate is for updating parameter smoothing. + /// + /// After calling this function, you should call + /// [`notify_param_values_changed()`][Self::notify_param_values_changed()] to allow the editor + /// to update itself. This needs to be done seperately so you can process parameter changes in + /// batches. pub fn set_normalized_value_by_hash( &self, hash: u32, diff --git a/src/wrapper/vst3/wrapper.rs b/src/wrapper/vst3/wrapper.rs index 55172a96..eb839b4a 100644 --- a/src/wrapper/vst3/wrapper.rs +++ b/src/wrapper/vst3/wrapper.rs @@ -233,6 +233,8 @@ impl IComponent for Wrapper

{ } // Reinitialize the plugin after loading state so it can respond to the new parameter values + self.inner.notify_param_values_changed(); + let bus_config = self.inner.current_bus_config.load(); if let Some(buffer_config) = self.inner.current_buffer_config.load() { let mut plugin = self.inner.plugin.write(); @@ -461,8 +463,12 @@ impl IEditController for Wrapper

{ .current_buffer_config .load() .map(|c| c.sample_rate); - self.inner - .set_normalized_value_by_hash(id, value as f32, sample_rate) + let result = self + .inner + .set_normalized_value_by_hash(id, value as f32, sample_rate); + self.inner.notify_param_values_changed(); + + result } unsafe fn set_component_handler( @@ -680,6 +686,7 @@ impl IAudioProcessor for Wrapper

{ // chunks whenever a parameter change occurs. Otherwise all parameter changes are // handled right here and now. let mut input_param_changes = self.inner.input_param_changes.borrow_mut(); + let mut parameter_values_changed = false; input_param_changes.clear(); if let Some(param_changes) = data.input_param_changes.upgrade() { let num_param_queues = param_changes.get_parameter_count(); @@ -713,6 +720,7 @@ impl IAudioProcessor for Wrapper

{ value as f32, Some(sample_rate), ); + parameter_values_changed = true; } } } @@ -743,10 +751,17 @@ impl IAudioProcessor for Wrapper

{ change.normalized_value, Some(sample_rate), ); + parameter_values_changed = true; } } } + // This allows the GUI to react to incoming parameter changes + if parameter_values_changed { + self.inner.notify_param_values_changed(); + parameter_values_changed = false; + } + if P::ACCEPTS_MIDI { let mut input_events = self.inner.input_events.borrow_mut(); if let Some(events) = data.input_events.upgrade() {