use four_cc::FourCC;
use crate::parameter::{EnumParameter, FloatParameter, Parameter, ParameterPolarity};
pub(crate) mod matrix;
pub(crate) mod processor;
pub(crate) mod state;
#[derive(Debug, Clone)]
#[allow(clippy::large_enum_variant)]
pub enum ModulationSource {
Lfo {
id: FourCC,
name: &'static str,
rate_param: FloatParameter,
waveform_param: EnumParameter,
},
Envelope {
id: FourCC,
name: &'static str,
attack_param: FloatParameter,
hold_param: FloatParameter,
decay_param: FloatParameter,
sustain_param: FloatParameter,
release_param: FloatParameter,
},
Velocity { id: FourCC, name: &'static str },
Keytracking { id: FourCC, name: &'static str },
}
impl ModulationSource {
pub fn id(&self) -> FourCC {
match self {
Self::Lfo { id, .. } => *id,
Self::Envelope { id, .. } => *id,
Self::Velocity { id, .. } => *id,
Self::Keytracking { id, .. } => *id,
}
}
pub fn name(&self) -> &'static str {
match self {
Self::Lfo { name, .. } => name,
Self::Envelope { name, .. } => name,
Self::Velocity { name, .. } => name,
Self::Keytracking { name, .. } => name,
}
}
pub fn parameters(&self) -> Vec<&dyn Parameter> {
match self {
Self::Lfo {
rate_param,
waveform_param,
..
} => vec![rate_param as &dyn Parameter, waveform_param],
Self::Envelope {
attack_param,
hold_param,
decay_param,
sustain_param,
release_param,
..
} => vec![
attack_param as &dyn Parameter,
hold_param,
decay_param,
sustain_param,
release_param,
],
Self::Velocity { .. } | Self::Keytracking { .. } => vec![],
}
}
pub fn polarity(&self) -> ParameterPolarity {
match self {
Self::Lfo { .. } => ParameterPolarity::Bipolar,
Self::Envelope { .. } | Self::Velocity { .. } | Self::Keytracking { .. } => {
ParameterPolarity::Unipolar
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ModulationTarget {
id: FourCC,
name: &'static str,
}
impl ModulationTarget {
pub const fn new(id: FourCC, name: &'static str) -> Self {
Self { id, name }
}
#[inline]
pub const fn id(&self) -> FourCC {
self.id
}
#[inline]
pub const fn name(&self) -> &'static str {
self.name
}
}
#[derive(Debug, Clone, Default)]
pub struct ModulationConfig {
pub sources: Vec<ModulationSource>,
pub targets: Vec<ModulationTarget>,
}
impl ModulationConfig {
pub fn source_parameters(&self) -> Vec<Box<dyn Parameter>> {
self.sources
.iter()
.flat_map(|source_config| {
source_config
.parameters()
.iter()
.map(|p| p.dyn_clone())
.collect::<Vec<_>>()
})
.collect()
}
}