use crate::SizeError;
use crate::slicetools::copy_within_slice;
use crate::{check_slice_length, implement_size_getters};
use alloc::{vec, vec::Vec};
use audioadapter::{Adapter, AdapterMut};
pub struct InterleavedOwned<U> {
buf: Vec<U>,
frames: usize,
channels: usize,
}
impl<U> InterleavedOwned<U> {
fn calc_index(&self, channel: usize, frame: usize) -> usize {
frame * self.channels + channel
}
}
impl<T> InterleavedOwned<T>
where
T: Clone,
{
pub fn new(value: T, channels: usize, frames: usize) -> Self {
let buf = vec![value; channels * frames];
Self {
buf,
frames,
channels,
}
}
pub fn new_from(buf: Vec<T>, channels: usize, frames: usize) -> Result<Self, SizeError> {
check_slice_length!(channels, frames, buf.len());
Ok(Self {
buf,
frames,
channels,
})
}
pub fn take_data(self) -> Vec<T> {
self.buf
}
}
unsafe impl<'a, T> Adapter<'a, T> for InterleavedOwned<T>
where
T: Clone + 'a,
{
unsafe fn read_sample_unchecked(&self, channel: usize, frame: usize) -> T {
let index = self.calc_index(channel, frame);
unsafe { self.buf.get_unchecked(index).clone() }
}
implement_size_getters!();
fn copy_from_frame_to_slice(&self, frame: usize, skip: usize, slice: &mut [T]) -> usize {
if frame >= self.frames || skip >= self.channels {
return 0;
}
let channels_to_write = if (self.channels - skip) < slice.len() {
self.channels - skip
} else {
slice.len()
};
let buffer_skip = self.calc_index(skip, frame);
slice[..channels_to_write]
.clone_from_slice(&self.buf[buffer_skip..buffer_skip + channels_to_write]);
channels_to_write
}
}
unsafe impl<'a, T> AdapterMut<'a, T> for InterleavedOwned<T>
where
T: Clone + 'a,
{
unsafe fn write_sample_unchecked(&mut self, channel: usize, frame: usize, value: &T) -> bool {
let index = self.calc_index(channel, frame);
unsafe {
*self.buf.get_unchecked_mut(index) = value.clone();
}
false
}
fn copy_from_slice_to_frame(
&mut self,
frame: usize,
skip: usize,
slice: &[T],
) -> (usize, usize) {
if frame >= self.frames || skip >= self.channels {
return (0, 0);
}
let channels_to_read = if (self.channels - skip) < slice.len() {
self.channels - skip
} else {
slice.len()
};
let buffer_skip = self.calc_index(skip, frame);
self.buf[buffer_skip..buffer_skip + channels_to_read]
.clone_from_slice(&slice[..channels_to_read]);
(channels_to_read, 0)
}
fn copy_frames_within(&mut self, src: usize, dest: usize, count: usize) -> Option<usize> {
if src + count > self.frames || dest + count > self.frames {
return None;
}
unsafe {
copy_within_slice(
&mut self.buf,
src * self.channels,
dest * self.channels,
count * self.channels,
);
}
Some(count)
}
fn copy_sample_within(
&mut self,
source_channel: usize,
source_frame: usize,
target_channel: usize,
target_frame: usize,
) -> bool {
if source_channel >= self.channels
|| source_frame >= self.frames
|| target_channel >= self.channels
|| target_frame >= self.frames
{
return false;
}
let source_index = self.calc_index(source_channel, source_frame);
let target_index = self.calc_index(target_channel, target_frame);
self.buf[target_index] = self.buf[source_index].clone();
true
}
fn swap_samples(
&mut self,
channel_a: usize,
frame_a: usize,
channel_b: usize,
frame_b: usize,
) -> bool {
if channel_a >= self.channels
|| frame_a >= self.frames
|| channel_b >= self.channels
|| frame_b >= self.frames
{
return false;
}
let index_a = self.calc_index(channel_a, frame_a);
let index_b = self.calc_index(channel_b, frame_b);
self.buf.swap(index_a, index_b);
true
}
}
pub struct SequentialOwned<U> {
buf: Vec<U>,
frames: usize,
channels: usize,
}
impl<U> SequentialOwned<U> {
fn calc_index(&self, channel: usize, frame: usize) -> usize {
channel * self.frames + frame
}
}
impl<T> SequentialOwned<T>
where
T: Clone,
{
pub fn new(value: T, channels: usize, frames: usize) -> Self {
let buf = vec![value; channels * frames];
Self {
buf,
frames,
channels,
}
}
pub fn new_from(buf: Vec<T>, channels: usize, frames: usize) -> Result<Self, SizeError> {
check_slice_length!(channels, frames, buf.len());
Ok(Self {
buf,
frames,
channels,
})
}
pub fn take_data(self) -> Vec<T> {
self.buf
}
}
unsafe impl<'a, T> Adapter<'a, T> for SequentialOwned<T>
where
T: Clone + 'a,
{
unsafe fn read_sample_unchecked(&self, channel: usize, frame: usize) -> T {
let index = self.calc_index(channel, frame);
unsafe { self.buf.get_unchecked(index).clone() }
}
implement_size_getters!();
fn copy_from_channel_to_slice(&self, channel: usize, skip: usize, slice: &mut [T]) -> usize {
if channel >= self.channels || skip >= self.frames {
return 0;
}
let frames_to_write = if (self.frames - skip) < slice.len() {
self.frames - skip
} else {
slice.len()
};
let buffer_skip = self.calc_index(channel, skip);
slice[..frames_to_write]
.clone_from_slice(&self.buf[buffer_skip..buffer_skip + frames_to_write]);
frames_to_write
}
}
unsafe impl<'a, T> AdapterMut<'a, T> for SequentialOwned<T>
where
T: Clone + 'a,
{
unsafe fn write_sample_unchecked(&mut self, channel: usize, frame: usize, value: &T) -> bool {
let index = self.calc_index(channel, frame);
unsafe {
*self.buf.get_unchecked_mut(index) = value.clone();
}
false
}
fn copy_from_slice_to_channel(
&mut self,
channel: usize,
skip: usize,
slice: &[T],
) -> (usize, usize) {
if channel >= self.channels || skip >= self.frames {
return (0, 0);
}
let frames_to_read = if (self.frames - skip) < slice.len() {
self.frames - skip
} else {
slice.len()
};
let buffer_skip = self.calc_index(channel, skip);
self.buf[buffer_skip..buffer_skip + frames_to_read]
.clone_from_slice(&slice[..frames_to_read]);
(frames_to_read, 0)
}
fn copy_frames_within(&mut self, src: usize, dest: usize, count: usize) -> Option<usize> {
if src + count > self.frames || dest + count > self.frames {
return None;
}
for ch in 0..self.channels {
let offset = ch * self.frames;
unsafe {
copy_within_slice(&mut self.buf, src + offset, dest + offset, count);
}
}
Some(count)
}
fn copy_sample_within(
&mut self,
source_channel: usize,
source_frame: usize,
target_channel: usize,
target_frame: usize,
) -> bool {
if source_channel >= self.channels
|| source_frame >= self.frames
|| target_channel >= self.channels
|| target_frame >= self.frames
{
return false;
}
let source_index = self.calc_index(source_channel, source_frame);
let target_index = self.calc_index(target_channel, target_frame);
self.buf[target_index] = self.buf[source_index].clone();
true
}
fn swap_samples(
&mut self,
channel_a: usize,
frame_a: usize,
channel_b: usize,
frame_b: usize,
) -> bool {
if channel_a >= self.channels
|| frame_a >= self.frames
|| channel_b >= self.channels
|| frame_b >= self.frames
{
return false;
}
let index_a = self.calc_index(channel_a, frame_a);
let index_b = self.calc_index(channel_b, frame_b);
self.buf.swap(index_a, index_b);
true
}
}
#[cfg(test)]
mod tests {
use super::*;
use audioadapter::tests::test_adapter_mut_methods;
#[cfg(feature = "alloc")]
use alloc::vec;
fn insert_data(buffer: &mut dyn AdapterMut<i32>) {
buffer.write_sample(0, 0, &1);
buffer.write_sample(0, 1, &2);
buffer.write_sample(0, 2, &3);
buffer.write_sample(1, 0, &4);
buffer.write_sample(1, 1, &5);
buffer.write_sample(1, 2, &6);
}
fn test_get(buffer: &mut dyn AdapterMut<i32>) {
insert_data(buffer);
assert_eq!(buffer.read_sample(0, 0).unwrap(), 1);
assert_eq!(buffer.read_sample(0, 1).unwrap(), 2);
assert_eq!(buffer.read_sample(0, 2).unwrap(), 3);
assert_eq!(buffer.read_sample(1, 0).unwrap(), 4);
assert_eq!(buffer.read_sample(1, 1).unwrap(), 5);
assert_eq!(buffer.read_sample(1, 2).unwrap(), 6);
}
fn test_slice_channel(buffer: &mut dyn AdapterMut<i32>) {
insert_data(buffer);
let mut other1 = [0; 2];
let mut other2 = [0; 4];
buffer.copy_from_channel_to_slice(0, 1, &mut other1);
buffer.copy_from_channel_to_slice(1, 0, &mut other2);
assert_eq!(other1[0], 2);
assert_eq!(other1[1], 3);
assert_eq!(other2[0], 4);
assert_eq!(other2[1], 5);
assert_eq!(other2[2], 6);
assert_eq!(other2[3], 0);
}
fn test_slice_frame(buffer: &mut dyn AdapterMut<i32>) {
insert_data(buffer);
let mut other1 = [0; 1];
let mut other2 = [0; 3];
buffer.copy_from_frame_to_slice(0, 1, &mut other1);
buffer.copy_from_frame_to_slice(1, 0, &mut other2);
assert_eq!(other1[0], 4);
assert_eq!(other2[0], 2);
assert_eq!(other2[1], 5);
assert_eq!(other2[2], 0);
}
fn test_mut_slice_channel(buffer: &mut dyn AdapterMut<i32>) {
insert_data(buffer);
let other1 = [8, 9];
let other2 = [10, 11, 12, 13];
buffer.copy_from_slice_to_channel(0, 1, &other1);
buffer.copy_from_slice_to_channel(1, 0, &other2);
assert_eq!(buffer.read_sample(0, 0).unwrap(), 1);
assert_eq!(buffer.read_sample(0, 1).unwrap(), 8);
assert_eq!(buffer.read_sample(0, 2).unwrap(), 9);
assert_eq!(buffer.read_sample(1, 0).unwrap(), 10);
assert_eq!(buffer.read_sample(1, 1).unwrap(), 11);
assert_eq!(buffer.read_sample(1, 2).unwrap(), 12);
}
fn test_mut_slice_frame(buffer: &mut dyn AdapterMut<i32>) {
insert_data(buffer);
let other1 = [8];
let other2 = [10, 11, 12];
buffer.copy_from_slice_to_frame(0, 0, &other1);
buffer.copy_from_slice_to_frame(1, 0, &other2);
assert_eq!(buffer.read_sample(0, 0).unwrap(), 8);
assert_eq!(buffer.read_sample(1, 0).unwrap(), 4);
assert_eq!(buffer.read_sample(0, 1).unwrap(), 10);
assert_eq!(buffer.read_sample(1, 1).unwrap(), 11);
assert_eq!(buffer.read_sample(0, 2).unwrap(), 3);
assert_eq!(buffer.read_sample(1, 2).unwrap(), 6);
}
#[test]
fn interleaved() {
let data = vec![1_i32, 4, 2, 5, 3, 6];
let mut buffer = InterleavedOwned::new_from(data, 2, 3).unwrap();
test_get(&mut buffer);
test_slice_channel(&mut buffer);
test_slice_frame(&mut buffer);
test_mut_slice_channel(&mut buffer);
test_mut_slice_frame(&mut buffer);
let _data = buffer.take_data();
}
#[test]
fn sequential() {
let data = vec![1_i32, 2, 3, 4, 5, 6];
let mut buffer = SequentialOwned::new_from(data, 2, 3).unwrap();
test_get(&mut buffer);
test_slice_channel(&mut buffer);
test_slice_frame(&mut buffer);
test_mut_slice_channel(&mut buffer);
test_mut_slice_frame(&mut buffer);
let _data = buffer.take_data();
}
#[cfg(feature = "std")]
#[test]
fn boxed_buffer() {
let boxed: Box<dyn Adapter<i32>> = Box::new(SequentialOwned::new(1, 2, 3));
assert_eq!(boxed.read_sample(0, 0).unwrap(), 1);
}
#[allow(dead_code)]
fn test_adapter_send_and_sync() {
fn is_send<T: Send>() {}
fn is_sync<T: Sync>() {}
is_send::<InterleavedOwned<f32>>();
is_sync::<InterleavedOwned<f32>>();
}
#[test]
fn copy_channel_from_other() {
let data_other = vec![1.0_f32, 2.0, 3.0, 4.0, 5.0, 6.0];
let other = SequentialOwned::new_from(data_other, 2, 3).unwrap();
let mut buffer: SequentialOwned<f32> = SequentialOwned::new(0.0, 2, 3);
let res1 = buffer.copy_from_other_to_channel(&other, 1, 0, 1, 0, 2);
let res2 = buffer.copy_from_other_to_channel(&other, 0, 1, 0, 1, 2);
assert_eq!(res1, Some(0));
assert_eq!(res2, Some(0));
assert_eq!(buffer.read_sample(0, 0).unwrap(), 5.0);
assert_eq!(buffer.read_sample(0, 1).unwrap(), 6.0);
assert_eq!(buffer.read_sample(0, 2).unwrap(), 0.0);
assert_eq!(buffer.read_sample(1, 0).unwrap(), 0.0);
assert_eq!(buffer.read_sample(1, 1).unwrap(), 1.0);
assert_eq!(buffer.read_sample(1, 2).unwrap(), 2.0);
}
#[test]
fn fill_channel() {
let mut buffer = InterleavedOwned::new(1, 2, 3);
buffer.fill_channel_with(0, &2);
let expected: [i32; 6] = [2, 1, 2, 1, 2, 1];
let data = buffer.take_data();
assert_eq!(data, expected);
}
#[test]
fn fill_frame() {
let mut buffer = InterleavedOwned::new(1, 2, 3);
buffer.fill_frame_with(1, &2);
let expected: [i32; 6] = [1, 1, 2, 2, 1, 1];
let data = buffer.take_data();
assert_eq!(data, expected);
}
#[test]
fn fill_buffer() {
let mut buffer = InterleavedOwned::new(1, 2, 3);
buffer.fill_with(&2);
let expected: [i32; 6] = [2; 6];
let data = buffer.take_data();
assert_eq!(data, expected);
}
#[test]
fn test_interleaved_owned_with_generic_tester() {
let mut buffer = InterleavedOwned::new(0usize, 2, 4);
test_adapter_mut_methods(&mut buffer);
}
#[test]
fn test_sequential_owned_with_generic_tester() {
let mut buffer = SequentialOwned::new(0usize, 2, 4);
test_adapter_mut_methods(&mut buffer);
}
}