use crate::sample::Sample;
pub type InputChannel<'a, S> = &'a [S];
pub type OutputChannel<'a, S> = &'a mut [S];
#[derive(Debug, Clone, Copy)]
pub struct BusRange {
start: usize,
len: usize,
}
pub struct AudioBuffer<'a, S: Sample> {
inputs: &'a [&'a [S]],
outputs: &'a mut [&'a mut [S]],
num_frames: usize,
bus_inputs: &'a [BusRange],
bus_outputs: &'a [BusRange],
}
impl<'a, S: Sample> AudioBuffer<'a, S> {
#[must_use]
pub fn new(
inputs: &'a [&'a [S]],
outputs: &'a mut [&'a mut [S]],
num_frames: usize,
bus_inputs: &'a [BusRange],
bus_outputs: &'a [BusRange],
) -> Self {
debug_assert!(
inputs.iter().all(|c| c.len() >= num_frames),
"all input channels must have at least num_frames samples"
);
debug_assert!(
outputs.iter().all(|c| c.len() >= num_frames),
"all output channels must have at least num_frames samples"
);
debug_assert_eq!(
bus_inputs.iter().map(|r| r.len).sum::<usize>(),
inputs.len(),
"input bus ranges must partition the channel array"
);
debug_assert_eq!(
bus_outputs.iter().map(|r| r.len).sum::<usize>(),
outputs.len(),
"output bus ranges must partition the channel array"
);
Self {
inputs,
outputs,
num_frames,
bus_inputs,
bus_outputs,
}
}
#[must_use]
pub fn num_frames(&self) -> usize {
self.num_frames
}
#[must_use]
pub fn num_input_buses(&self) -> usize {
self.bus_inputs.len()
}
#[must_use]
pub fn num_output_buses(&self) -> usize {
self.bus_outputs.len()
}
#[must_use]
pub fn total_input_channels(&self) -> usize {
self.inputs.len()
}
#[must_use]
pub fn total_output_channels(&self) -> usize {
self.outputs.len()
}
#[must_use]
pub fn bus_inputs(&self, bus_index: usize) -> &[InputChannel<'a, S>] {
let range = self.bus_inputs[bus_index];
&self.inputs[range.start..range.start + range.len]
}
pub fn bus_outputs(&mut self, bus_index: usize) -> &mut [&'a mut [S]] {
let range = self.bus_outputs[bus_index];
&mut self.outputs[range.start..range.start + range.len]
}
#[must_use]
pub fn main_inputs(&self) -> &[InputChannel<'a, S>] {
if self.bus_inputs.is_empty() {
&[]
} else {
self.bus_inputs(0)
}
}
pub fn main_outputs(&mut self) -> &mut [&'a mut [S]] {
debug_assert!(
!self.bus_outputs.is_empty(),
"main_outputs called on a buffer with no output buses"
);
self.bus_outputs(0)
}
}
impl BusRange {
#[must_use]
pub const fn new(start: usize, len: usize) -> Self {
Self { start, len }
}
}