#[derive(Clone, Debug, Default)]
#[non_exhaustive]
pub struct BusLayout {
pub inputs: Vec<BusConfig>,
pub outputs: Vec<BusConfig>,
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct BusConfig {
pub name: &'static str,
pub channels: ChannelConfig,
pub kind: BusKind,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum BusKind {
Main,
Sidechain,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ChannelConfig {
Mono,
Stereo,
Custom(u32),
}
impl ChannelConfig {
#[must_use]
pub fn channel_count(&self) -> u32 {
match self {
Self::Mono => 1,
Self::Stereo => 2,
Self::Custom(n) => *n,
}
}
}
impl BusLayout {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn stereo() -> Self {
Self::new()
.with_input("Main", ChannelConfig::Stereo)
.with_output("Main", ChannelConfig::Stereo)
}
#[must_use]
pub fn with_input(mut self, name: &'static str, channels: ChannelConfig) -> Self {
let kind = if self.inputs.is_empty() {
BusKind::Main
} else {
BusKind::Sidechain
};
self.inputs.push(BusConfig {
name,
channels,
kind,
});
self
}
#[must_use]
pub fn with_sidechain_input(mut self, name: &'static str, channels: ChannelConfig) -> Self {
self.inputs.push(BusConfig {
name,
channels,
kind: BusKind::Sidechain,
});
self
}
#[must_use]
pub fn with_output(mut self, name: &'static str, channels: ChannelConfig) -> Self {
self.outputs.push(BusConfig {
name,
channels,
kind: BusKind::Main,
});
self
}
pub fn sidechain_input_indices(&self) -> impl Iterator<Item = usize> + '_ {
self.inputs
.iter()
.enumerate()
.filter(|(_, b)| b.kind == BusKind::Sidechain)
.map(|(i, _)| i)
}
#[must_use]
pub fn total_input_channels(&self) -> u32 {
self.inputs.iter().map(|b| b.channels.channel_count()).sum()
}
#[must_use]
pub fn total_output_channels(&self) -> u32 {
self.outputs
.iter()
.map(|b| b.channels.channel_count())
.sum()
}
}