use crate::BusInfo;
pub struct ConversionBuffers {
pub main_input_f32: Vec<Vec<f32>>,
pub main_output_f32: Vec<Vec<f32>>,
pub aux_input_f32: Vec<Vec<Vec<f32>>>,
pub aux_output_f32: Vec<Vec<Vec<f32>>>,
}
impl ConversionBuffers {
pub fn new() -> Self {
Self {
main_input_f32: Vec::new(),
main_output_f32: Vec::new(),
aux_input_f32: Vec::new(),
aux_output_f32: Vec::new(),
}
}
pub fn allocate_from_buses(
input_buses: &[BusInfo],
output_buses: &[BusInfo],
max_frames: usize,
) -> Self {
let main_in_channels = input_buses
.first()
.map(|b| b.channel_count as usize)
.unwrap_or(0);
let main_out_channels = output_buses
.first()
.map(|b| b.channel_count as usize)
.unwrap_or(0);
let main_input_f32: Vec<Vec<f32>> = (0..main_in_channels)
.map(|_| vec![0.0f32; max_frames])
.collect();
let main_output_f32: Vec<Vec<f32>> = (0..main_out_channels)
.map(|_| vec![0.0f32; max_frames])
.collect();
let aux_input_f32: Vec<Vec<Vec<f32>>> = input_buses
.iter()
.skip(1)
.map(|info| {
(0..info.channel_count)
.map(|_| vec![0.0f32; max_frames])
.collect()
})
.collect();
let aux_output_f32: Vec<Vec<Vec<f32>>> = output_buses
.iter()
.skip(1)
.map(|info| {
(0..info.channel_count)
.map(|_| vec![0.0f32; max_frames])
.collect()
})
.collect();
Self {
main_input_f32,
main_output_f32,
aux_input_f32,
aux_output_f32,
}
}
pub fn allocate(
main_input_channels: usize,
main_output_channels: usize,
aux_input_channels: &[usize],
aux_output_channels: &[usize],
max_frames: usize,
) -> Self {
let main_input_f32 = (0..main_input_channels)
.map(|_| vec![0.0f32; max_frames])
.collect();
let main_output_f32 = (0..main_output_channels)
.map(|_| vec![0.0f32; max_frames])
.collect();
let aux_input_f32 = aux_input_channels
.iter()
.map(|&channels| (0..channels).map(|_| vec![0.0f32; max_frames]).collect())
.collect();
let aux_output_f32 = aux_output_channels
.iter()
.map(|&channels| (0..channels).map(|_| vec![0.0f32; max_frames]).collect())
.collect();
Self {
main_input_f32,
main_output_f32,
aux_input_f32,
aux_output_f32,
}
}
#[inline]
pub fn main_input_mut(&mut self, channel: usize) -> Option<&mut [f32]> {
self.main_input_f32.get_mut(channel).map(|v| v.as_mut_slice())
}
#[inline]
pub fn main_input(&self, channel: usize) -> Option<&[f32]> {
self.main_input_f32.get(channel).map(|v| v.as_slice())
}
#[inline]
pub fn main_output_mut(&mut self, channel: usize) -> Option<&mut [f32]> {
self.main_output_f32.get_mut(channel).map(|v| v.as_mut_slice())
}
#[inline]
pub fn main_output(&self, channel: usize) -> Option<&[f32]> {
self.main_output_f32.get(channel).map(|v| v.as_slice())
}
#[inline]
pub fn main_input_channel_count(&self) -> usize {
self.main_input_f32.len()
}
#[inline]
pub fn main_output_channel_count(&self) -> usize {
self.main_output_f32.len()
}
#[inline]
pub fn aux_input_mut(&mut self, bus: usize, channel: usize, len: usize) -> Option<&mut [f32]> {
self.aux_input_f32
.get_mut(bus)
.and_then(|b| b.get_mut(channel))
.map(|v| {
let actual_len = len.min(v.len());
&mut v[..actual_len]
})
}
#[inline]
pub fn aux_input(&self, bus: usize, channel: usize, len: usize) -> Option<&[f32]> {
self.aux_input_f32
.get(bus)
.and_then(|b| b.get(channel))
.map(|v| &v[..len.min(v.len())])
}
#[inline]
pub fn aux_output_mut(&mut self, bus: usize, channel: usize, len: usize) -> Option<&mut [f32]> {
self.aux_output_f32
.get_mut(bus)
.and_then(|b| b.get_mut(channel))
.map(|v| {
let actual_len = len.min(v.len());
&mut v[..actual_len]
})
}
#[inline]
pub fn aux_output(&self, bus: usize, channel: usize, len: usize) -> Option<&[f32]> {
self.aux_output_f32
.get(bus)
.and_then(|b| b.get(channel))
.map(|v| &v[..len.min(v.len())])
}
#[inline]
pub fn aux_input_bus_count(&self) -> usize {
self.aux_input_f32.len()
}
#[inline]
pub fn aux_output_bus_count(&self) -> usize {
self.aux_output_f32.len()
}
#[inline]
pub fn aux_input_channel_count(&self, bus: usize) -> usize {
self.aux_input_f32.get(bus).map(|b| b.len()).unwrap_or(0)
}
#[inline]
pub fn aux_output_channel_count(&self, bus: usize) -> usize {
self.aux_output_f32.get(bus).map(|b| b.len()).unwrap_or(0)
}
}
impl Default for ConversionBuffers {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_empty() {
let buffers = ConversionBuffers::new();
assert_eq!(buffers.main_input_channel_count(), 0);
assert_eq!(buffers.main_output_channel_count(), 0);
assert_eq!(buffers.aux_input_bus_count(), 0);
assert_eq!(buffers.aux_output_bus_count(), 0);
}
#[test]
fn test_allocate_stereo() {
let buffers = ConversionBuffers::allocate(2, 2, &[], &[], 512);
assert_eq!(buffers.main_input_channel_count(), 2);
assert_eq!(buffers.main_output_channel_count(), 2);
assert_eq!(buffers.aux_input_bus_count(), 0);
assert_eq!(buffers.aux_output_bus_count(), 0);
assert_eq!(buffers.main_input_f32[0].len(), 512);
assert_eq!(buffers.main_output_f32[1].len(), 512);
}
#[test]
fn test_allocate_with_aux() {
let buffers = ConversionBuffers::allocate(2, 2, &[2, 1], &[2], 256);
assert_eq!(buffers.main_input_channel_count(), 2);
assert_eq!(buffers.main_output_channel_count(), 2);
assert_eq!(buffers.aux_input_bus_count(), 2);
assert_eq!(buffers.aux_output_bus_count(), 1);
assert_eq!(buffers.aux_input_channel_count(0), 2);
assert_eq!(buffers.aux_input_channel_count(1), 1);
assert_eq!(buffers.aux_output_channel_count(0), 2);
}
#[test]
fn test_allocate_from_buses() {
let input_buses = vec![
BusInfo::stereo("Main In"),
BusInfo::aux("Sidechain", 2),
];
let output_buses = vec![BusInfo::stereo("Main Out")];
let buffers = ConversionBuffers::allocate_from_buses(&input_buses, &output_buses, 1024);
assert_eq!(buffers.main_input_channel_count(), 2);
assert_eq!(buffers.main_output_channel_count(), 2);
assert_eq!(buffers.aux_input_bus_count(), 1);
assert_eq!(buffers.aux_input_channel_count(0), 2);
assert_eq!(buffers.aux_output_bus_count(), 0);
}
#[test]
fn test_accessors() {
let mut buffers = ConversionBuffers::allocate(2, 2, &[2], &[], 128);
if let Some(buf) = buffers.main_input_mut(0) {
buf[0] = 0.5;
}
assert_eq!(buffers.main_input(0).unwrap()[0], 0.5);
if let Some(buf) = buffers.main_output_mut(1) {
buf[10] = -0.5;
}
assert_eq!(buffers.main_output(1).unwrap()[10], -0.5);
if let Some(buf) = buffers.aux_input_mut(0, 0, 64) {
buf[0] = 0.25;
}
assert_eq!(buffers.aux_input(0, 0, 64).unwrap()[0], 0.25);
assert!(buffers.main_input(5).is_none());
assert!(buffers.aux_input(5, 0, 64).is_none());
}
}