use core::cmp;
use core::fmt;
use core::hash;
use core::ops;
use core::ptr;
use audio_core::{Buf, BufMut, ExactSizeBuf, ResizableBuf, Sample, UniformBuf};
use crate::buf::sequential::{IterChannels, IterChannelsMut};
use crate::channel::{LinearChannel, LinearChannelMut};
use crate::frame::{RawSequential, SequentialFrame, SequentialFramesIter};
#[derive(Default)]
pub struct Sequential<T> {
data: Vec<T>,
channels: usize,
frames: usize,
}
impl<T> Sequential<T> {
pub fn new() -> Self {
Self {
data: Vec::new(),
channels: 0,
frames: 0,
}
}
pub fn with_topology(channels: usize, frames: usize) -> Self
where
T: Sample,
{
Self {
data: vec![T::ZERO; channels * frames],
channels,
frames,
}
}
pub fn from_vec(data: Vec<T>, channels: usize, frames: usize) -> Self {
Self {
data,
channels,
frames,
}
}
pub fn from_frames<const N: usize>(frames: [T; N], channels: usize) -> Self
where
T: Copy,
{
return Self {
data: data_from_frames(frames, channels),
channels,
frames: N,
};
fn data_from_frames<T, const N: usize>(frames: [T; N], channels: usize) -> Vec<T>
where
T: Copy,
{
let mut data = Vec::with_capacity(N * channels);
for _ in 0..channels {
data.extend(frames);
}
data
}
}
pub fn from_array<const F: usize, const C: usize>(channels: [[T; F]; C]) -> Self
where
T: Copy,
{
return Self {
data: data_from_array(channels),
channels: C,
frames: F,
};
#[inline]
fn data_from_array<T, const F: usize, const C: usize>(channels: [[T; F]; C]) -> Vec<T> {
let mut data = Vec::with_capacity(C * F);
for frames in channels {
for f in frames {
data.push(f);
}
}
data
}
}
pub fn into_vec(self) -> Vec<T> {
self.data
}
pub fn as_slice(&self) -> &[T] {
&self.data
}
pub fn as_slice_mut(&mut self) -> &mut [T] {
&mut self.data
}
pub fn capacity(&self) -> usize {
self.data.capacity()
}
pub fn frames(&self) -> usize {
self.frames
}
pub fn channels(&self) -> usize {
self.channels
}
pub fn iter_channels(&self) -> IterChannels<'_, T> {
IterChannels::new(&self.data, self.frames)
}
pub fn iter_channels_mut(&mut self) -> IterChannelsMut<'_, T> {
IterChannelsMut::new(&mut self.data, self.frames)
}
pub fn resize_channels(&mut self, channels: usize)
where
T: Sample,
{
self.resize_inner(self.channels, self.frames, channels, self.frames);
}
pub fn resize_frames(&mut self, frames: usize)
where
T: Sample,
{
self.resize_inner(self.channels, self.frames, self.channels, frames);
}
pub fn get_channel(&self, channel: usize) -> Option<LinearChannel<'_, T>> {
if channel >= self.channels {
return None;
}
let data = self.data.get(channel * self.frames..)?.get(..self.frames)?;
Some(LinearChannel::new(data))
}
pub fn get_mut(&mut self, channel: usize) -> Option<LinearChannelMut<'_, T>> {
if channel >= self.channels {
return None;
}
let data = self
.data
.get_mut(channel * self.frames..)?
.get_mut(..self.frames)?;
Some(LinearChannelMut::new(data))
}
pub fn reserve(&mut self, capacity: usize) {
let old_cap = self.data.capacity();
if old_cap < capacity {
self.data.reserve(capacity - self.data.len());
}
}
fn as_raw(&self) -> RawSequential<T> {
unsafe { RawSequential::new(&self.data, self.channels, self.frames) }
}
fn resize_inner(
&mut self,
from_channels: usize,
from_frames: usize,
to_channels: usize,
to_frames: usize,
) where
T: Sample,
{
if to_channels == 0 || to_frames == 0 {
self.channels = to_channels;
self.frames = to_frames;
return;
} else if self.channels == to_channels && self.frames == to_frames {
return;
}
let old_cap = self.data.capacity();
let new_len = to_channels * to_frames;
if old_cap < new_len {
let additional = new_len - self.data.len();
self.data.reserve(additional);
unsafe {
ptr::write_bytes(
self.data.as_mut_ptr().add(old_cap),
0,
self.data.capacity() - old_cap,
);
}
}
if from_frames < to_frames {
for chan in (0..from_channels).rev() {
unsafe {
let src = self.data.as_mut_ptr().add(chan * from_frames);
let dst = self.data.as_mut_ptr().add(chan * to_frames);
ptr::copy(src, dst, from_frames);
}
}
} else {
for chan in 0..from_channels {
unsafe {
let src = self.data.as_mut_ptr().add(chan * from_frames);
let dst = self.data.as_mut_ptr().add(chan * to_frames);
ptr::copy(src, dst, from_frames);
}
}
}
unsafe {
self.data.set_len(new_len);
}
self.channels = to_channels;
self.frames = to_frames;
}
}
impl<T> fmt::Debug for Sequential<T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.iter_channels()).finish()
}
}
impl<T> cmp::PartialEq for Sequential<T>
where
T: cmp::PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.iter_channels().eq(other.iter_channels())
}
}
impl<T> cmp::Eq for Sequential<T> where T: cmp::Eq {}
impl<T> cmp::PartialOrd for Sequential<T>
where
T: cmp::PartialOrd,
{
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
self.iter_channels().partial_cmp(other.iter_channels())
}
}
impl<T> cmp::Ord for Sequential<T>
where
T: cmp::Ord,
{
fn cmp(&self, other: &Self) -> cmp::Ordering {
self.iter_channels().cmp(other.iter_channels())
}
}
impl<T> hash::Hash for Sequential<T>
where
T: hash::Hash,
{
fn hash<H: hash::Hasher>(&self, state: &mut H) {
for channel in self.iter_channels() {
channel.hash(state);
}
}
}
impl<'a, T> IntoIterator for &'a Sequential<T> {
type IntoIter = IterChannels<'a, T>;
type Item = <Self::IntoIter as Iterator>::Item;
fn into_iter(self) -> Self::IntoIter {
self.iter_channels()
}
}
impl<'a, T> IntoIterator for &'a mut Sequential<T> {
type IntoIter = IterChannelsMut<'a, T>;
type Item = <Self::IntoIter as Iterator>::Item;
fn into_iter(self) -> Self::IntoIter {
self.iter_channels_mut()
}
}
impl<T> ops::Index<usize> for Sequential<T> {
type Output = [T];
fn index(&self, index: usize) -> &Self::Output {
match self.get_channel(index) {
Some(slice) => slice.into_ref(),
None => panic!("index `{}` is not a channel", index),
}
}
}
impl<T> ops::IndexMut<usize> for Sequential<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
match self.get_mut(index) {
Some(slice) => slice.into_mut(),
None => panic!("index `{}` is not a channel", index,),
}
}
}
impl<T> ExactSizeBuf for Sequential<T>
where
T: Copy,
{
fn frames(&self) -> usize {
self.frames
}
}
impl<T> Buf for Sequential<T>
where
T: Copy,
{
type Sample = T;
type Channel<'this>
= LinearChannel<'this, Self::Sample>
where
Self::Sample: 'this;
type IterChannels<'this>
= IterChannels<'this, T>
where
Self: 'this;
fn frames_hint(&self) -> Option<usize> {
Some(self.frames)
}
fn channels(&self) -> usize {
(*self).channels()
}
fn get_channel(&self, channel: usize) -> Option<Self::Channel<'_>> {
(*self).get_channel(channel)
}
fn iter_channels(&self) -> Self::IterChannels<'_> {
(*self).iter_channels()
}
}
impl<T> UniformBuf for Sequential<T>
where
T: Copy,
{
type Frame<'this>
= SequentialFrame<'this, T>
where
Self: 'this;
type IterFrames<'this>
= SequentialFramesIter<'this, T>
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> ResizableBuf for Sequential<T>
where
T: Sample,
{
fn try_reserve(&mut self, capacity: usize) -> bool {
self.reserve(capacity);
true
}
fn resize_frames(&mut self, frames: usize) {
Self::resize_frames(self, frames);
}
fn resize_topology(&mut self, channels: usize, frames: usize) {
Self::resize_frames(self, frames);
Self::resize_channels(self, channels);
}
}
impl<T> BufMut for Sequential<T>
where
T: Copy,
{
type ChannelMut<'this>
= LinearChannelMut<'this, Self::Sample>
where
Self: 'this;
type IterChannelsMut<'this>
= IterChannelsMut<'this, T>
where
Self: 'this;
fn get_channel_mut(&mut self, channel: usize) -> Option<Self::ChannelMut<'_>> {
(*self).get_mut(channel)
}
fn copy_channel(&mut self, from: usize, to: usize) {
unsafe {
crate::utils::copy_channels_sequential(
ptr::NonNull::new_unchecked(self.data.as_mut_ptr()),
self.channels,
self.frames,
from,
to,
)
}
}
fn iter_channels_mut(&mut self) -> Self::IterChannelsMut<'_> {
(*self).iter_channels_mut()
}
#[inline]
fn fill(&mut self, value: T)
where
T: Copy,
{
self.data.fill(value);
}
}