use Sample;
pub type Mono<S> = [S; 1];
pub type Stereo<S> = [S; 2];
pub trait Frame: Copy + Clone + PartialEq {
type Sample: Sample;
type NumChannels: NumChannels;
type Channels: Iterator<Item = Self::Sample>;
type Signed: Frame<Sample = <Self::Sample as Sample>::Signed, NumChannels = Self::NumChannels>;
type Float: Frame<Sample = <Self::Sample as Sample>::Float, NumChannels = Self::NumChannels>;
fn equilibrium() -> Self;
fn from_fn<F>(from: F) -> Self
where
F: FnMut(usize) -> Self::Sample;
fn from_samples<I>(samples: &mut I) -> Option<Self>
where
I: Iterator<Item = Self::Sample>;
fn n_channels() -> usize;
fn channels(self) -> Self::Channels;
fn channel(&self, idx: usize) -> Option<&Self::Sample>;
unsafe fn channel_unchecked(&self, idx: usize) -> &Self::Sample;
fn map<F, M>(self, map: M) -> F
where
F: Frame<NumChannels = Self::NumChannels>,
M: FnMut(Self::Sample) -> F::Sample;
fn zip_map<O, F, M>(self, other: O, zip_map: M) -> F
where
O: Frame<NumChannels = Self::NumChannels>,
F: Frame<NumChannels = Self::NumChannels>,
M: FnMut(Self::Sample, O::Sample) -> F::Sample;
fn to_signed_frame(self) -> Self::Signed;
fn to_float_frame(self) -> Self::Float;
#[inline]
fn offset_amp(self, offset: <Self::Sample as Sample>::Signed) -> Self {
self.map(|s| s.add_amp(offset))
}
#[inline]
fn scale_amp(self, amp: <Self::Sample as Sample>::Float) -> Self {
self.map(|s| s.mul_amp(amp))
}
#[inline]
fn add_amp<F>(self, other: F) -> Self
where
F: Frame<Sample = <Self::Sample as Sample>::Signed, NumChannels = Self::NumChannels>,
{
self.zip_map(other, Sample::add_amp)
}
#[inline]
fn mul_amp<F>(self, other: F) -> Self
where
F: Frame<Sample = <Self::Sample as Sample>::Float, NumChannels = Self::NumChannels>,
{
self.zip_map(other, Sample::mul_amp)
}
}
#[derive(Clone)]
pub struct Channels<F> {
next_idx: usize,
frame: F,
}
pub trait NumChannels {}
macro_rules! impl_frame {
($($NChan:ident $N:expr, [$($idx:expr)*],)*) => {
$(
/// A typified version of a number of channels.
pub struct $NChan;
impl NumChannels for $NChan {}
impl<S> Frame for [S; $N]
where
S: Sample,
{
type Sample = S;
type NumChannels = $NChan;
type Channels = Channels<Self>;
type Float = [S::Float; $N];
type Signed = [S::Signed; $N];
#[inline]
fn equilibrium() -> Self {
[S::equilibrium(); $N]
}
#[inline]
fn n_channels() -> usize {
$N
}
#[inline]
fn channels(self) -> Self::Channels {
Channels {
next_idx: 0,
frame: self,
}
}
#[inline]
fn channel(&self, idx: usize) -> Option<&Self::Sample> {
self.get(idx)
}
#[inline]
fn from_fn<F>(mut from: F) -> Self
where
F: FnMut(usize) -> S,
{
[$(from($idx), )*]
}
#[inline]
fn from_samples<I>(samples: &mut I) -> Option<Self>
where
I: Iterator<Item=Self::Sample>
{
Some([$( {
$idx;
match samples.next() {
Some(sample) => sample,
None => return None,
}
}, )*])
}
#[inline(always)]
unsafe fn channel_unchecked(&self, idx: usize) -> &Self::Sample {
self.get_unchecked(idx)
}
#[inline]
fn to_signed_frame(self) -> Self::Signed {
self.map(|s| s.to_sample())
}
#[inline]
fn to_float_frame(self) -> Self::Float {
self.map(|s| s.to_sample())
}
#[inline]
fn map<F, M>(self, mut map: M) -> F
where
F: Frame<NumChannels=Self::NumChannels>,
M: FnMut(Self::Sample) -> F::Sample,
{
F::from_fn(|channel_idx| {
unsafe { map(*self.channel_unchecked(channel_idx)) }
})
}
#[inline]
fn zip_map<O, F, M>(self, other: O, mut zip_map: M) -> F
where
O: Frame<NumChannels=Self::NumChannels>,
F: Frame<NumChannels=Self::NumChannels>,
M: FnMut(Self::Sample, O::Sample) -> F::Sample
{
F::from_fn(|channel_idx| {
unsafe {
zip_map(*self.channel_unchecked(channel_idx),
*other.channel_unchecked(channel_idx))
}
})
}
#[inline]
fn scale_amp(self, amp: S::Float) -> Self {
[$(self[$idx].mul_amp(amp), )*]
}
#[inline]
fn add_amp<F>(self, other: F) -> Self
where
F: Frame<Sample=S::Signed, NumChannels=$NChan>,
{
unsafe {
[$(self[$idx].add_amp(*other.channel_unchecked($idx)), )*]
}
}
}
)*
};
}
impl_frame!{
N1 1, [0],
N2 2, [0 1],
N3 3, [0 1 2],
N4 4, [0 1 2 3],
N5 5, [0 1 2 3 4],
N6 6, [0 1 2 3 4 5],
N7 7, [0 1 2 3 4 5 6],
N8 8, [0 1 2 3 4 5 6 7],
N9 9, [0 1 2 3 4 5 6 7 8],
N10 10, [0 1 2 3 4 5 6 7 8 9],
N11 11, [0 1 2 3 4 5 6 7 8 9 10],
N12 12, [0 1 2 3 4 5 6 7 8 9 10 11],
N13 13, [0 1 2 3 4 5 6 7 8 9 10 11 12],
N14 14, [0 1 2 3 4 5 6 7 8 9 10 11 12 13],
N15 15, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14],
N16 16, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15],
N17 17, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16],
N18 18, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17],
N19 19, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18],
N20 20, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19],
N21 21, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20],
N22 22, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21],
N23 23, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22],
N24 24, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23],
N25 25, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24],
N26 26, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25],
N27 27, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26],
N28 28, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27],
N29 29, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28],
N30 30, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29],
N31 31, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30],
N32 32, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31],
}
impl<F> Iterator for Channels<F>
where
F: Frame,
{
type Item = F::Sample;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.frame.channel(self.next_idx).map(|&s| s).map(|s| {
self.next_idx += 1;
s
})
}
}
impl<F> ExactSizeIterator for Channels<F>
where
F: Frame,
{
#[inline]
fn len(&self) -> usize {
F::n_channels() - self.next_idx
}
}