#![doc = include_str!("../README.md")]
#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
pub mod direct;
pub mod number_to_float;
#[cfg(feature = "std")]
pub mod owned;
pub mod dummy;
mod slicetools;
#[cfg(feature = "std")]
use std::error::Error;
#[cfg(feature = "std")]
use std::fmt;
pub mod adapter_to_float;
#[derive(Debug)]
pub enum SizeError {
Channel {
index: usize,
actual: usize,
required: usize,
},
Frame {
index: usize,
actual: usize,
required: usize,
},
Total {
actual: usize,
required: usize,
},
Mask {
actual: usize,
required: usize,
},
}
#[cfg(feature = "std")]
impl Error for SizeError {}
#[cfg(feature = "std")]
impl fmt::Display for SizeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let desc = match self {
SizeError::Channel {
index,
actual,
required,
} => format!(
"Buffer for channel {} is too short, got: {}, required: {}",
index, actual, required
),
SizeError::Frame {
index,
actual,
required,
} => format!(
"Buffer for frame {} is too short, got: {}, required: {}",
index, actual, required
),
SizeError::Total { actual, required } => format!(
"Buffer is too short, got: {}, required: {}",
actual, required
),
SizeError::Mask { actual, required } => format!(
"Mask is wrong length, got: {}, required: {}",
actual, required
),
};
write!(f, "{}", &desc)
}
}
macro_rules! implement_size_getters {
() => {
fn channels(&self) -> usize {
self.channels
}
fn frames(&self) -> usize {
self.frames
}
};
}
pub(crate) use implement_size_getters;
macro_rules! check_slice_length {
($channels:expr , $frames:expr, $length:expr ) => {
if $length < $frames * $channels {
return Err(SizeError::Total {
actual: $length,
required: $frames * $channels,
});
}
};
($channels:expr , $frames:expr, $length:expr, $elements_per_sample:expr) => {
if $length < $frames * $channels * $elements_per_sample {
return Err(SizeError::Total {
actual: $length,
required: $frames * $channels * $elements_per_sample,
});
}
};
}
pub(crate) use check_slice_length;
#[cfg(test)]
mod tests {
use audioadapter::AdapterMut;
fn prepare_test_data(buffer: &mut dyn AdapterMut<u32>) {
for channel in 0..buffer.channels() {
for frame in 0..buffer.frames() {
let value = (100 * channel + frame) as u32;
buffer.write_sample(channel, frame, &value);
}
}
}
pub(crate) fn check_copy_within(buffer: &mut dyn AdapterMut<u32>) {
assert!(buffer.channels() > 1, "Too few chanels to run tests");
assert!(buffer.frames() > 8, "Too few frames to run test");
prepare_test_data(buffer);
assert_eq!(buffer.copy_frames_within(1, 5, 3), Some(3));
check_copy_result(buffer, 1, 5, 3);
prepare_test_data(buffer);
assert_eq!(buffer.copy_frames_within(5, 1, 3), Some(3));
check_copy_result(buffer, 5, 1, 3);
prepare_test_data(buffer);
assert_eq!(buffer.copy_frames_within(1, 3, 5), Some(5));
check_copy_result(buffer, 1, 3, 5);
prepare_test_data(buffer);
assert_eq!(buffer.copy_frames_within(3, 1, 5), Some(5));
check_copy_result(buffer, 3, 1, 5);
}
fn check_copy_result(buffer: &dyn AdapterMut<u32>, src: usize, dest: usize, count: usize) {
for channel in 0..buffer.channels() {
for frame in 0..buffer.frames() {
let copied_frame = if frame >= dest && frame < dest + count {
frame + src - dest
} else {
frame
};
let expected_value = (100 * channel + copied_frame) as u32;
assert_eq!(
buffer.read_sample(channel, frame),
Some(expected_value),
"Wrong value at ch {}, frame {}",
channel,
frame
);
}
}
}
}