From 1d6a9aac74d814ac6366ff1eae11e827e1535b37 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Tue, 8 Feb 2022 23:47:41 +0100 Subject: [PATCH] Add a way to fetch a parameter's default value --- src/context.rs | 20 ++++++++++++++++++++ src/wrapper/vst3/inner.rs | 19 +++++++++++++++---- src/wrapper/vst3/wrapper.rs | 2 +- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/context.rs b/src/context.rs index ee1ed6be..d51d4988 100644 --- a/src/context.rs +++ b/src/context.rs @@ -98,6 +98,16 @@ pub trait GuiContext: Send + Sync + 'static { /// The implementing function still needs to check if `param` actually exists. This function is /// mostly marked as unsafe for API reasons. unsafe fn raw_end_set_parameter(&self, param: ParamPtr); + + /// Retrieve the default value for a parameter, in case you forgot. This does not perform a + /// callback Create a [ParamSetter] and use [ParamSetter::default_param_value] instead for a + /// safe, user friendly API. + /// + /// # Safety + /// + /// The implementing function still needs to check if `param` actually exists. This function is + /// mostly marked as unsafe for API reasons. + unsafe fn raw_default_normalized_param_value(&self, param: ParamPtr) -> f32; } /// A convenience helper for setting parameter values. Any changes made here will be broadcasted to @@ -138,6 +148,16 @@ impl<'a> ParamSetter<'a> { pub fn end_set_parameter(&self, param: &P) { unsafe { self.context.raw_end_set_parameter(param.as_ptr()) }; } + + /// Retrieve the default value for a parameter, in case you forgot. This is useful when + /// implementing GUIs, and it does not perform a callback. + fn raw_default_normalized_param_value(&self, param: &P) -> P::Plain { + let normalized = unsafe { + self.context + .raw_default_normalized_param_value(param.as_ptr()) + }; + param.preview_plain(normalized) + } } /// A trait describing the functionality of the platform-specific event loop that can execute tasks diff --git a/src/wrapper/vst3/inner.rs b/src/wrapper/vst3/inner.rs index 2a891f97..7e01e439 100644 --- a/src/wrapper/vst3/inner.rs +++ b/src/wrapper/vst3/inner.rs @@ -88,8 +88,9 @@ pub(crate) struct WrapperInner { /// addresses will remain stable, as they are obtained from a pinned object. pub param_by_hash: HashMap, /// The default normalized parameter value for every parameter in `param_ids`. We need to store - /// this in case the host requeries the parmaeter later. - pub param_defaults_normalized: Vec, + /// this in case the host requeries the parmaeter later. This is also indexed by the hash so we + /// can retrieve them later for the UI if needed. + pub param_defaults_normalized: HashMap, /// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging /// and when storing and restorign plugin state. pub param_id_to_hash: HashMap<&'static str, u32>, @@ -143,7 +144,7 @@ impl WrapperInner

{ param_hashes: Vec::new(), param_by_hash: HashMap::new(), - param_defaults_normalized: Vec::new(), + param_defaults_normalized: HashMap::new(), param_id_to_hash: HashMap::new(), param_ptr_to_hash: HashMap::new(), }; @@ -178,7 +179,7 @@ impl WrapperInner

{ .collect(); wrapper.param_defaults_normalized = param_id_hashes_ptrs .iter() - .map(|&(_, _, ptr)| unsafe { ptr.normalized_value() }) + .map(|&(_, hash, ptr)| (hash, unsafe { ptr.normalized_value() })) .collect(); wrapper.param_id_to_hash = param_id_hashes_ptrs .iter() @@ -292,6 +293,16 @@ impl GuiContext for WrapperInner

{ None => nih_debug_assert_failure!("Component handler not yet set"), } } + + unsafe fn raw_default_normalized_param_value(&self, param: ParamPtr) -> f32 { + match self.param_ptr_to_hash.get(¶m) { + Some(hash) => self.param_defaults_normalized[hash], + None => { + nih_debug_assert_failure!("Unknown parameter: {:?}", param); + 0.5 + } + } + } } impl MainThreadExecutor for WrapperInner

{ diff --git a/src/wrapper/vst3/wrapper.rs b/src/wrapper/vst3/wrapper.rs index 0dc225ef..047c276c 100644 --- a/src/wrapper/vst3/wrapper.rs +++ b/src/wrapper/vst3/wrapper.rs @@ -431,7 +431,7 @@ impl IEditController for Wrapper

{ | vst3_sys::vst::ParameterFlags::kIsBypass as i32; } else { let param_hash = &self.inner.param_hashes[param_index as usize]; - let default_value = &self.inner.param_defaults_normalized[param_index as usize]; + let default_value = &self.inner.param_defaults_normalized[param_hash]; let param_ptr = &self.inner.param_by_hash[param_hash]; info.id = *param_hash;