use core::num::NonZeroUsize;
use core::ops::{Index, IndexMut, Range};
use arrayvec::ArrayVec;
#[derive(Debug, Clone)]
pub struct VarChannelBufferRef<'a, T: Clone + Copy + Default + Sized, const MAX_CHANNELS: usize> {
data: &'a [T],
offsets: ArrayVec<*const T, MAX_CHANNELS>,
frames: usize,
}
impl<'a, T: Clone + Copy + Default + Sized, const MAX_CHANNELS: usize>
VarChannelBufferRef<'a, T, MAX_CHANNELS>
{
const _COMPILE_TIME_ASSERTS: () = {
assert!(MAX_CHANNELS > 0);
};
#[inline(always)]
pub(crate) unsafe fn from_raw(
data: &'a [T],
offsets: ArrayVec<*const T, MAX_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 mut offsets = ArrayVec::new();
offsets.push(data.as_ptr());
Self {
data,
offsets,
frames: 0,
}
}
pub fn new(data: &'a [T], channels: NonZeroUsize) -> Self {
let _ = Self::_COMPILE_TIME_ASSERTS;
assert!(channels.get() <= MAX_CHANNELS);
let frames = data.len() / channels.get();
let mut offsets = ArrayVec::new();
unsafe {
for ch_i in 0..channels.get() {
offsets.push_unchecked(data.as_ptr().add(ch_i * frames));
}
}
Self {
data,
offsets,
frames,
}
}
pub unsafe fn new_unchecked(data: &'a [T], frames: usize, channels: NonZeroUsize) -> Self {
let _ = Self::_COMPILE_TIME_ASSERTS;
let mut offsets = ArrayVec::new();
for ch_i in 0..channels.get() {
offsets.push_unchecked(data.as_ptr().add(ch_i * frames));
}
Self {
data,
offsets,
frames,
}
}
pub fn channels(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.offsets.len()) }
}
pub fn frames(&self) -> usize {
self.frames
}
#[inline(always)]
pub fn channel(&self, index: usize) -> Option<&[T]> {
if index < self.offsets.len() {
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) -> ArrayVec<&[T], MAX_CHANNELS> {
let mut v = ArrayVec::new();
unsafe {
for ptr in self.offsets.iter() {
v.push_unchecked(core::slice::from_raw_parts(*ptr, self.frames));
}
}
v
}
#[inline]
pub fn as_slices_with_length(&self, frames: usize) -> ArrayVec<&[T], MAX_CHANNELS> {
let frames = frames.min(self.frames);
let mut v = ArrayVec::new();
unsafe {
for ptr in self.offsets.iter() {
v.push_unchecked(core::slice::from_raw_parts(*ptr, frames));
}
}
v
}
#[inline]
pub fn as_slices_with_range(&self, range: Range<usize>) -> ArrayVec<&[T], MAX_CHANNELS> {
let start_frame = range.start.min(self.frames);
let frames = range.end.min(self.frames) - start_frame;
let mut v = ArrayVec::new();
unsafe {
for ptr in self.offsets.iter() {
v.push_unchecked(core::slice::from_raw_parts(ptr.add(start_frame), frames));
}
}
v
}
pub fn raw(&self) -> &[T] {
self.data
}
}
impl<'a, T: Clone + Copy + Default + Sized, const MAX_CHANNELS: usize> Index<usize>
for VarChannelBufferRef<'a, T, MAX_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 MAX_CHANNELS: usize> Default
for VarChannelBufferRef<'a, T, MAX_CHANNELS>
{
fn default() -> Self {
Self::empty()
}
}
impl<'a, T: Clone + Copy + Default + Sized, const MAX_CHANNELS: usize> Into<&'a [T]>
for VarChannelBufferRefMut<'a, T, MAX_CHANNELS>
{
fn into(self) -> &'a [T] {
self.data
}
}
unsafe impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Send
for VarChannelBufferRef<'a, T, CHANNELS>
{
}
unsafe impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Sync
for VarChannelBufferRef<'a, T, CHANNELS>
{
}
#[derive(Debug)]
pub struct VarChannelBufferRefMut<'a, T: Clone + Copy + Default + Sized, const MAX_CHANNELS: usize>
{
data: &'a mut [T],
offsets: ArrayVec<*mut T, MAX_CHANNELS>,
frames: usize,
}
impl<'a, T: Clone + Copy + Default + Sized, const MAX_CHANNELS: usize>
VarChannelBufferRefMut<'a, T, MAX_CHANNELS>
{
const _COMPILE_TIME_ASSERTS: () = {
assert!(MAX_CHANNELS > 0);
};
#[inline(always)]
pub(crate) unsafe fn from_raw(
data: &'a mut [T],
offsets: ArrayVec<*mut T, MAX_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 mut offsets = ArrayVec::new();
offsets.push(data.as_mut_ptr());
Self {
data,
offsets,
frames: 0,
}
}
pub fn new(data: &'a mut [T], channels: NonZeroUsize) -> Self {
let _ = Self::_COMPILE_TIME_ASSERTS;
assert!(channels.get() <= MAX_CHANNELS);
let frames = data.len() / channels.get();
let mut offsets = ArrayVec::new();
unsafe {
for ch_i in 0..channels.get() {
offsets.push_unchecked(data.as_mut_ptr().add(ch_i * frames));
}
}
Self {
data,
offsets,
frames,
}
}
pub unsafe fn new_unchecked(data: &'a mut [T], frames: usize, channels: NonZeroUsize) -> Self {
let _ = Self::_COMPILE_TIME_ASSERTS;
let mut offsets = ArrayVec::new();
for ch_i in 0..channels.get() {
offsets.push_unchecked(data.as_mut_ptr().add(ch_i * frames));
}
Self {
data,
offsets,
frames,
}
}
pub fn channels(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.offsets.len()) }
}
pub fn frames(&self) -> usize {
self.frames
}
#[inline(always)]
pub fn channel(&self, index: usize) -> Option<&[T]> {
if index < self.offsets.len() {
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 < self.offsets.len() {
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) -> ArrayVec<&[T], MAX_CHANNELS> {
let mut v = ArrayVec::new();
unsafe {
for ptr in self.offsets.iter() {
v.push_unchecked(core::slice::from_raw_parts(*ptr, self.frames));
}
}
v
}
#[inline]
pub fn as_mut_slices(&mut self) -> ArrayVec<&mut [T], MAX_CHANNELS> {
let mut v = ArrayVec::new();
unsafe {
for ptr in self.offsets.iter() {
v.push_unchecked(core::slice::from_raw_parts_mut(*ptr, self.frames));
}
}
v
}
#[inline]
pub fn as_slices_with_length(&self, frames: usize) -> ArrayVec<&[T], MAX_CHANNELS> {
let frames = frames.min(self.frames);
let mut v = ArrayVec::new();
unsafe {
for ptr in self.offsets.iter() {
v.push_unchecked(core::slice::from_raw_parts(*ptr, frames));
}
}
v
}
#[inline]
pub fn as_mut_slices_with_length(&mut self, frames: usize) -> ArrayVec<&mut [T], MAX_CHANNELS> {
let frames = frames.min(self.frames);
let mut v = ArrayVec::new();
unsafe {
for ptr in self.offsets.iter() {
v.push_unchecked(core::slice::from_raw_parts_mut(*ptr, frames));
}
}
v
}
#[inline]
pub fn as_slices_with_range(&self, range: Range<usize>) -> ArrayVec<&[T], MAX_CHANNELS> {
let start_frame = range.start.min(self.frames);
let frames = range.end.min(self.frames) - start_frame;
let mut v = ArrayVec::new();
unsafe {
for ptr in self.offsets.iter() {
v.push_unchecked(core::slice::from_raw_parts(ptr.add(start_frame), frames));
}
}
v
}
#[inline]
pub fn as_mut_slices_with_range(
&mut self,
range: Range<usize>,
) -> ArrayVec<&mut [T], MAX_CHANNELS> {
let start_frame = range.start.min(self.frames);
let frames = range.end.min(self.frames) - start_frame;
let mut v = ArrayVec::new();
unsafe {
for ptr in self.offsets.iter_mut() {
v.push_unchecked(core::slice::from_raw_parts_mut(
ptr.add(start_frame),
frames,
));
}
}
v
}
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 MAX_CHANNELS: usize> Index<usize>
for VarChannelBufferRefMut<'a, T, MAX_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 MAX_CHANNELS: usize> IndexMut<usize>
for VarChannelBufferRefMut<'a, T, MAX_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 MAX_CHANNELS: usize> Default
for VarChannelBufferRefMut<'a, T, MAX_CHANNELS>
{
fn default() -> Self {
Self::empty()
}
}
impl<'a, T: Clone + Copy + Default + Sized, const MAX_CHANNELS: usize>
Into<VarChannelBufferRef<'a, T, MAX_CHANNELS>> for VarChannelBufferRefMut<'a, T, MAX_CHANNELS>
{
#[inline(always)]
fn into(self) -> VarChannelBufferRef<'a, T, MAX_CHANNELS> {
VarChannelBufferRef {
data: self.data,
offsets: unsafe { core::mem::transmute_copy(&self.offsets) },
frames: self.frames,
}
}
}
impl<'a, T: Clone + Copy + Default + Sized, const MAX_CHANNELS: usize> Into<&'a mut [T]>
for VarChannelBufferRefMut<'a, T, MAX_CHANNELS>
{
fn into(self) -> &'a mut [T] {
self.data
}
}
unsafe impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Send
for VarChannelBufferRefMut<'a, T, CHANNELS>
{
}
unsafe impl<'a, T: Clone + Copy + Default + Sized, const CHANNELS: usize> Sync
for VarChannelBufferRefMut<'a, T, CHANNELS>
{
}