use std::ops::Range;
mod buf;
mod channels;
mod generic;
mod slice;
mod util;
pub mod conv;
pub mod sample;
pub use buf::*;
pub use channels::*;
pub use generic::*;
pub use slice::*;
use util::*;
use conv::FromSample;
use sample::{Sample, SampleBytes};
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct AudioSpec {
rate: u32,
channels: Channels,
}
impl AudioSpec {
pub fn new(rate: u32, channels: Channels) -> Self {
AudioSpec { rate, channels }
}
pub fn rate(&self) -> u32 {
self.rate
}
pub fn channels(&self) -> &Channels {
&self.channels
}
}
pub struct AudioPlanes<'a, S: Sample> {
planes: &'a [Vec<S>],
bound: Range<usize>,
}
impl<'a, S: Sample> AudioPlanes<'a, S> {
fn new(planes: &'a [Vec<S>], bound: Range<usize>) -> Self {
AudioPlanes { planes, bound }
}
}
impl<'a, S: Sample> Iterator for AudioPlanes<'a, S> {
type Item = &'a [S];
fn next(&mut self) -> Option<Self::Item> {
match self.planes.split_first() {
Some((next, rest)) => {
self.planes = rest;
Some(&next[self.bound.clone()])
}
_ => None,
}
}
}
pub struct AudioPlanesMut<'a, S: Sample> {
planes: &'a mut [Vec<S>],
bound: Range<usize>,
}
impl<'a, S: Sample> AudioPlanesMut<'a, S> {
fn new(planes: &'a mut [Vec<S>], bound: Range<usize>) -> Self {
AudioPlanesMut { planes, bound }
}
}
impl<'a, S: Sample> Iterator for AudioPlanesMut<'a, S> {
type Item = &'a mut [S];
fn next(&mut self) -> Option<Self::Item> {
match std::mem::take(&mut self.planes).split_first_mut() {
Some((next, rest)) => {
self.planes = rest;
Some(&mut next[self.bound.clone()])
}
_ => None,
}
}
}
pub struct Interleaved<'a, S: Sample> {
planes: &'a [Vec<S>],
num_planes: usize,
index: usize,
end: usize,
}
impl<S: Sample> Interleaved<'_, S> {
fn new(planes: &[Vec<S>], bound: Range<usize>) -> Interleaved<'_, S> {
let num_planes = planes.len();
let len = bound.len();
let index = bound.start * num_planes;
let end = index + len * num_planes;
Interleaved { planes, num_planes, index, end }
}
}
impl<S: Sample> Iterator for Interleaved<'_, S> {
type Item = S;
fn next(&mut self) -> Option<Self::Item> {
if self.index < self.end {
let frame = self.index / self.num_planes;
let plane = self.index % self.num_planes;
self.index += 1;
return Some(self.planes[plane][frame]);
}
None
}
}
pub trait Audio<S: Sample> {
fn spec(&self) -> &AudioSpec;
fn num_planes(&self) -> usize;
fn is_empty(&self) -> bool;
fn frames(&self) -> usize;
fn plane(&self, idx: usize) -> Option<&[S]>;
fn plane_by_position(&self, pos: Position) -> Option<&[S]> {
self.spec()
.channels()
.get_canonical_index_for_positioned_channel(pos)
.and_then(|idx| self.plane(idx))
}
fn plane_pair(&self, idx0: usize, idx1: usize) -> Option<(&[S], &[S])>;
fn plane_pair_by_position(&self, pos0: Position, pos1: Position) -> Option<(&[S], &[S])> {
assert!(pos0 != pos1, "channel positions cannot be the same");
let channels = self.spec().channels();
let idx0 = channels.get_canonical_index_for_positioned_channel(pos0);
let idx1 = channels.get_canonical_index_for_positioned_channel(pos1);
idx0.and_then(|idx0| idx1.map(|idx1| (idx0, idx1)))
.and_then(|(idx0, idx1)| self.plane_pair(idx0, idx1))
}
fn iter_planes(&self) -> AudioPlanes<'_, S>;
fn iter_interleaved(&self) -> Interleaved<'_, S>;
fn samples_interleaved(&self) -> usize {
self.num_planes() * self.frames()
}
fn samples_planar(&self) -> usize {
self.frames()
}
fn copy_to_slice_interleaved<Sout, Dst>(&self, dst: Dst)
where
Sout: Sample + FromSample<S>,
Dst: AsMut<[Sout]>;
fn copy_to_slice_planar<Sout, Dst>(&self, dst: &mut [Dst])
where
Sout: Sample + FromSample<S>,
Dst: AsMut<[Sout]>,
{
assert!(
dst.len() == self.num_planes(),
"expected {} destination slices",
self.num_planes()
);
for (src, dst) in self.iter_planes().zip(dst) {
copy_to_slice(src, dst.as_mut());
}
}
fn copy_to_vec_interleaved<Sout>(&self, dst: &mut Vec<Sout>)
where
Sout: Sample + FromSample<S>,
{
dst.resize(self.samples_interleaved(), Sout::MID);
self.copy_to_slice_interleaved(dst);
}
fn copy_to_vecs_planar<Sout>(&self, dst: &mut Vec<Vec<Sout>>)
where
Sout: Sample + FromSample<S>,
{
dst.resize(self.num_planes(), Default::default());
for vec in dst.iter_mut() {
vec.resize(self.samples_planar(), Sout::MID);
}
self.copy_to_slice_planar(dst);
}
}
pub trait AudioMut<S: Sample>: Audio<S> {
fn plane_mut(&mut self, idx: usize) -> Option<&mut [S]>;
fn plane_by_position_mut(&mut self, pos: Position) -> Option<&mut [S]> {
self.spec()
.channels()
.get_canonical_index_for_positioned_channel(pos)
.and_then(move |idx| self.plane_mut(idx))
}
fn plane_pair_mut(&mut self, idx0: usize, idx1: usize) -> Option<(&mut [S], &mut [S])>;
fn plane_pair_by_position_mut(
&mut self,
pos0: Position,
pos1: Position,
) -> Option<(&mut [S], &mut [S])> {
assert!(pos0 != pos1, "channel positions cannot be the same");
let channels = self.spec().channels();
let idx0 = channels.get_canonical_index_for_positioned_channel(pos0);
let idx1 = channels.get_canonical_index_for_positioned_channel(pos1);
idx0.and_then(|idx0| idx1.map(|idx1| (idx0, idx1)))
.and_then(move |(idx0, idx1)| self.plane_pair_mut(idx0, idx1))
}
fn iter_planes_mut(&mut self) -> AudioPlanesMut<'_, S>;
fn apply<F>(&mut self, f: F)
where
F: Fn(S) -> S,
{
for plane in self.iter_planes_mut() {
for sample in plane {
*sample = f(*sample);
}
}
}
fn copy_from<Sin, Src>(&mut self, src: &Src)
where
Sin: Sample,
S: Sample + FromSample<Sin>,
Src: Audio<Sin>,
{
assert!(self.spec() == src.spec(), "expected identical audio specifications");
assert!(self.frames() == src.frames(), "expected identical number of frames");
for (src, dst) in src.iter_planes().zip(self.iter_planes_mut()) {
copy_to_slice(src, dst);
}
}
fn copy_from_slice_planar<Sin, Src>(&mut self, src: &[Src])
where
Sin: Sample,
S: Sample + FromSample<Sin>,
Src: AsRef<[Sin]>,
{
assert!(src.len() == self.num_planes(), "expected {} source slices", self.num_planes());
for (src, dst) in src.iter().zip(self.iter_planes_mut()) {
copy_to_slice(src.as_ref(), dst);
}
}
fn copy_from_slice_interleaved<Sin, Src>(&mut self, src: &Src)
where
Sin: Sample,
S: Sample + FromSample<Sin>,
Src: AsRef<[Sin]>;
}
pub trait AudioBytes<S: Sample + SampleBytes>: Audio<S> {
fn byte_len_as<Sout>(&self) -> usize
where
Sout: SampleBytes + FromSample<S>,
{
std::mem::size_of::<Sout::RawType>() * self.samples_interleaved()
}
fn byte_len_per_plane_as<Sout>(&self) -> usize
where
Sout: SampleBytes + FromSample<S>,
{
std::mem::size_of::<Sout::RawType>() * self.samples_planar()
}
fn byte_len_per_frame_as<Sout>(&self) -> usize
where
Sout: SampleBytes + FromSample<S>,
{
std::mem::size_of::<Sout::RawType>() * self.num_planes()
}
fn copy_bytes_interleaved_as<Sout, Dst>(&self, dst: Dst)
where
Sout: SampleBytes + FromSample<S>,
Dst: AsMut<[u8]>;
fn copy_bytes_planar_as<Sout, Dst>(&self, dst: &mut [Dst])
where
Sout: SampleBytes + FromSample<S>,
Dst: AsMut<[u8]>;
fn byte_len(&self) -> usize {
std::mem::size_of::<S::RawType>() * self.samples_interleaved()
}
fn byte_len_per_plane(&self) -> usize {
std::mem::size_of::<S::RawType>() * self.samples_planar()
}
fn byte_len_per_frame(&self) -> usize {
std::mem::size_of::<S::RawType>() * self.num_planes()
}
fn copy_bytes_interleaved<Dst>(&self, dst: Dst)
where
Dst: AsMut<[u8]>;
fn copy_bytes_planar<Dst>(&self, dst: &mut [Dst])
where
Dst: AsMut<[u8]>;
fn copy_bytes_to_vec_interleaved(&self, dst: &mut Vec<u8>) {
dst.resize(self.byte_len(), 0);
self.copy_bytes_interleaved(dst);
}
fn copy_bytes_to_vec_interleaved_as<Sout>(&self, dst: &mut Vec<u8>)
where
Sout: SampleBytes + FromSample<S>,
{
dst.resize(self.byte_len_as::<Sout>(), 0);
self.copy_bytes_interleaved_as::<Sout, _>(dst);
}
fn copy_bytes_to_vecs_planar(&self, dst: &mut Vec<Vec<u8>>) {
dst.resize(self.num_planes(), Default::default());
for vec in dst.iter_mut() {
vec.resize(self.byte_len_per_plane(), 0);
}
self.copy_bytes_planar(dst);
}
fn copy_bytes_to_vecs_planar_as<Sout>(&self, dst: &mut Vec<Vec<u8>>)
where
Sout: SampleBytes + FromSample<S>,
{
dst.resize(self.num_planes(), Default::default());
for vec in dst.iter_mut() {
vec.resize(self.byte_len_per_plane_as::<Sout>(), 0);
}
self.copy_bytes_planar_as::<Sout, _>(dst);
}
}
pub trait AudioBufferBytes<S: Sample + SampleBytes>: AudioBytes<S> {
fn max_byte_len_as<Sout>(&self) -> usize
where
Sout: SampleBytes,
{
self.max_byte_len_per_plane_as::<Sout>() * self.num_planes()
}
fn max_byte_len_per_plane_as<Sout>(&self) -> usize
where
Sout: SampleBytes;
fn max_byte_len(&self) -> usize {
self.max_byte_len_per_plane() * self.num_planes()
}
fn max_byte_len_per_plane(&self) -> usize;
}