use audio_core::{Buf, BufMut, ExactSizeBuf, UniformBuf};
use crate::buf::sequential::{IterChannels, IterChannelsMut};
use crate::channel::{LinearChannel, LinearChannelMut};
use crate::frame::{RawSequential, SequentialFrame, SequentialFramesIter};
use crate::slice::{Slice, SliceMut};
pub struct Sequential<T> {
value: T,
channels: usize,
frames: usize,
}
impl<T> Sequential<T>
where
T: Slice,
{
pub(super) fn new(value: T, channels: usize) -> Self {
assert!(
channels != 0 && value.as_ref().len() % channels == 0,
"slice provided {} doesn't match channel configuration {}",
value.as_ref().len(),
channels,
);
let frames = value.as_ref().len() / channels;
Self {
value,
channels,
frames,
}
}
#[inline]
pub fn into_inner(self) -> T {
self.value
}
#[inline]
pub fn iter(&self) -> IterChannels<'_, T::Item> {
IterChannels::new(self.value.as_ref(), self.frames)
}
#[inline]
fn as_raw(&self) -> RawSequential<T::Item>
where
T: Slice,
{
unsafe { RawSequential::new(self.value.as_ref(), self.channels, self.frames) }
}
}
impl<T> Sequential<T>
where
T: SliceMut,
{
#[inline]
pub fn iter_mut(&mut self) -> IterChannelsMut<'_, T::Item> {
IterChannelsMut::new(self.value.as_mut(), self.frames)
}
}
impl<T> Buf for Sequential<T>
where
T: Slice,
{
type Sample = T::Item;
type Channel<'this>
= LinearChannel<'this, Self::Sample>
where
Self: 'this;
type IterChannels<'this>
= IterChannels<'this, Self::Sample>
where
Self: 'this;
#[inline]
fn frames_hint(&self) -> Option<usize> {
Some(self.frames)
}
#[inline]
fn channels(&self) -> usize {
self.channels
}
fn get_channel(&self, channel: usize) -> Option<Self::Channel<'_>> {
let value = self
.value
.as_ref()
.get(channel.saturating_mul(self.frames)..)?
.get(..self.frames)
.unwrap_or_default();
Some(LinearChannel::new(value))
}
#[inline]
fn iter_channels(&self) -> Self::IterChannels<'_> {
(*self).iter()
}
}
impl<T> UniformBuf for Sequential<T>
where
T: Slice,
{
type Frame<'this>
= SequentialFrame<'this, T::Item>
where
Self: 'this;
type IterFrames<'this>
= SequentialFramesIter<'this, T::Item>
where
Self: 'this;
#[inline]
fn get_frame(&self, frame: usize) -> Option<Self::Frame<'_>> {
if frame >= self.frames {
return None;
}
Some(SequentialFrame::new(frame, self.as_raw()))
}
#[inline]
fn iter_frames(&self) -> Self::IterFrames<'_> {
SequentialFramesIter::new(0, self.as_raw())
}
}
impl<T> ExactSizeBuf for Sequential<T>
where
T: Slice,
{
#[inline]
fn frames(&self) -> usize {
self.value.as_ref().len() / self.channels
}
}
impl<T> BufMut for Sequential<T>
where
T: SliceMut,
{
type ChannelMut<'a>
= LinearChannelMut<'a, Self::Sample>
where
Self: 'a;
type IterChannelsMut<'a>
= IterChannelsMut<'a, Self::Sample>
where
Self: 'a;
fn get_channel_mut(&mut self, channel: usize) -> Option<Self::ChannelMut<'_>> {
let value = self
.value
.as_mut()
.get_mut(channel.saturating_mul(self.frames)..)?;
let value = value.get_mut(..self.frames).unwrap_or_default();
Some(LinearChannelMut::new(value))
}
fn copy_channel(&mut self, from: usize, to: usize) {
unsafe {
crate::utils::copy_channels_sequential(
self.value.as_mut_ptr(),
self.channels,
self.frames,
from,
to,
);
}
}
#[inline]
fn iter_channels_mut(&mut self) -> Self::IterChannelsMut<'_> {
(*self).iter_mut()
}
}