use core::num::{NonZeroU32, NonZeroUsize};
use std::ops::{Deref, DerefMut};
use non_empty_slice::NonEmptySlice;
use crate::error::AudioSampleResult;
use crate::repr::{AudioSamples, SampleRate};
use crate::traits::StandardSample;
pub struct FixedSizeAudioSamples<T, const N: usize>
where
T: StandardSample,
{
samples: AudioSamples<'static, T>,
}
impl<T: StandardSample, const N: usize> FixedSizeAudioSamples<T, N> {
#[inline]
#[must_use]
pub fn zeros(sample_rate: SampleRate) -> Self {
const { assert!(N > 0, "N must be greater than 0") };
let len = unsafe { NonZeroUsize::new_unchecked(N) };
Self {
samples: AudioSamples::zeros_mono(len, sample_rate),
}
}
#[inline]
pub fn from_1d<D: AsRef<NonEmptySlice<T>>>(
data: D,
sample_rate: SampleRate,
) -> AudioSampleResult<Self> {
let samples = AudioSamples::from_mono_vec(data.as_ref().to_non_empty_vec(), sample_rate);
Ok(Self { samples })
}
#[inline]
#[must_use]
pub const fn capacity(&self) -> usize {
N
}
#[inline]
#[must_use]
pub fn samples(&self) -> &AudioSamples<'static, T> {
&self.samples
}
#[inline]
pub fn samples_mut(&mut self) -> &mut AudioSamples<'static, T> {
&mut self.samples
}
#[inline]
pub fn swap(&mut self, other: &mut Self) {
std::mem::swap(&mut self.samples, &mut other.samples);
}
}
impl<T: StandardSample, const N: usize> Deref for FixedSizeAudioSamples<T, N> {
type Target = AudioSamples<'static, T>;
fn deref(&self) -> &Self::Target {
&self.samples
}
}
impl<T: StandardSample, const N: usize> DerefMut for FixedSizeAudioSamples<T, N> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.samples
}
}
impl<T: StandardSample, const N: usize> AsRef<AudioSamples<'static, T>>
for FixedSizeAudioSamples<T, N>
{
fn as_ref(&self) -> &AudioSamples<'static, T> {
&self.samples
}
}
impl<T: StandardSample, const N: usize> AsMut<AudioSamples<'static, T>>
for FixedSizeAudioSamples<T, N>
{
fn as_mut(&mut self) -> &mut AudioSamples<'static, T> {
&mut self.samples
}
}
pub struct FixedSizeMultiChannelAudioSamples<T, const N: usize, const C: usize>
where
T: StandardSample,
{
samples: AudioSamples<'static, T>,
}
impl<T: StandardSample, const N: usize, const C: usize> FixedSizeMultiChannelAudioSamples<T, N, C> {
#[inline]
#[must_use]
pub fn zeros(sample_rate: SampleRate) -> Self {
const { assert!(N > 0, "N (frames per channel) must be greater than 0") };
const { assert!(C > 0, "C (channel count) must be greater than 0") };
let frames = unsafe { NonZeroUsize::new_unchecked(N) };
let channels = unsafe { NonZeroU32::new_unchecked(C as u32) };
Self {
samples: AudioSamples::zeros_multi_channel(channels, frames, sample_rate),
}
}
#[inline]
#[must_use]
pub const fn frames(&self) -> usize {
N
}
#[inline]
#[must_use]
pub const fn channels(&self) -> usize {
C
}
#[inline]
#[must_use]
pub const fn capacity(&self) -> usize {
N * C
}
#[inline]
#[must_use]
pub fn samples(&self) -> &AudioSamples<'static, T> {
&self.samples
}
#[inline]
pub fn samples_mut(&mut self) -> &mut AudioSamples<'static, T> {
&mut self.samples
}
#[inline]
pub fn swap(&mut self, other: &mut Self) {
std::mem::swap(&mut self.samples, &mut other.samples);
}
}
impl<T: StandardSample, const N: usize, const C: usize> Deref
for FixedSizeMultiChannelAudioSamples<T, N, C>
{
type Target = AudioSamples<'static, T>;
fn deref(&self) -> &Self::Target {
&self.samples
}
}
impl<T: StandardSample, const N: usize, const C: usize> DerefMut
for FixedSizeMultiChannelAudioSamples<T, N, C>
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.samples
}
}
impl<T: StandardSample, const N: usize, const C: usize> AsRef<AudioSamples<'static, T>>
for FixedSizeMultiChannelAudioSamples<T, N, C>
{
fn as_ref(&self) -> &AudioSamples<'static, T> {
&self.samples
}
}
impl<T: StandardSample, const N: usize, const C: usize> AsMut<AudioSamples<'static, T>>
for FixedSizeMultiChannelAudioSamples<T, N, C>
{
fn as_mut(&mut self) -> &mut AudioSamples<'static, T> {
&mut self.samples
}
}