use crate::{AudioChannels, ConstInit, PcmSample, PcmSpec};
use crate::{PhantomData, is, whilst};
#[doc = crate::_tags!(audio data)]
#[doc = crate::_doc_meta!{
location("media/audio"),
#[cfg(target_pointer_width = "32")]
test_size_of(PcmBuf_f64: PcmBuf<i32, &[i32]> = 16|128),
#[cfg(target_pointer_width = "32")]
test_size_of(PcmBuf_i32_planar: PcmBuf<f64, &[&[f64]]> = 16|128),
#[cfg(target_pointer_width = "64")]
test_size_of(PcmBuf_f64: PcmBuf<i32, &[i32]> = 24|192),
#[cfg(target_pointer_width = "64")]
test_size_of(PcmBuf_i32_planar: PcmBuf<f64, &[&[f64]]> = 24|192),
}]
#[must_use]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct PcmBuf<T, B> {
pub data: B,
pub spec: PcmSpec,
_sample: PhantomData<fn() -> T>,
}
impl<T> ConstInit for PcmBuf<T, &[T]> {
const INIT: Self = Self::new(&[], PcmSpec::INIT);
}
impl<T> ConstInit for PcmBuf<T, &mut [T]> {
const INIT: Self = Self::new(&mut [], PcmSpec::INIT);
}
impl<T> ConstInit for PcmBuf<T, &[&[T]]> {
const INIT: Self = Self::new(&[], PcmSpec::INIT);
}
impl<T> ConstInit for PcmBuf<T, &mut [&mut [T]]> {
const INIT: Self = Self::new(&mut [], PcmSpec::INIT);
}
#[rustfmt::skip]
impl<T, B> PcmBuf<T, B> {
pub const fn new(data: B, spec: PcmSpec) -> Self { Self { data, spec, _sample: PhantomData } }
pub const fn from_parts(data: B, format: PcmSample, channels: AudioChannels, sample_rate: u32)
-> Self { Self::new(data, PcmSpec::new(format, channels, sample_rate)) }
pub const fn sample(&self) -> PcmSample { self.spec.sample }
#[must_use]
pub const fn channels(&self) -> AudioChannels { self.spec.channels }
#[must_use]
pub const fn channel_count(&self) -> usize { self.spec.channel_count() }
#[must_use]
pub const fn sample_rate(&self) -> u32 { self.spec.sample_rate }
}
impl<'a, T> PcmBuf<T, &'a [T]> {
pub const fn from_interleaved(data: &'a [T], spec: PcmSpec) -> Self {
Self::new(data, spec)
}
pub const fn data(&self) -> &'a [T] {
self.data
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.data.is_empty()
}
#[must_use]
pub const fn samples_len(&self) -> usize {
self.data.len()
}
#[must_use]
pub const fn frames(&self) -> Option<usize> {
let len = self.samples_len();
let channels = self.channel_count();
if channels == 0 || len % channels != 0 { None } else { Some(len / channels) }
}
#[must_use]
pub const fn has_complete_frames(&self) -> bool {
self.frames().is_some()
}
pub fn visit_samples<F, R>(&self, f: F) -> R
where
for<'v> F: FnOnce(&'v [T]) -> R,
{
f(self.data)
}
pub fn visit_each<F>(&self, f: F)
where
for<'v> F: Fn(&'v T),
{
for sample in self.data.iter() {
f(sample);
}
}
pub fn visit_each_frame<F>(&self, f: F)
where
for<'v> F: Fn(usize, &'v [T]),
{
let channels = self.channel_count();
is! { channels == 0, return }
for (frame, samples) in self.data.chunks_exact(channels).enumerate() {
f(frame, samples);
}
}
}
impl<'a, T> PcmBuf<T, &'a mut [T]> {
pub const fn from_interleaved_mut(data: &'a mut [T], spec: PcmSpec) -> Self {
Self::new(data, spec)
}
pub const fn data(&self) -> &[T] {
&*self.data
}
pub const fn data_mut(&mut self) -> &mut [T] {
self.data
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.data.is_empty()
}
#[must_use]
pub const fn samples_len(&self) -> usize {
self.data.len()
}
#[must_use]
pub const fn frames(&self) -> Option<usize> {
let len = self.samples_len();
let channels = self.channel_count();
if channels == 0 || len % channels != 0 { None } else { Some(len / channels) }
}
#[must_use]
pub const fn has_complete_frames(&self) -> bool {
self.frames().is_some()
}
pub fn visit_samples_mut<F, R>(&mut self, f: F) -> R
where
for<'v> F: FnOnce(&'v mut [T]) -> R,
{
f(self.data)
}
pub fn visit_each_mut<F>(&mut self, f: F)
where
for<'v> F: Fn(&'v mut T),
{
for sample in self.data.iter_mut() {
f(sample);
}
}
pub fn visit_each_frame_mut<F>(&mut self, f: F)
where
for<'v> F: Fn(usize, &'v mut [T]),
{
let channels = self.channel_count();
is! { channels == 0, return }
for (frame, samples) in self.data.chunks_exact_mut(channels).enumerate() {
f(frame, samples);
}
}
}
impl<'a, T> PcmBuf<T, &'a [&'a [T]]> {
pub const fn from_planar(data: &'a [&'a [T]], spec: PcmSpec) -> Self {
Self::new(data, spec)
}
pub const fn planes(&self) -> &'a [&'a [T]] {
self.data
}
#[must_use]
pub const fn planes_len(&self) -> usize {
self.data.len()
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.data.is_empty()
}
#[must_use]
pub const fn frames(&self) -> Option<usize> {
let planes = self.data.len();
is! { planes != self.channel_count(), return None }
is! { planes == 0, return Some(0) }
let frames = self.data[0].len();
whilst! { i in 1..planes; {
is! { self.data[i].len() != frames, return None }
}}
Some(frames)
}
#[must_use]
pub const fn has_complete_frames(&self) -> bool {
self.frames().is_some()
}
pub fn visit_planes<F, R>(&self, f: F) -> R
where
for<'v> F: FnOnce(&'v [&'a [T]]) -> R,
{
f(self.data)
}
pub fn visit_each_plane<F>(&self, f: F)
where
for<'v> F: Fn(usize, &'v [T]),
{
for (i, plane) in self.data.iter().enumerate() {
f(i, plane);
}
}
}
impl<'a, 'p, T> PcmBuf<T, &'a mut [&'p mut [T]]> {
pub const fn from_planar_mut(data: &'a mut [&'p mut [T]], spec: PcmSpec) -> Self {
Self::new(data, spec)
}
pub const fn planes(&self) -> &[&'p mut [T]] {
&*self.data
}
pub const fn planes_mut(&mut self) -> &mut [&'p mut [T]] {
&mut *self.data
}
pub fn plane(&self, index: usize) -> Option<&[T]> {
self.data.get(index).map(|plane| &**plane)
}
pub fn plane_mut(&mut self, index: usize) -> Option<&mut [T]> {
self.data.get_mut(index).map(|plane| &mut **plane)
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.data.is_empty()
}
#[must_use]
pub const fn planes_len(&self) -> usize {
self.data.len()
}
#[must_use]
pub const fn frames(&self) -> Option<usize> {
let planes = self.data.len();
is! { planes != self.channel_count(), return None }
is! { planes == 0, return Some(0) }
let frames = self.data[0].len();
whilst! { i in 1..planes; {
is! { self.data[i].len() != frames, return None }
}}
Some(frames)
}
#[must_use]
pub const fn has_complete_frames(&self) -> bool {
self.frames().is_some()
}
pub fn visit_planes_mut<F, R>(&mut self, f: F) -> R
where
for<'v> F: FnOnce(&'v mut [&'p mut [T]]) -> R,
{
f(self.data)
}
pub fn visit_each_plane_mut<F>(&mut self, f: F)
where
for<'v> F: Fn(usize, &'v mut [T]),
{
for (i, plane) in self.data.iter_mut().enumerate() {
f(i, plane);
}
}
pub fn visit_each_mut<F>(&mut self, f: F)
where
for<'v> F: Fn(usize, usize, &'v mut T),
{
for (channel, plane) in self.data.iter_mut().enumerate() {
for (frame, sample) in plane.iter_mut().enumerate() {
f(channel, frame, sample);
}
}
}
}