use core::ops::{Index, IndexMut, Range};
#[derive(Debug, Clone, Copy)]
pub struct ChannelBufferRef<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> {
data: &'a [T],
offsets: [*const T; CHANNELS],
frames: usize,
}
impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize>
ChannelBufferRef<'a, T, CHANNELS>
{
const _COMPILE_TIME_ASSERTS: () = {
assert!(CHANNELS > 0);
};
#[inline(always)]
pub(crate) unsafe fn from_raw(
data: &'a [T],
offsets: [*const T; CHANNELS],
frames: usize,
) -> Self {
let _ = Self::_COMPILE_TIME_ASSERTS;
Self {
data,
offsets,
frames,
}
}
pub fn empty() -> Self {
let _ = Self::_COMPILE_TIME_ASSERTS;
let data = &[];
let offsets = core::array::from_fn(|_| data.as_ptr());
Self {
data,
offsets,
frames: 0,
}
}
pub fn new(data: &'a [T]) -> Self {
let _ = Self::_COMPILE_TIME_ASSERTS;
let frames = data.len() / CHANNELS;
Self {
data,
offsets: unsafe { core::array::from_fn(|ch_i| data.as_ptr().add(ch_i * frames)) },
frames,
}
}
pub unsafe fn new_unchecked(data: &'a [T], frames: usize) -> Self {
let _ = Self::_COMPILE_TIME_ASSERTS;
Self {
data,
offsets: core::array::from_fn(|ch_i| data.as_ptr().add(ch_i * frames)),
frames,
}
}
pub fn frames(&self) -> usize {
self.frames
}
pub fn channels(&self) -> usize {
CHANNELS
}
#[inline(always)]
pub fn channel(&self, index: usize) -> Option<&[T]> {
if index < CHANNELS {
unsafe { Some(self.channel_unchecked(index)) }
} else {
None
}
}
#[inline(always)]
pub unsafe fn channel_unchecked(&self, index: usize) -> &[T] {
core::slice::from_raw_parts(*self.offsets.get_unchecked(index), self.frames)
}
#[inline]
pub fn as_slices(&self) -> [&[T]; CHANNELS] {
unsafe {
core::array::from_fn(|ch_i| {
core::slice::from_raw_parts(*self.offsets.get_unchecked(ch_i), self.frames)
})
}
}
#[inline]
pub fn as_slices_with_length(&self, frames: usize) -> [&[T]; CHANNELS] {
let frames = frames.min(self.frames);
unsafe {
core::array::from_fn(|ch_i| {
core::slice::from_raw_parts(*self.offsets.get_unchecked(ch_i), frames)
})
}
}
#[inline]
pub fn as_slices_with_range(&self, range: Range<usize>) -> [&[T]; CHANNELS] {
let start_frame = range.start.min(self.frames);
let frames = range.end.min(self.frames) - start_frame;
unsafe {
core::array::from_fn(|ch_i| {
core::slice::from_raw_parts(
self.offsets.get_unchecked(ch_i).add(start_frame),
frames,
)
})
}
}
pub fn raw(&self) -> &[T] {
self.data
}
}
impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Index<usize>
for ChannelBufferRef<'a, T, CHANNELS>
{
type Output = [T];
#[inline(always)]
fn index(&self, index: usize) -> &Self::Output {
self.channel(index).unwrap()
}
}
impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Default
for ChannelBufferRef<'a, T, CHANNELS>
{
fn default() -> Self {
Self::empty()
}
}
impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Into<&'a [T]>
for ChannelBufferRefMut<'a, T, CHANNELS>
{
fn into(self) -> &'a [T] {
self.data
}
}
unsafe impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Send
for ChannelBufferRef<'a, T, CHANNELS>
{
}
unsafe impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Sync
for ChannelBufferRef<'a, T, CHANNELS>
{
}
#[derive(Debug)]
pub struct ChannelBufferRefMut<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> {
data: &'a mut [T],
offsets: [*mut T; CHANNELS],
frames: usize,
}
impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize>
ChannelBufferRefMut<'a, T, CHANNELS>
{
const _COMPILE_TIME_ASSERTS: () = {
assert!(CHANNELS > 0);
};
#[inline(always)]
pub(crate) unsafe fn from_raw(
data: &'a mut [T],
offsets: [*mut T; CHANNELS],
frames: usize,
) -> Self {
let _ = Self::_COMPILE_TIME_ASSERTS;
Self {
data,
offsets,
frames,
}
}
pub fn empty() -> Self {
let _ = Self::_COMPILE_TIME_ASSERTS;
let data = &mut [];
let offsets = core::array::from_fn(|_| data.as_mut_ptr());
Self {
data,
offsets,
frames: 0,
}
}
pub fn new(data: &'a mut [T]) -> Self {
let _ = Self::_COMPILE_TIME_ASSERTS;
let frames = data.len() / CHANNELS;
let offsets = unsafe { core::array::from_fn(|ch_i| data.as_mut_ptr().add(ch_i * frames)) };
Self {
data,
offsets,
frames,
}
}
pub unsafe fn new_unchecked(data: &'a mut [T], frames: usize) -> Self {
let _ = Self::_COMPILE_TIME_ASSERTS;
let offsets = core::array::from_fn(|ch_i| data.as_mut_ptr().add(ch_i * frames));
Self {
data,
offsets,
frames,
}
}
pub fn frames(&self) -> usize {
self.frames
}
pub fn channels(&self) -> usize {
CHANNELS
}
#[inline(always)]
pub fn channel(&self, index: usize) -> Option<&[T]> {
if index < CHANNELS {
unsafe { Some(self.channel_unchecked(index)) }
} else {
None
}
}
#[inline(always)]
pub unsafe fn channel_unchecked(&self, index: usize) -> &[T] {
core::slice::from_raw_parts(*self.offsets.get_unchecked(index), self.frames)
}
#[inline(always)]
pub fn channel_mut(&mut self, index: usize) -> Option<&mut [T]> {
if index < CHANNELS {
unsafe { Some(self.channel_unchecked_mut(index)) }
} else {
None
}
}
#[inline(always)]
pub unsafe fn channel_unchecked_mut(&mut self, index: usize) -> &mut [T] {
core::slice::from_raw_parts_mut(*self.offsets.get_unchecked(index), self.frames)
}
#[inline]
pub fn as_slices(&self) -> [&[T]; CHANNELS] {
unsafe {
core::array::from_fn(|ch_i| {
core::slice::from_raw_parts(*self.offsets.get_unchecked(ch_i), self.frames)
})
}
}
#[inline]
pub fn as_mut_slices(&mut self) -> [&mut [T]; CHANNELS] {
unsafe {
core::array::from_fn(|ch_i| {
core::slice::from_raw_parts_mut(*self.offsets.get_unchecked(ch_i), self.frames)
})
}
}
#[inline]
pub fn as_slices_with_length(&self, frames: usize) -> [&[T]; CHANNELS] {
let frames = frames.min(self.frames);
unsafe {
core::array::from_fn(|ch_i| {
core::slice::from_raw_parts(*self.offsets.get_unchecked(ch_i), frames)
})
}
}
#[inline]
pub fn as_mut_slices_with_length(&mut self, frames: usize) -> [&mut [T]; CHANNELS] {
let frames = frames.min(self.frames);
unsafe {
core::array::from_fn(|ch_i| {
core::slice::from_raw_parts_mut(*self.offsets.get_unchecked(ch_i), frames)
})
}
}
#[inline]
pub fn as_slices_with_range(&self, range: Range<usize>) -> [&[T]; CHANNELS] {
let start_frame = range.start.min(self.frames);
let frames = range.end.min(self.frames) - start_frame;
unsafe {
core::array::from_fn(|ch_i| {
core::slice::from_raw_parts(
self.offsets.get_unchecked(ch_i).add(start_frame),
frames,
)
})
}
}
#[inline]
pub fn as_mut_slices_with_range(&mut self, range: Range<usize>) -> [&mut [T]; CHANNELS] {
let start_frame = range.start.min(self.frames);
let frames = range.end.min(self.frames) - start_frame;
unsafe {
core::array::from_fn(|ch_i| {
core::slice::from_raw_parts_mut(
self.offsets.get_unchecked(ch_i).add(start_frame),
frames,
)
})
}
}
pub fn raw(&self) -> &[T] {
self.data
}
pub fn raw_mut(&mut self) -> &mut [T] {
&mut self.data[..]
}
pub fn clear(&mut self) {
self.raw_mut().fill(T::default());
}
pub fn clear_frames(&mut self, frames: usize) {
for ch in self.as_mut_slices_with_length(frames) {
ch.fill(T::default());
}
}
}
impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Index<usize>
for ChannelBufferRefMut<'a, T, CHANNELS>
{
type Output = [T];
#[inline(always)]
fn index(&self, index: usize) -> &Self::Output {
self.channel(index).unwrap()
}
}
impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> IndexMut<usize>
for ChannelBufferRefMut<'a, T, CHANNELS>
{
#[inline(always)]
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
self.channel_mut(index).unwrap()
}
}
impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Default
for ChannelBufferRefMut<'a, T, CHANNELS>
{
fn default() -> Self {
Self::empty()
}
}
impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize>
Into<ChannelBufferRef<'a, T, CHANNELS>> for ChannelBufferRefMut<'a, T, CHANNELS>
{
#[inline(always)]
fn into(self) -> ChannelBufferRef<'a, T, CHANNELS> {
ChannelBufferRef {
data: self.data,
offsets: unsafe { core::mem::transmute_copy(&self.offsets) },
frames: self.frames,
}
}
}
impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Into<&'a mut [T]>
for ChannelBufferRefMut<'a, T, CHANNELS>
{
fn into(self) -> &'a mut [T] {
self.data
}
}
unsafe impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Send
for ChannelBufferRefMut<'a, T, CHANNELS>
{
}
unsafe impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Sync
for ChannelBufferRefMut<'a, T, CHANNELS>
{
}