// Copyright © 2020-2022 The Fon Contributors. // // Licensed under any of: // - Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0) // - MIT License (https://mit-license.org/) // - Boost Software License, Version 1.0 (https://www.boost.org/LICENSE_1_0.txt) // At your choosing (See accompanying files LICENSE_APACHE_2_0.txt, // LICENSE_MIT.txt and LICENSE_BOOST_1_0.txt). #[cfg(not(test))] use crate::math::Libm; use crate::chan::{Ch16, Ch24, Ch32, Ch64, Channel}; use crate::frame::Frame; use crate::{Sink, Stream}; use alloc::boxed::Box; use alloc::slice::{Iter, IterMut}; use alloc::{vec, vec::Vec}; use core::convert::TryInto; use core::num::NonZeroU32; use core::{fmt::Debug, mem::size_of, slice::from_raw_parts_mut}; /// Audio buffer (fixed-size array of audio [`Frame`](crate::frame::Frame)s at /// sample rate specified in hertz). #[derive(Debug)] pub struct Audio { // Sample rate of the audio in hertz. sample_rate: NonZeroU32, // Audio frames. frames: Box<[Frame]>, } impl Audio { /// Construct an `Audio` buffer with all all samples set to zero. #[inline(always)] pub fn with_silence(hz: u32, len: usize) -> Self { Self::with_frames(hz, vec![Frame::::default(); len]) } /// Construct an `Audio` buffer with owned sample data. You can get /// ownership of the sample data back from the `Audio` buffer as either a /// `Vec` or a `Box<[S]>` by calling into(). #[inline(always)] pub fn with_frames(hz: u32, frames: B) -> Self where B: Into]>>, { Audio { sample_rate: hz.try_into().unwrap(), frames: frames.into(), } } /// Construct an `Audio` buffer from another `Audio` buffer of a different /// format. #[inline(always)] pub fn with_audio(hz: u32, audio: &Audio) -> Self where Ch: Channel, Ch32: From, Chan: From, { let len = audio.len() as f64 * hz as f64 / audio.sample_rate().get() as f64; let mut output = Self::with_silence(hz, len.ceil() as usize); let mut stream = Stream::new(hz); let mut sink = crate::SinkTo::<_, Chan, _, CH, N>::new(output.sink()); stream.pipe(audio, &mut sink); stream.flush(&mut sink); output } /// Get an audio frame. #[inline(always)] pub fn get(&self, index: usize) -> Option> { self.frames.get(index).cloned() } /// Get a mutable reference to an audio frame. #[inline(always)] pub fn get_mut(&mut self, index: usize) -> Option<&mut Frame> { self.frames.get_mut(index) } /// Get a slice of all audio frames. #[inline(always)] pub fn as_slice(&self) -> &[Frame] { &*self.frames } /// Get a slice of all audio frames. #[inline(always)] pub fn as_mut_slice(&mut self) -> &mut [Frame] { &mut *self.frames } /// Returns an iterator over the audio frames. #[inline(always)] pub fn iter(&self) -> Iter<'_, Frame> { self.frames.iter() } /// Returns an iterator that allows modifying each audio frame. #[inline(always)] pub fn iter_mut(&mut self) -> IterMut<'_, Frame> { self.frames.iter_mut() } /// Get the sample rate of this audio buffer. #[inline(always)] pub fn sample_rate(&self) -> NonZeroU32 { self.sample_rate } /// Get the length of the `Audio` buffer. #[inline(always)] pub fn len(&self) -> usize { self.frames.len() } /// Check if `Audio` buffer is empty. #[inline(always)] pub fn is_empty(&self) -> bool { self.len() == 0 } /// Silence the audio buffer. #[inline(always)] pub fn silence(&mut self) { for f in self.frames.iter_mut() { *f = Frame::::default() } } /// Sink audio into this audio buffer from a `Stream`. #[inline(always)] pub fn sink(&mut self) -> AudioSink<'_, Chan, CH> { AudioSink { index: 0, audio: self, } } } /// Returned from [`Audio::sink()`](crate::Audio::sink). #[derive(Debug)] pub struct AudioSink<'a, Chan: Channel, const CH: usize> { index: usize, audio: &'a mut Audio, } // Using '_ results in reserved lifetime error. #[allow(single_use_lifetimes)] impl<'a, Chan: Channel, const CH: usize> Sink for AudioSink<'a, Chan, CH> { #[inline(always)] fn sample_rate(&self) -> NonZeroU32 { self.audio.sample_rate() } #[inline(always)] fn len(&self) -> usize { self.audio.len() } #[inline(always)] fn sink_with(&mut self, iter: &mut dyn Iterator>) { let mut this = self; Sink::::sink_with(&mut this, iter) } } impl Sink for &mut AudioSink<'_, Chan, CH> { #[inline(always)] fn sample_rate(&self) -> NonZeroU32 { self.audio.sample_rate() } #[inline(always)] fn len(&self) -> usize { self.audio.len() } #[inline(always)] fn sink_with(&mut self, iter: &mut dyn Iterator>) { for frame in self.audio.iter_mut().skip(self.index) { *frame = if let Some(frame) = iter.next() { frame } else { break; }; self.index += 1; } } } impl Audio { /// Construct an `Audio` buffer from an `i16` buffer. #[allow(unsafe_code)] pub fn with_i16_buffer(hz: u32, buffer: B) -> Self where B: Into>, { let buffer: Box<[i16]> = buffer.into(); let bytes = buffer.len() * size_of::(); let len = bytes / size_of::>(); assert_eq!(0, bytes % size_of::>()); let slice = Box::<[i16]>::into_raw(buffer); let frames: Box<[Frame]> = unsafe { let ptr = (*slice).as_mut_ptr() as *mut Frame; Box::from_raw(from_raw_parts_mut(ptr, len)) }; let frames: Vec> = frames.into(); Audio::with_frames(hz, frames) } /// Get view of samples as an `i16` slice. #[allow(unsafe_code)] pub fn as_i16_slice(&mut self) -> &mut [i16] { let frames = self.as_mut_slice(); unsafe { let (prefix, v, suffix) = frames.align_to_mut::(); debug_assert!(prefix.is_empty()); debug_assert!(suffix.is_empty()); v } } } impl Audio { /// Construct an `Audio` buffer from an `u8` buffer. #[allow(unsafe_code)] pub fn with_u8_buffer(hz: u32, buffer: B) -> Self where B: Into>, { let buffer: Box<[u8]> = buffer.into(); let bytes = buffer.len() * size_of::(); let len = bytes / size_of::>(); assert_eq!(0, bytes % size_of::>()); let slice = Box::<[u8]>::into_raw(buffer); let frames: Box<[Frame]> = unsafe { let ptr = (*slice).as_mut_ptr() as *mut Frame; Box::from_raw(from_raw_parts_mut(ptr, len)) }; let frames: Vec> = frames.into(); Audio::with_frames(hz, frames) } /// Get view of samples as an `u8` slice. #[allow(unsafe_code)] pub fn as_u8_slice(&mut self) -> &mut [u8] { let frames = self.as_mut_slice(); unsafe { let (prefix, v, suffix) = frames.align_to_mut::(); debug_assert!(prefix.is_empty()); debug_assert!(suffix.is_empty()); v } } } impl Audio { /// Construct an `Audio` buffer from an `f32` buffer. #[allow(unsafe_code)] pub fn with_f32_buffer(hz: u32, buffer: B) -> Self where B: Into>, { let buffer: Box<[f32]> = buffer.into(); let bytes = buffer.len() * size_of::(); let len = bytes / size_of::>(); assert_eq!(0, bytes % size_of::>()); let slice = Box::<[f32]>::into_raw(buffer); let frames: Box<[Frame]> = unsafe { let ptr = (*slice).as_mut_ptr() as *mut Frame; Box::from_raw(from_raw_parts_mut(ptr, len)) }; let frames: Vec> = frames.into(); Audio::with_frames(hz, frames) } /// Get view of samples as an `f32` slice. #[allow(unsafe_code)] pub fn as_f32_slice(&mut self) -> &mut [f32] { let frames = self.as_mut_slice(); unsafe { let (prefix, v, suffix) = frames.align_to_mut::(); debug_assert!(prefix.is_empty()); debug_assert!(suffix.is_empty()); v } } } impl Audio { /// Construct an `Audio` buffer from an `f64` buffer. #[allow(unsafe_code)] pub fn with_f64_buffer(hz: u32, buffer: B) -> Self where B: Into>, { let buffer: Box<[f64]> = buffer.into(); let bytes = buffer.len() * size_of::(); let len = bytes / size_of::>(); assert_eq!(0, bytes % size_of::>()); let slice = Box::<[f64]>::into_raw(buffer); let frames: Box<[Frame]> = unsafe { let ptr = (*slice).as_mut_ptr() as *mut Frame; Box::from_raw(from_raw_parts_mut(ptr, len)) }; let frames: Vec> = frames.into(); Audio::with_frames(hz, frames) } /// Get view of samples as an `f64` slice. #[allow(unsafe_code)] pub fn as_f64_slice(&mut self) -> &mut [f64] { let frames = self.as_mut_slice(); unsafe { let (prefix, v, suffix) = frames.align_to_mut::(); debug_assert!(prefix.is_empty()); debug_assert!(suffix.is_empty()); v } } } impl From> for Vec> where Chan: Channel, { /// Get internal sample data as `Vec` of audio frames. fn from(audio: Audio) -> Self { audio.frames.into() } } impl From> for Box<[Frame]> { /// Get internal sample data as `Vec` of audio frames. fn from(audio: Audio) -> Self { let audio: Vec> = audio.frames.into(); audio.into() } } impl From> for Box<[i16]> { /// Get internal sample data as boxed slice of *i16*. #[allow(unsafe_code)] fn from(audio: Audio) -> Self { let mut frames: Vec> = audio.frames.into(); let capacity = frames.len() * size_of::>() / 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 From> for Box<[u8]> { /// Get internal sample data as boxed slice of *u8*. #[allow(unsafe_code)] fn from(audio: Audio) -> Self { let mut frames: Vec> = audio.frames.into(); let capacity = frames.len() * size_of::>() / 3; let buffer: Box<[u8]> = unsafe { let ptr = frames.as_mut_ptr() as *mut u8; Box::from_raw(from_raw_parts_mut(ptr, capacity)) }; buffer } } impl From> for Box<[f32]> { /// Get internal sample data as boxed slice of *f32*. #[allow(unsafe_code)] fn from(audio: Audio) -> Self { let mut frames: Vec> = audio.frames.into(); let capacity = frames.len() * size_of::>() / 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 From> for Box<[f64]> { /// Get internal sample data as boxed slice of *f64*. #[allow(unsafe_code)] fn from(audio: Audio) -> Self { let mut frames: Vec> = audio.frames.into(); let capacity = frames.len() * size_of::>() / 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 } }