use crate::event::LV2AtomSequence;
#[derive(Copy, Clone, Debug)]
pub enum IOType {
Input,
Output,
}
#[derive(Copy, Clone, Debug)]
pub enum DataType {
Control,
Audio,
AtomSequence,
CV,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum PortType {
ControlInput,
ControlOutput,
AudioInput,
AudioOutput,
AtomSequenceInput,
AtomSequenceOutput,
CVInput,
CVOutput,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct PortIndex(pub usize);
#[derive(Clone, Debug, PartialEq)]
pub struct Port {
pub port_type: PortType,
pub name: String,
pub default_value: f32,
pub min_value: Option<f32>,
pub max_value: Option<f32>,
pub index: PortIndex,
}
pub type EmptyPortConnections = PortConnections<
'static,
std::iter::Empty<&'static [f32]>,
std::iter::Empty<&'static mut [f32]>,
std::iter::Empty<&'static LV2AtomSequence>,
std::iter::Empty<&'static mut LV2AtomSequence>,
std::iter::Empty<&'static [f32]>,
std::iter::Empty<&'static mut [f32]>,
>;
impl EmptyPortConnections {
pub fn new() -> EmptyPortConnections {
EmptyPortConnections {
audio_inputs: std::iter::empty(),
audio_outputs: std::iter::empty(),
atom_sequence_inputs: std::iter::empty(),
atom_sequence_outputs: std::iter::empty(),
cv_inputs: std::iter::empty(),
cv_outputs: std::iter::empty(),
}
}
}
impl Default for EmptyPortConnections {
fn default() -> Self {
Self::new()
}
}
pub struct PortConnections<
'a,
AudioInputs,
AudioOutputs,
AtomSequenceInputs,
AtomSequenceOutputs,
CVInputs,
CVOutputs,
> where
AudioInputs: ExactSizeIterator + Iterator<Item = &'a [f32]>,
AudioOutputs: ExactSizeIterator + Iterator<Item = &'a mut [f32]>,
AtomSequenceInputs: ExactSizeIterator + Iterator<Item = &'a LV2AtomSequence>,
AtomSequenceOutputs: ExactSizeIterator + Iterator<Item = &'a mut LV2AtomSequence>,
CVInputs: ExactSizeIterator + Iterator<Item = &'a [f32]>,
CVOutputs: ExactSizeIterator + Iterator<Item = &'a mut [f32]>,
{
pub audio_inputs: AudioInputs,
pub audio_outputs: AudioOutputs,
pub atom_sequence_inputs: AtomSequenceInputs,
pub atom_sequence_outputs: AtomSequenceOutputs,
pub cv_inputs: CVInputs,
pub cv_outputs: CVOutputs,
}
impl<
'a,
AudioInputs,
AudioOutputs,
AtomSequenceInputs,
AtomSequenceOutputs,
CVInputs,
CVOutputs,
>
PortConnections<
'a,
AudioInputs,
AudioOutputs,
AtomSequenceInputs,
AtomSequenceOutputs,
CVInputs,
CVOutputs,
>
where
AudioInputs: ExactSizeIterator + Iterator<Item = &'a [f32]>,
AudioOutputs: ExactSizeIterator + Iterator<Item = &'a mut [f32]>,
AtomSequenceInputs: ExactSizeIterator + Iterator<Item = &'a LV2AtomSequence>,
AtomSequenceOutputs: ExactSizeIterator + Iterator<Item = &'a mut LV2AtomSequence>,
CVInputs: ExactSizeIterator + Iterator<Item = &'a [f32]>,
CVOutputs: ExactSizeIterator + Iterator<Item = &'a mut [f32]>,
{
pub fn port_counts(&self) -> PortCounts {
PortCounts {
control_inputs: 0,
control_outputs: 0,
audio_inputs: self.audio_inputs.len(),
audio_outputs: self.audio_outputs.len(),
atom_sequence_inputs: self.atom_sequence_inputs.len(),
atom_sequence_outputs: self.atom_sequence_outputs.len(),
cv_inputs: self.cv_inputs.len(),
cv_outputs: self.cv_outputs.len(),
}
}
pub fn with_audio_inputs<I>(
self,
audio_inputs: I,
) -> PortConnections<
'a,
I,
AudioOutputs,
AtomSequenceInputs,
AtomSequenceOutputs,
CVInputs,
CVOutputs,
>
where
I: ExactSizeIterator + Iterator<Item = &'a [f32]>,
{
PortConnections {
audio_inputs,
audio_outputs: self.audio_outputs,
atom_sequence_inputs: self.atom_sequence_inputs,
atom_sequence_outputs: self.atom_sequence_outputs,
cv_inputs: self.cv_inputs,
cv_outputs: self.cv_outputs,
}
}
pub fn with_audio_outputs<I>(
self,
audio_outputs: I,
) -> PortConnections<
'a,
AudioInputs,
I,
AtomSequenceInputs,
AtomSequenceOutputs,
CVInputs,
CVOutputs,
>
where
I: ExactSizeIterator + Iterator<Item = &'a mut [f32]>,
{
PortConnections {
audio_inputs: self.audio_inputs,
audio_outputs,
atom_sequence_inputs: self.atom_sequence_inputs,
atom_sequence_outputs: self.atom_sequence_outputs,
cv_inputs: self.cv_inputs,
cv_outputs: self.cv_outputs,
}
}
pub fn with_atom_sequence_inputs<I>(
self,
atom_sequence_inputs: I,
) -> PortConnections<'a, AudioInputs, AudioOutputs, I, AtomSequenceOutputs, CVInputs, CVOutputs>
where
I: ExactSizeIterator + Iterator<Item = &'a LV2AtomSequence>,
{
PortConnections {
audio_inputs: self.audio_inputs,
audio_outputs: self.audio_outputs,
atom_sequence_inputs,
atom_sequence_outputs: self.atom_sequence_outputs,
cv_inputs: self.cv_inputs,
cv_outputs: self.cv_outputs,
}
}
pub fn with_atom_sequence_outputs<I>(
self,
atom_sequence_outputs: I,
) -> PortConnections<'a, AudioInputs, AudioOutputs, AtomSequenceInputs, I, CVInputs, CVOutputs>
where
I: ExactSizeIterator + Iterator<Item = &'a mut LV2AtomSequence>,
{
PortConnections {
audio_inputs: self.audio_inputs,
audio_outputs: self.audio_outputs,
atom_sequence_inputs: self.atom_sequence_inputs,
atom_sequence_outputs,
cv_inputs: self.cv_inputs,
cv_outputs: self.cv_outputs,
}
}
pub fn with_cv_inputs<I>(
self,
cv_inputs: I,
) -> PortConnections<
'a,
AudioInputs,
AudioOutputs,
AtomSequenceInputs,
AtomSequenceOutputs,
I,
CVOutputs,
>
where
I: ExactSizeIterator + Iterator<Item = &'a [f32]>,
{
PortConnections {
audio_inputs: self.audio_inputs,
audio_outputs: self.audio_outputs,
atom_sequence_inputs: self.atom_sequence_inputs,
atom_sequence_outputs: self.atom_sequence_outputs,
cv_inputs,
cv_outputs: self.cv_outputs,
}
}
pub fn with_cv_outputs<I>(
self,
cv_outputs: I,
) -> PortConnections<
'a,
AudioInputs,
AudioOutputs,
AtomSequenceInputs,
AtomSequenceOutputs,
CVInputs,
I,
>
where
I: ExactSizeIterator + Iterator<Item = &'a mut [f32]>,
{
PortConnections {
audio_inputs: self.audio_inputs,
audio_outputs: self.audio_outputs,
atom_sequence_inputs: self.atom_sequence_inputs,
atom_sequence_outputs: self.atom_sequence_outputs,
cv_inputs: self.cv_inputs,
cv_outputs,
}
}
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
pub struct PortCounts {
pub control_inputs: usize,
pub control_outputs: usize,
pub audio_inputs: usize,
pub audio_outputs: usize,
pub atom_sequence_inputs: usize,
pub atom_sequence_outputs: usize,
pub cv_inputs: usize,
pub cv_outputs: usize,
}
#[derive(Debug)]
struct DetailedPortValues {
port_index: PortIndex,
value: f32,
minimum: f32,
maximum: f32,
}
#[derive(Debug)]
pub(crate) struct Controls {
controls: Vec<DetailedPortValues>,
}
impl Controls {
pub(crate) fn new<I>(ports: I) -> Controls
where
I: Iterator<Item = Port>,
{
let mut controls: Vec<DetailedPortValues> = ports
.map(|p| DetailedPortValues {
port_index: p.index,
value: p.default_value,
minimum: p.min_value.unwrap_or(std::f32::NEG_INFINITY),
maximum: p.max_value.unwrap_or(std::f32::INFINITY),
})
.collect();
controls.sort_by(|a, b| a.port_index.cmp(&b.port_index));
controls.dedup_by_key(|p| p.port_index);
Controls { controls }
}
pub fn get(&self, port: PortIndex) -> Option<f32> {
let idx = self.port_index_to_index_in_controls(port)?;
self.controls.get(idx).map(|p| p.value)
}
pub fn len(&self) -> usize {
self.controls.len()
}
pub fn set(&mut self, port: PortIndex, value: f32) -> Option<f32> {
let idx = self.port_index_to_index_in_controls(port)?;
let mut p = self.controls.get_mut(idx)?;
let normalized_value = value.clamp(p.minimum, p.maximum);
p.value = normalized_value;
Some(normalized_value)
}
pub fn value_ptr(&self, port: PortIndex) -> Option<*const f32> {
let idx = self.port_index_to_index_in_controls(port)?;
let p = self.controls.get(idx)?;
Some(&p.value)
}
fn port_index_to_index_in_controls(&self, port: PortIndex) -> Option<usize> {
self.controls
.binary_search_by_key(&port, |p| p.port_index)
.ok()
}
}