use super::audionode::*;
use super::*;
extern crate alloc;
use alloc::vec::Vec;
use numeric_array::ArrayLength;
pub struct BufferMut<'a>(&'a mut [F32x]);
impl<'a> BufferMut<'a> {
#[inline]
pub fn new(buffer: &'a mut [F32x]) -> Self {
debug_assert!(buffer.len() & (SIMD_LEN - 1) == 0);
Self(buffer)
}
#[inline]
pub fn empty() -> Self {
Self(&mut [])
}
#[inline]
pub fn subset(&mut self, first_channel: usize, channels: usize) -> BufferMut {
debug_assert!(first_channel + channels <= self.channels());
BufferMut::new(
&mut self.0[(first_channel << SIMD_C)..((first_channel + channels) << SIMD_C)],
)
}
#[inline]
pub fn buffer_ref(&mut self) -> BufferRef {
BufferRef::new(self.0)
}
#[inline]
pub fn channels(&self) -> usize {
self.0.len() >> SIMD_C
}
#[inline]
pub fn channel(&self, channel: usize) -> &[F32x] {
debug_assert!(channel < self.channels());
&(self.0)[(channel << SIMD_C)..(channel + 1) << SIMD_C]
}
#[inline]
pub fn channel_mut(&mut self, channel: usize) -> &mut [F32x] {
debug_assert!(channel < self.channels());
&mut (self.0)[(channel << SIMD_C)..(channel + 1) << SIMD_C]
}
#[inline]
pub fn channel_f32(&self, channel: usize) -> &'a [f32] {
debug_assert!(channel < self.channels());
let data = self.channel(channel).as_ptr() as *const f32;
unsafe { core::slice::from_raw_parts(data, MAX_BUFFER_SIZE) }
}
#[inline]
pub fn channel_f32_mut(&mut self, channel: usize) -> &'a mut [f32] {
debug_assert!(channel < self.channels());
let data = self.channel_mut(channel).as_mut_ptr() as *mut f32;
unsafe { core::slice::from_raw_parts_mut(data, MAX_BUFFER_SIZE) }
}
#[inline]
pub fn set(&mut self, channel: usize, i: usize, value: F32x) {
debug_assert!(channel < self.channels());
(self.0)[(channel << SIMD_C) + i] = value;
}
#[inline]
pub fn set_f32(&mut self, channel: usize, i: usize, value: f32) {
debug_assert!(channel < self.channels());
(self.0)[(channel << SIMD_C) + (i >> SIMD_S)].as_array_mut()[i & SIMD_M] = value;
}
#[inline]
pub fn at(&self, channel: usize, i: usize) -> F32x {
debug_assert!(channel < self.channels());
(self.0)[(channel << SIMD_C) + i]
}
#[inline]
pub fn at_mut(&mut self, channel: usize, i: usize) -> &mut F32x {
debug_assert!(channel < self.channels());
&mut (self.0)[(channel << SIMD_C) + i]
}
#[inline]
pub fn at_f32(&self, channel: usize, i: usize) -> f32 {
debug_assert!(channel < self.channels());
(self.0)[(channel << SIMD_C) + (i >> SIMD_S)].as_array_ref()[i & SIMD_M]
}
pub fn add(&mut self, channel: usize, i: usize, value: F32x) {
debug_assert!(channel < self.channels());
(self.0)[(channel << SIMD_C) + i] += value;
}
}
pub struct BufferRef<'a>(&'a [F32x]);
impl<'a> BufferRef<'a> {
#[inline]
pub fn new(buffer: &'a [F32x]) -> Self {
debug_assert!(buffer.len() & (SIMD_LEN - 1) == 0);
Self(buffer)
}
#[inline]
pub fn empty() -> Self {
Self(&[])
}
#[inline]
pub fn subset(&self, first_channel: usize, channels: usize) -> BufferRef {
debug_assert!(first_channel + channels <= self.channels());
BufferRef::new(&self.0[(first_channel << SIMD_C)..((first_channel + channels) << SIMD_C)])
}
#[inline]
pub fn channels(&self) -> usize {
self.0.len() >> SIMD_C
}
#[inline]
pub fn channel(&self, channel: usize) -> &[F32x] {
debug_assert!(channel < self.channels());
&(self.0)[(channel << SIMD_C)..(channel + 1) << SIMD_C]
}
#[inline]
pub fn channel_f32(&self, channel: usize) -> &'a [f32] {
debug_assert!(channel < self.channels());
let data = self.channel(channel).as_ptr() as *const f32;
unsafe { core::slice::from_raw_parts(data, MAX_BUFFER_SIZE) }
}
#[inline]
pub fn at(&self, channel: usize, i: usize) -> F32x {
debug_assert!(channel < self.channels());
(self.0)[(channel << SIMD_C) + i]
}
#[inline]
pub fn at_f32(&self, channel: usize, i: usize) -> f32 {
debug_assert!(channel < self.channels());
(self.0)[(channel << SIMD_C) + (i >> SIMD_S)].as_array_ref()[i & SIMD_M]
}
}
#[derive(Clone, Default)]
pub struct BufferVec {
buffer: Vec<F32x>,
}
impl BufferVec {
pub fn new(channels: usize) -> Self {
let mut buffer = Vec::with_capacity(channels << SIMD_C);
buffer.resize(channels << SIMD_C, F32x::ZERO);
Self { buffer }
}
#[inline]
pub fn channels(&self) -> usize {
self.buffer.len() >> SIMD_C
}
#[inline]
pub fn length(&self) -> usize {
SIMD_LEN
}
#[inline]
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
SIMD_LEN
}
#[inline]
pub fn at(&self, channel: usize, i: usize) -> F32x {
debug_assert!(channel < self.channels());
self.buffer[(channel << SIMD_C) + i]
}
#[inline]
pub fn set(&mut self, channel: usize, i: usize, value: F32x) {
debug_assert!(channel < self.channels());
self.buffer[(channel << SIMD_C) + i] = value;
}
#[inline]
pub fn at_f32(&self, channel: usize, i: usize) -> f32 {
debug_assert!(channel < self.channels());
self.buffer[(channel << SIMD_C) + (i >> SIMD_S)].as_array_ref()[i & SIMD_M]
}
#[inline]
pub fn set_f32(&mut self, channel: usize, i: usize, value: f32) {
debug_assert!(channel < self.channels());
self.buffer[(channel << SIMD_C) + (i >> SIMD_S)].as_array_mut()[i & SIMD_M] = value;
}
#[inline]
pub fn channel(&self, channel: usize) -> &[F32x] {
debug_assert!(channel < self.channels());
&self.buffer[(channel << SIMD_C)..(channel + 1) << SIMD_C]
}
#[inline]
pub fn channel_mut(&mut self, channel: usize) -> &mut [F32x] {
debug_assert!(channel < self.channels());
&mut self.buffer[(channel << SIMD_C)..(channel + 1) << SIMD_C]
}
#[inline]
pub fn channel_f32(&mut self, channel: usize) -> &[f32] {
debug_assert!(channel < self.channels());
let data = self.channel(channel).as_ptr() as *const f32;
unsafe { core::slice::from_raw_parts(data, MAX_BUFFER_SIZE) }
}
#[inline]
pub fn channel_f32_mut(&mut self, channel: usize) -> &mut [f32] {
debug_assert!(channel < self.channels());
let data = self.channel_mut(channel).as_mut_ptr() as *mut f32;
unsafe { core::slice::from_raw_parts_mut(data, MAX_BUFFER_SIZE) }
}
#[inline]
pub fn clear(&mut self) {
self.buffer.fill(F32x::ZERO);
}
pub fn resize(&mut self, channels: usize) {
self.buffer.resize(channels << SIMD_C, F32x::ZERO);
}
#[inline]
pub fn buffer_ref(&self) -> BufferRef {
BufferRef::new(&self.buffer)
}
#[inline]
pub fn buffer_mut(&mut self) -> BufferMut {
BufferMut::new(&mut self.buffer)
}
}
#[repr(C)]
#[derive(Clone, Default)]
pub struct BufferArray<N: ArrayLength> {
array: Frame<[F32x; SIMD_LEN], N>,
}
impl<N: ArrayLength> BufferArray<N> {
#[inline]
pub fn new() -> Self {
Self::default()
}
#[inline]
pub(crate) fn uninitialized() -> Self {
#[allow(clippy::uninit_assumed_init)]
unsafe {
core::mem::MaybeUninit::uninit().assume_init()
}
}
#[inline]
pub fn at(&self, channel: usize, i: usize) -> F32x {
self.array[channel][i]
}
#[inline]
pub fn at_f32(&self, channel: usize, i: usize) -> f32 {
debug_assert!(channel < self.channels());
self.array[channel][i >> SIMD_S].as_array_ref()[i & SIMD_M]
}
#[inline]
pub fn set(&mut self, channel: usize, i: usize, value: F32x) {
debug_assert!(channel < self.channels());
self.array[channel][i] = value;
}
#[inline]
pub fn set_f32(&mut self, channel: usize, i: usize, value: f32) {
debug_assert!(channel < self.channels());
self.array[channel][i >> SIMD_S].as_array_mut()[i & SIMD_M] = value;
}
#[inline]
pub fn channels(&self) -> usize {
N::USIZE
}
#[inline]
pub fn length(&self) -> usize {
SIMD_LEN
}
#[inline]
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
SIMD_LEN
}
#[inline]
pub fn clear(&mut self) {
self.array.fill([F32x::ZERO; SIMD_LEN]);
}
#[inline]
pub fn channel(&self, channel: usize) -> &[F32x] {
unsafe {
&core::slice::from_raw_parts(self.array.as_ptr() as *const F32x, N::USIZE << SIMD_C)
[(channel << SIMD_C)..(channel + 1) << SIMD_C]
}
}
#[inline]
pub fn channel_mut(&mut self, channel: usize) -> &mut [F32x] {
unsafe {
&mut core::slice::from_raw_parts_mut(
self.array.as_mut_ptr() as *mut F32x,
N::USIZE << SIMD_C,
)[(channel << SIMD_C)..(channel + 1) << SIMD_C]
}
}
#[inline]
pub fn channel_f32(&mut self, channel: usize) -> &[f32] {
let data = self.channel(channel).as_ptr() as *const f32;
unsafe { core::slice::from_raw_parts(data, MAX_BUFFER_SIZE) }
}
#[inline]
pub fn channel_f32_mut(&mut self, channel: usize) -> &mut [f32] {
let data = self.channel_mut(channel).as_mut_ptr() as *mut f32;
unsafe { core::slice::from_raw_parts_mut(data, MAX_BUFFER_SIZE) }
}
#[inline]
pub fn buffer_ref(&self) -> BufferRef {
let slice = unsafe {
core::slice::from_raw_parts(self.array.as_ptr() as *const F32x, N::USIZE << SIMD_C)
};
BufferRef::new(slice)
}
#[inline]
pub fn buffer_mut(&mut self) -> BufferMut {
let data = self.array.as_mut_ptr() as *mut F32x;
let slice = unsafe { core::slice::from_raw_parts_mut(data, N::USIZE << SIMD_C) };
BufferMut::new(slice)
}
}