Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

Support for parameter properties min/max and step sizes #185

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,72 @@ impl Default for SmpteFrameRate {
}
}

/// Parameter properties.
#[repr(C)]
pub struct VstParameterProperties {
/// Float step.
pub step_float: f32,
/// Small float step.
pub small_step_float: f32,
/// Large float step.
pub large_step_float: f32,
/// Parameter label.
pub label: [u8; 64],
/// Flags found in `VstParameterFlags`.
pub flags: i32,
/// Integer minimum.
pub min_integer: i32,
/// Integer maximum.
pub max_integer: i32,
/// Integer step.
pub step_integer: i32,
/// Large integer step.
pub large_step_integer: i32,
/// Short label.
///
/// Recommended: 6 characters + delimiter.
pub short_label: [u8; 8],
/// Index where this parameter should be displayed (starting with 0).
///
/// Requires flag `SUPPORTS_DISPLAY_INDEX`.
pub display_index: i16,
/// Parameter category.
///
/// 0 means no category, else category index + 1.
pub category: i16,
/// Number of parameters in category.
pub num_parameters_in_category: i16,
/// Reserved for future use (please zero).
pub reserved: i16,
/// Category label.
pub category_label: [u8; 24],
/// Reserved for future use (please zero).
pub future: [u8; 16],
}

impl Default for VstParameterProperties {
fn default() -> Self {
Self {
step_float: 0.0,
small_step_float: 0.0,
large_step_float: 0.0,
label: [0; 64],
flags: 0,
min_integer: 0,
max_integer: 0,
step_integer: 0,
large_step_integer: 0,
short_label: [0; 8],
display_index: 0,
category: 0,
num_parameters_in_category: 0,
reserved: 0,
category_label: [0; 24],
future: [0; 16],
}
}
}

bitflags! {
/// Flags for VST channels.
pub struct ChannelFlags: i32 {
Expand Down Expand Up @@ -828,6 +894,28 @@ bitflags! {
}
}

bitflags! {
/// Flags for VST parameters.
///
/// Used in `VstParameterProperties`.
pub struct VstParameterFlags: i32 {
/// Parameter is a switch (on or off).
const IS_SWITCH = 1;
/// Indicates that `min_integer` and `max_integer` are valid.
const USES_INTEGER_MIN_MAX = 1 << 1;
/// Indicates that `step_float`, `small_step_float` and `large_step_float` are valid.
const USES_FLOAT_STEP = 1 << 2;
/// Indicates that `step_integer` and `large_step_integer` are valid.
const USES_INT_STEP = 1 << 3;
/// Indicates that `display_index` is valid.
const SUPPORTS_DISPLAY_INDEX = 1 << 4;
/// Indicates that `category`, `num_parameters_in_category` and `category_label` are valid.
const SUPPORTS_DISPLAY_CATEGORY = 1 << 5;
/// If the parameter value can ramp up or down.
const CAN_RAMP = 1 << 6;
}
}

#[cfg(test)]
mod tests {
use super::super::event;
Expand Down
13 changes: 11 additions & 2 deletions src/interfaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ fn copy_string(dst: *mut c_void, src: &str, max: usize) -> isize {

let dst = dst as *mut c_void;
memset(dst, 0, max);
memcpy(dst, src.as_ptr() as *const c_void, min(max, src.as_bytes().len()));
memcpy(dst, src.as_ptr() as *const c_void, min(max - 1, src.as_bytes().len()));
}

1 // Success
Expand Down Expand Up @@ -244,7 +244,16 @@ pub extern "C" fn dispatch(
}
}

//OpCode::GetParamInfo => { /*TODO*/ }
Ok(OpCode::GetParamInfo) => {
if let Some(info) = get_plugin().get_parameter_info(index) {
let ptr = ptr as *mut api::VstParameterProperties;
unsafe {
*ptr = info.into();
}
return 1;
}
}

Ok(OpCode::GetApiVersion) => return 2400,

Ok(OpCode::EditorKeyDown) => {
Expand Down
109 changes: 109 additions & 0 deletions src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,110 @@ impl Default for Info {
}
}

/// A structure representing information about a specific plug-in parameter.
///
/// # Example
///
/// ```no_run
/// # use vst::plugin::{PluginParameterCharacter, PluginParameterInfo};
/// let mut info = PluginParameterInfo::default();
/// info.character = PluginParameterCharacter::Switch;
/// ```
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct PluginParameterInfo {
/// Defines the parameter character.
pub character: PluginParameterCharacter,
/// If the parameter value can ramp up or down.
pub can_ramp: bool,
}

impl Default for PluginParameterInfo {
fn default() -> Self {
Self {
character: PluginParameterCharacter::Continuous { steps: None },
can_ramp: false,
}
}
}

/// Character of a plug-in parameter.
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum PluginParameterCharacter {
/// Parameter is a switch (on or off).
Switch,
/// Parameter has a continuous value range (floating point numbers).
Continuous {
/// Step sizes.
steps: Option<FloatSteps>,
},
/// Parameter has a discrete value range (integers).
Discrete {
/// Minimum value.
min: i32,
/// Maximum value.
max: i32,
/// Step sizes.
steps: Option<IntegerSteps>,
},
}

/// Custom step sizes for continuous parameters.
#[derive(Clone, Debug)]
pub struct FloatSteps {
/// Normal step.
pub step: f32,
/// Small step.
pub small_step: f32,
/// Large step.
pub large_step: f32,
}

/// Custom step sizes for discrete parameters.
#[derive(Clone, Debug)]
pub struct IntegerSteps {
/// Normal step.
pub step: i32,
/// Large step.
pub large_step: i32,
}

impl From<PluginParameterInfo> for api::VstParameterProperties {
fn from(info: PluginParameterInfo) -> api::VstParameterProperties {
let mut props = api::VstParameterProperties::default();
let mut flags = api::VstParameterFlags::empty();
if info.can_ramp {
flags |= api::VstParameterFlags::CAN_RAMP;
}
match info.character {
PluginParameterCharacter::Switch => {
flags |= api::VstParameterFlags::IS_SWITCH;
}
PluginParameterCharacter::Continuous { steps } => {
if let Some(steps) = steps {
flags |= api::VstParameterFlags::USES_FLOAT_STEP;
props.small_step_float = steps.small_step;
props.step_float = steps.step;
props.large_step_float = steps.large_step;
}
}
PluginParameterCharacter::Discrete { min, max, steps } => {
flags |= api::VstParameterFlags::USES_INTEGER_MIN_MAX;
props.min_integer = min;
props.max_integer = max;
if let Some(steps) = steps {
flags |= api::VstParameterFlags::USES_INT_STEP;
props.step_integer = steps.step;
props.large_step_integer = steps.large_step;
}
}
}
props.flags = flags.bits();
props
}
}

/// Features which are optionally supported by a plugin. These are queried by the host at run time.
#[derive(Debug)]
#[allow(missing_docs)]
Expand Down Expand Up @@ -676,6 +780,11 @@ pub trait Plugin: Send {
)
}

/// Returns additional information about the parameter at the given index.
fn get_parameter_info(&self, index: i32) -> Option<PluginParameterInfo> {
None
}

/// Called one time before the start of process call.
///
/// This indicates that the process call will be interrupted (due to Host reconfiguration
Expand Down