pub unsafe trait Adapter<'a, T: 'a> {
unsafe fn read_sample_unchecked(&self, channel: usize, frame: usize) -> T;
fn read_sample(&self, channel: usize, frame: usize) -> Option<T> {
if channel >= self.channels() || frame >= self.frames() {
return None;
}
Some(unsafe { self.read_sample_unchecked(channel, frame) })
}
fn channels(&self) -> usize;
fn frames(&self) -> usize;
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()
};
for (n, item) in slice.iter_mut().enumerate().take(frames_to_write) {
unsafe { *item = self.read_sample_unchecked(channel, skip + n) };
}
frames_to_write
}
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()
};
for (n, item) in slice.iter_mut().enumerate().take(channels_to_write) {
unsafe { *item = self.read_sample_unchecked(skip + n, frame) };
}
channels_to_write
}
}
pub unsafe trait AdapterMut<'a, T>: Adapter<'a, T>
where
T: Clone + 'a,
{
unsafe fn write_sample_unchecked(&mut self, channel: usize, frame: usize, value: &T) -> bool;
fn write_sample(&mut self, channel: usize, frame: usize, value: &T) -> Option<bool> {
if channel >= self.channels() || frame >= self.frames() {
return None;
}
Some(unsafe { self.write_sample_unchecked(channel, frame, value) })
}
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 mut nbr_clipped = 0;
for (n, item) in slice.iter().enumerate().take(frames_to_read) {
unsafe { nbr_clipped += self.write_sample_unchecked(channel, skip + n, item) as usize };
}
(frames_to_read, nbr_clipped)
}
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 mut nbr_clipped = 0;
for (n, item) in slice.iter().enumerate().take(channels_to_read) {
unsafe { nbr_clipped += self.write_sample_unchecked(skip + n, frame, item) as usize };
}
(channels_to_read, nbr_clipped)
}
fn copy_from_other_to_channel(
&mut self,
other: &dyn Adapter<'a, T>,
other_channel: usize,
self_channel: usize,
other_skip: usize,
self_skip: usize,
take: usize,
) -> Option<usize> {
if self_channel >= self.channels()
|| take + self_skip > self.frames()
|| other_channel >= other.channels()
|| take + other_skip > other.frames()
{
return None;
}
let mut nbr_clipped = 0;
for n in 0..take {
unsafe {
let value = other.read_sample_unchecked(other_channel, n + other_skip);
nbr_clipped +=
self.write_sample_unchecked(self_channel, n + self_skip, &value) as usize
};
}
Some(nbr_clipped)
}
fn fill_channel_with(&mut self, channel: usize, value: &T) -> Option<()> {
if channel >= self.channels() {
return None;
}
for frame in 0..self.frames() {
unsafe { self.write_sample_unchecked(channel, frame, value) };
}
Some(())
}
fn fill_frame_with(&mut self, frame: usize, value: &T) -> Option<()> {
if frame >= self.frames() {
return None;
}
for channel in 0..self.channels() {
unsafe { self.write_sample_unchecked(channel, frame, value) };
}
Some(())
}
fn fill_frames_with(&mut self, start: usize, count: usize, value: &T) -> Option<usize> {
if start + count >= self.frames() {
return None;
}
for channel in 0..self.channels() {
for frame in start..start + count {
unsafe { self.write_sample_unchecked(channel, frame, value) };
}
}
Some(count)
}
fn fill_with(&mut self, value: &T) {
for channel in 0..self.channels() {
self.fill_channel_with(channel, value).unwrap_or_default();
}
}
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;
}
if count == 0 || src == dest {
return Some(count);
}
if dest < src {
for channel in 0..self.channels() {
for frame in 0..count {
unsafe {
let value = self.read_sample_unchecked(channel, frame + src);
self.write_sample_unchecked(channel, frame + dest, &value);
}
}
}
} else {
for channel in 0..self.channels() {
for frame in 0..count {
let backwards = count - frame - 1;
unsafe {
let value = self.read_sample_unchecked(channel, backwards + src);
self.write_sample_unchecked(channel, backwards + dest, &value);
}
}
}
}
Some(count)
}
fn copy_sample_within(
&mut self,
source_channel: usize,
source_frame: usize,
target_channel: usize,
target_frame: usize,
) -> bool {
if let Some(value) = self.read_sample(source_channel, source_frame) {
if self
.write_sample(target_channel, target_frame, &value)
.is_some()
{
return true;
}
}
false
}
fn swap_samples(
&mut self,
channel_a: usize,
frame_a: usize,
channel_b: usize,
frame_b: usize,
) -> bool {
if let Some(value_a) = self.read_sample(channel_a, frame_a) {
if let Some(value_b) = self.read_sample(channel_b, frame_b) {
unsafe {
self.write_sample_unchecked(channel_b, frame_b, &value_a);
self.write_sample_unchecked(channel_a, frame_a, &value_b);
return true;
}
}
}
false
}
}
#[cfg(test)]
mod tests {
extern crate alloc;
use crate::tests::MinimalAdapter;
use crate::{Adapter, AdapterMut};
use alloc::vec;
fn dummy_adapter() -> MinimalAdapter<i32> {
let data = vec![1_i32, 1, 2, 3, 4, 5, 6, 7];
MinimalAdapter::new_from_vec(data, 2, 4)
}
#[test]
fn read_sample() {
let buffer = dummy_adapter();
assert_eq!(buffer.read_sample(0, 0), Some(1));
assert_eq!(buffer.read_sample(1, 3), Some(7));
assert_eq!(buffer.read_sample(2, 0), None); assert_eq!(buffer.read_sample(0, 4), None); }
#[test]
fn copy_from_channel_to_slice() {
let buffer = dummy_adapter();
let mut slice = [0; 3];
let copied = buffer.copy_from_channel_to_slice(0, 1, &mut slice);
assert_eq!(copied, 3);
assert_eq!(slice, [2, 4, 6]);
let mut slice2 = [0; 2];
let copied = buffer.copy_from_channel_to_slice(2, 0, &mut slice2);
assert_eq!(copied, 0);
assert_eq!(slice2, [0, 0]);
let copied = buffer.copy_from_channel_to_slice(0, 4, &mut slice2);
assert_eq!(copied, 0);
let mut slice3 = [0; 5];
let copied = buffer.copy_from_channel_to_slice(0, 0, &mut slice3);
assert_eq!(copied, 4);
assert_eq!(slice3, [1, 2, 4, 6, 0]);
}
#[test]
fn copy_from_frame_to_slice() {
let buffer = dummy_adapter();
let mut slice = [0; 1];
let copied = buffer.copy_from_frame_to_slice(1, 1, &mut slice);
assert_eq!(copied, 1);
assert_eq!(slice, [3]);
let mut slice2 = [0; 2];
let copied = buffer.copy_from_frame_to_slice(4, 0, &mut slice2);
assert_eq!(copied, 0);
assert_eq!(slice2, [0, 0]);
let copied = buffer.copy_from_frame_to_slice(0, 2, &mut slice2);
assert_eq!(copied, 0);
let mut slice3 = [0; 3];
let copied = buffer.copy_from_frame_to_slice(1, 0, &mut slice3);
assert_eq!(copied, 2);
assert_eq!(slice3, [2, 3, 0]);
}
#[test]
fn write_sample() {
let mut buffer = dummy_adapter();
assert_eq!(buffer.write_sample(0, 0, &100), Some(false));
assert_eq!(buffer.read_sample(0, 0), Some(100));
assert_eq!(buffer.write_sample(2, 0, &101), None); assert_eq!(buffer.write_sample(0, 4, &102), None); }
#[test]
fn copy_from_slice_to_channel() {
let mut buffer = dummy_adapter();
let slice = [10, 11];
let (copied, clipped) = buffer.copy_from_slice_to_channel(0, 1, &slice);
assert_eq!(copied, 2);
assert_eq!(clipped, 0);
assert_eq!(buffer.read_sample(0, 0), Some(1));
assert_eq!(buffer.read_sample(0, 1), Some(10));
assert_eq!(buffer.read_sample(0, 2), Some(11));
assert_eq!(buffer.read_sample(0, 3), Some(6));
}
#[test]
fn copy_from_slice_to_frame() {
let mut buffer = dummy_adapter();
let slice = [10];
let (copied, clipped) = buffer.copy_from_slice_to_frame(1, 1, &slice);
assert_eq!(copied, 1);
assert_eq!(clipped, 0);
assert_eq!(buffer.read_sample(0, 1), Some(2));
assert_eq!(buffer.read_sample(1, 1), Some(10));
}
#[test]
fn copy_from_other_to_channel() {
let mut buffer = dummy_adapter();
let other = dummy_adapter();
let clipped = buffer.copy_from_other_to_channel(&other, 1, 0, 0, 0, 4);
assert_eq!(clipped, Some(0));
assert_eq!(buffer.read_sample(0, 0), Some(1));
assert_eq!(buffer.read_sample(0, 1), Some(3));
assert_eq!(buffer.read_sample(0, 2), Some(5));
assert_eq!(buffer.read_sample(0, 3), Some(7));
}
#[test]
fn fill_channel_with() {
let mut buffer = dummy_adapter();
buffer.fill_channel_with(0, &9).unwrap();
assert_eq!(buffer.read_sample(0, 0), Some(9));
assert_eq!(buffer.read_sample(0, 1), Some(9));
assert_eq!(buffer.read_sample(0, 2), Some(9));
assert_eq!(buffer.read_sample(0, 3), Some(9));
assert_eq!(buffer.read_sample(1, 0), Some(1)); }
#[test]
fn fill_frame_with() {
let mut buffer = dummy_adapter();
buffer.fill_frame_with(1, &9).unwrap();
assert_eq!(buffer.read_sample(0, 1), Some(9));
assert_eq!(buffer.read_sample(1, 1), Some(9));
assert_eq!(buffer.read_sample(0, 0), Some(1)); }
#[test]
fn fill_frames_with() {
let mut buffer = dummy_adapter();
buffer.fill_frames_with(1, 2, &9).unwrap();
assert_eq!(buffer.read_sample(0, 0), Some(1));
assert_eq!(buffer.read_sample(0, 1), Some(9));
assert_eq!(buffer.read_sample(0, 2), Some(9));
assert_eq!(buffer.read_sample(0, 3), Some(6));
}
#[test]
fn fill_with() {
let mut buffer = dummy_adapter();
buffer.fill_with(&9);
for f in 0..buffer.frames() {
for c in 0..buffer.channels() {
assert_eq!(buffer.read_sample(c, f), Some(9));
}
}
}
#[test]
fn copy_frames_within_forward_overlap() {
let mut buffer = dummy_adapter();
let copied = buffer.copy_frames_within(0, 1, 2).unwrap();
assert_eq!(copied, 2);
assert_eq!(buffer.read_sample(0, 0), Some(1));
assert_eq!(buffer.read_sample(1, 0), Some(1));
assert_eq!(buffer.read_sample(0, 1), Some(1));
assert_eq!(buffer.read_sample(1, 1), Some(1));
assert_eq!(buffer.read_sample(0, 2), Some(2));
assert_eq!(buffer.read_sample(1, 2), Some(3));
assert_eq!(buffer.read_sample(0, 3), Some(6));
assert_eq!(buffer.read_sample(1, 3), Some(7));
}
#[test]
fn copy_frames_within_backward_overlap() {
let mut buffer = dummy_adapter();
let copied = buffer.copy_frames_within(1, 0, 2).unwrap();
assert_eq!(copied, 2);
assert_eq!(buffer.read_sample(0, 0), Some(2));
assert_eq!(buffer.read_sample(1, 0), Some(3));
assert_eq!(buffer.read_sample(0, 1), Some(4));
assert_eq!(buffer.read_sample(1, 1), Some(5));
assert_eq!(buffer.read_sample(0, 2), Some(4));
assert_eq!(buffer.read_sample(1, 2), Some(5));
assert_eq!(buffer.read_sample(0, 3), Some(6));
assert_eq!(buffer.read_sample(1, 3), Some(7));
}
#[test]
fn copy_sample_within() {
let mut buffer = dummy_adapter();
let success = buffer.copy_sample_within(0, 0, 1, 1);
assert!(success);
assert_eq!(buffer.read_sample(0, 0), Some(1));
assert_eq!(buffer.read_sample(1, 1), Some(1));
assert!(!buffer.copy_sample_within(2, 0, 0, 0));
assert!(!buffer.copy_sample_within(0, 0, 2, 0));
}
#[test]
fn swap_samples() {
let mut buffer = dummy_adapter();
let success = buffer.swap_samples(0, 0, 1, 1);
assert!(success);
assert_eq!(buffer.read_sample(0, 0), Some(3));
assert_eq!(buffer.read_sample(1, 1), Some(1));
assert!(!buffer.swap_samples(0, 0, 2, 0));
}
}