use crate::{
chan::{Ch16, Ch32, Ch64, Ch8},
math, Frame, Resampler, Sink, Stream,
};
use alloc::{
boxed::Box,
collections::{
vec_deque::{Iter, IterMut},
VecDeque,
},
vec,
vec::Vec,
};
use core::{
fmt::Debug,
iter::Cloned,
mem::{size_of, swap},
ops::RangeBounds,
slice::{from_raw_parts_mut, SliceIndex},
};
#[derive(Debug)]
pub struct Audio<F: Frame> {
s_rate: f64,
frames: VecDeque<F>,
}
impl<F: Frame> Audio<F> {
pub fn get(&self, index: usize) -> Option<F> {
self.frames.get(index).cloned()
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut F> {
self.frames.get_mut(index)
}
pub fn as_slice(&mut self) -> &mut [F] {
self.frames.make_contiguous()
}
pub fn iter(&self) -> Iter<'_, F> {
self.frames.iter()
}
pub fn iter_mut(&mut self) -> IterMut<'_, F> {
self.frames.iter_mut()
}
pub fn with_frame<R: Into<f64>>(s_rate: R, len: usize, frame: F) -> Self {
let s_rate = s_rate.into();
let frames = vec![frame; len].into();
Audio { s_rate, frames }
}
pub fn with_silence<R: Into<f64>>(s_rate: R, len: usize) -> Self {
Self::with_frame(s_rate, len, F::default())
}
pub fn with_stream<S, R, M>(s_rate: R, src: M) -> Self
where
F::Chan: From<S::Chan>,
R: Into<f64>,
M: Stream<S>,
S: Frame,
{
let s_rate = s_rate.into();
let mut audio = Self::with_frames::<[F; 0], f64>(s_rate, []);
audio.extend(src);
audio
}
pub fn with_frames<B: Into<Box<[F]>>, R: Into<f64>>(
s_rate: R,
frames: B,
) -> Self {
let s_rate = s_rate.into();
let frames: Vec<F> = frames.into().into();
Audio {
s_rate,
frames: frames.into(),
}
}
#[allow(unsafe_code)]
pub fn with_i8_buffer<B, R>(s_rate: R, buffer: B) -> Self
where
B: Into<Box<[i8]>>,
F: Frame<Chan = Ch8>,
R: Into<f64>,
{
let s_rate = s_rate.into();
let buffer: Box<[i8]> = buffer.into();
let len = buffer.len() / size_of::<F>();
assert_eq!(0, buffer.len() % size_of::<F>());
let slice = Box::<[i8]>::into_raw(buffer);
let frames: Box<[F]> = unsafe {
let ptr = (*slice).as_mut_ptr() as *mut F;
Box::from_raw(from_raw_parts_mut(ptr, len))
};
let frames: Vec<F> = frames.into();
Audio {
s_rate,
frames: frames.into(),
}
}
#[allow(unsafe_code)]
pub fn with_i16_buffer<B, R>(s_rate: R, buffer: B) -> Self
where
B: Into<Box<[i16]>>,
F: Frame<Chan = Ch16>,
R: Into<f64>,
{
let s_rate = s_rate.into();
let buffer: Box<[i16]> = buffer.into();
let bytes = buffer.len() * size_of::<i16>();
let len = bytes / size_of::<F>();
assert_eq!(0, bytes % size_of::<F>());
let slice = Box::<[i16]>::into_raw(buffer);
let frames: Box<[F]> = unsafe {
let ptr = (*slice).as_mut_ptr() as *mut F;
Box::from_raw(from_raw_parts_mut(ptr, len))
};
let frames: Vec<F> = frames.into();
Audio {
s_rate,
frames: frames.into(),
}
}
#[allow(unsafe_code)]
pub fn with_f32_buffer<B, R>(s_rate: R, buffer: B) -> Self
where
B: Into<Box<[f32]>>,
F: Frame<Chan = Ch32>,
R: Into<f64>,
{
let s_rate = s_rate.into();
let buffer: Box<[f32]> = buffer.into();
let bytes = buffer.len() * size_of::<f32>();
let len = bytes / size_of::<F>();
assert_eq!(0, bytes % size_of::<F>());
let slice = Box::<[f32]>::into_raw(buffer);
let frames: Box<[F]> = unsafe {
let ptr = (*slice).as_mut_ptr() as *mut F;
Box::from_raw(from_raw_parts_mut(ptr, len))
};
let frames: Vec<F> = frames.into();
Audio {
s_rate,
frames: frames.into(),
}
}
#[allow(unsafe_code)]
pub fn with_f64_buffer<B, R>(s_rate: R, buffer: B) -> Self
where
B: Into<Box<[f64]>>,
F: Frame<Chan = Ch64>,
R: Into<f64>,
{
let s_rate = s_rate.into();
let buffer: Box<[f64]> = buffer.into();
let bytes = buffer.len() * size_of::<f64>();
let len = bytes / size_of::<F>();
assert_eq!(0, bytes % size_of::<F>());
let slice = Box::<[f64]>::into_raw(buffer);
let frames: Box<[F]> = unsafe {
let ptr = (*slice).as_mut_ptr() as *mut F;
Box::from_raw(from_raw_parts_mut(ptr, len))
};
let frames: Vec<F> = frames.into();
Audio {
s_rate,
frames: frames.into(),
}
}
pub fn len(&self) -> usize {
self.frames.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn sample_rate(&self) -> f64 {
self.s_rate
}
pub fn sink<
'a,
R: 'a + RangeBounds<usize> + SliceIndex<[F], Output = [F]>,
>(
&'a mut self,
reg: R,
) -> impl Sink<F> + '_ {
AudioSink {
s_rate: self.sample_rate(),
frames: &mut self.as_slice()[reg],
resampler: Resampler::default(),
}
}
pub fn drain(&mut self) -> impl Stream<F> + '_ {
AudioDrain {
cursor: 0,
buffer: self,
}
}
pub fn extend<G: Frame, M: Stream<G>>(&mut self, stream: M)
where
F::Chan: From<G::Chan>,
{
let mut temp_move = Self::with_frames::<[F; 0], f64>(0.0, []);
swap(self, &mut temp_move);
*self = temp_move.extend_internal(stream);
}
fn extend_internal<G: Frame, M: Stream<G>>(self, stream: M) -> Self
where
F::Chan: From<G::Chan>,
{
let s_rate = self.s_rate;
let srclen = stream
.len()
.expect("Audio::extend() called on infinite stream.");
let dstlen = if let Some(src_sr) = stream.sample_rate() {
math::ceil(s_rate * srclen as f64 / src_sr) as usize
} else {
srclen
};
let audio: Box<[F]> = self.into();
let mut audio: Vec<F> = audio.into();
let orig_len = audio.len();
audio.resize_with(orig_len + dstlen, Default::default);
let mut audio = Self::with_frames(s_rate, audio);
let mut sink = audio.sink(orig_len..);
sink.stream(stream);
sink.flush();
audio
}
}
impl<F: Frame<Chan = Ch8>> Audio<F> {
pub fn as_i8_slice(&mut self) -> &mut [i8] {
let frames = self.frames.make_contiguous();
unsafe {
let (prefix, v, suffix) = frames.align_to_mut::<i8>();
debug_assert!(prefix.is_empty());
debug_assert!(suffix.is_empty());
v
}
}
}
impl<F: Frame<Chan = Ch16>> Audio<F> {
pub fn as_i16_slice(&mut self) -> &mut [i16] {
let frames = self.frames.make_contiguous();
unsafe {
let (prefix, v, suffix) = frames.align_to_mut::<i16>();
debug_assert!(prefix.is_empty());
debug_assert!(suffix.is_empty());
v
}
}
}
impl<S: Frame<Chan = Ch32>> Audio<S> {
pub fn as_f32_slice(&mut self) -> &mut [f32] {
let frames = self.frames.make_contiguous();
unsafe {
let (prefix, v, suffix) = frames.align_to_mut::<f32>();
debug_assert!(prefix.is_empty());
debug_assert!(suffix.is_empty());
v
}
}
}
impl<F: Frame<Chan = Ch64>> Audio<F> {
pub fn as_f64_slice(&mut self) -> &mut [f64] {
let frames = self.frames.make_contiguous();
unsafe {
let (prefix, v, suffix) = frames.align_to_mut::<f64>();
debug_assert!(prefix.is_empty());
debug_assert!(suffix.is_empty());
v
}
}
}
impl<'a, F: Frame> IntoIterator for &'a Audio<F> {
type IntoIter = Cloned<Iter<'a, F>>;
type Item = F;
fn into_iter(self) -> Cloned<Iter<'a, F>> {
self.frames.iter().cloned()
}
}
impl<F: Frame> Stream<F> for &Audio<F> {
fn sample_rate(&self) -> Option<f64> {
Some(self.s_rate)
}
fn len(&self) -> Option<usize> {
Some(self.frames.len())
}
}
struct AudioSink<'a, F: Frame> {
s_rate: f64,
frames: &'a mut [F],
resampler: Resampler<F>,
}
impl<F: Frame> Sink<F> for AudioSink<'_, F> {
fn sample_rate(&self) -> f64 {
self.s_rate
}
fn resampler(&mut self) -> &mut Resampler<F> {
&mut self.resampler
}
fn buffer(&mut self) -> &mut [F] {
self.frames
}
}
struct AudioStream<
'a,
F: Frame,
R: RangeBounds<usize> + SliceIndex<[F], Output = [F]>,
> {
audio: &'a Audio<F>,
cursor: usize,
range: R,
size: usize,
}
impl<F: Frame, R: RangeBounds<usize> + SliceIndex<[F], Output = [F]>> Iterator
for AudioStream<'_, F, R>
{
type Item = F;
fn next(&mut self) -> Option<F> {
if !self.range.contains(&self.cursor) {
return None;
}
let sample = self.audio.get(self.cursor)?;
self.cursor += 1;
Some(sample)
}
}
impl<F: Frame, R: RangeBounds<usize> + SliceIndex<[F], Output = [F]>> Stream<F>
for AudioStream<'_, F, R>
{
fn sample_rate(&self) -> Option<f64> {
Some(self.audio.sample_rate())
}
fn len(&self) -> Option<usize> {
Some(self.size)
}
}
struct AudioDrain<'a, F: Frame> {
cursor: usize,
buffer: &'a mut Audio<F>,
}
impl<F: Frame> Iterator for AudioDrain<'_, F> {
type Item = F;
fn next(&mut self) -> Option<F> {
let sample = self.buffer.get(self.cursor)?;
self.cursor += 1;
Some(sample)
}
}
impl<'a, F: Frame> Stream<F> for AudioDrain<'_, F> {
fn sample_rate(&self) -> Option<f64> {
Some(self.buffer.s_rate)
}
fn len(&self) -> Option<usize> {
Some(self.buffer.len())
}
}
impl<'a, F: Frame> Drop for AudioDrain<'_, F> {
fn drop(&mut self) {
self.buffer.frames.drain(..self.cursor);
}
}
impl<F: Frame> From<Audio<F>> for Vec<F> {
fn from(audio: Audio<F>) -> Self {
audio.frames.into()
}
}
impl<F: Frame> From<Audio<F>> for Box<[F]> {
fn from(audio: Audio<F>) -> Self {
let audio: Vec<F> = audio.frames.into();
audio.into()
}
}
impl<F: Frame<Chan = Ch8>> From<Audio<F>> for Box<[i8]> {
#[allow(unsafe_code)]
fn from(audio: Audio<F>) -> Self {
let mut frames: Vec<F> = audio.frames.into();
let capacity = frames.len() * size_of::<F>();
let buffer: Box<[i8]> = unsafe {
let ptr = frames.as_mut_ptr() as *mut i8;
Box::from_raw(from_raw_parts_mut(ptr, capacity))
};
buffer
}
}
impl<F: Frame<Chan = Ch16>> From<Audio<F>> for Box<[i16]> {
#[allow(unsafe_code)]
fn from(audio: Audio<F>) -> Self {
let mut frames: Vec<F> = audio.frames.into();
let capacity = frames.len() * size_of::<F>() / 2;
let buffer: Box<[i16]> = unsafe {
let ptr = frames.as_mut_ptr() as *mut i16;
Box::from_raw(from_raw_parts_mut(ptr, capacity))
};
buffer
}
}
impl<F: Frame<Chan = Ch32>> From<Audio<F>> for Box<[f32]> {
#[allow(unsafe_code)]
fn from(audio: Audio<F>) -> Self {
let mut frames: Vec<F> = audio.frames.into();
let capacity = frames.len() * size_of::<F>() / 4;
let buffer: Box<[f32]> = unsafe {
let ptr = frames.as_mut_ptr() as *mut f32;
Box::from_raw(from_raw_parts_mut(ptr, capacity))
};
buffer
}
}
impl<F: Frame<Chan = Ch64>> From<Audio<F>> for Box<[f64]> {
#[allow(unsafe_code)]
fn from(audio: Audio<F>) -> Self {
let mut frames: Vec<F> = audio.frames.into();
let capacity = frames.len() * size_of::<F>() / 8;
let buffer: Box<[f64]> = unsafe {
let ptr = frames.as_mut_ptr() as *mut f64;
Box::from_raw(from_raw_parts_mut(ptr, capacity))
};
buffer
}
}