#![cfg_attr(not(feature = "std"), no_std)]
use dasp_frame::Frame;
use dasp_sample::Sample;
#[cfg(feature = "boxed")]
pub use boxed::{
from_boxed_frame_slice, from_boxed_sample_slice, to_boxed_frame_slice, to_boxed_sample_slice,
DuplexBoxedFrameSlice, DuplexBoxedSampleSlice, DuplexBoxedSlice, FromBoxedFrameSlice,
FromBoxedSampleSlice, ToBoxedFrameSlice, ToBoxedSampleSlice,
};
pub use frame::{
from_frame_slice, from_frame_slice_mut, to_frame_slice, to_frame_slice_mut, DuplexFrameSlice,
DuplexFrameSliceMut, FromFrameSlice, FromFrameSliceMut, ToFrameSlice, ToFrameSliceMut,
};
#[cfg(feature = "boxed")]
pub mod boxed;
mod frame;
pub trait FromSampleSlice<'a, S>: Sized
where
S: Sample,
{
fn from_sample_slice(slice: &'a [S]) -> Option<Self>;
}
pub trait FromSampleSliceMut<'a, S>: Sized
where
S: Sample,
{
fn from_sample_slice_mut(slice: &'a mut [S]) -> Option<Self>;
}
pub trait ToSampleSlice<'a, S>
where
S: Sample,
{
fn to_sample_slice(self) -> &'a [S];
}
pub trait ToSampleSliceMut<'a, S>
where
S: Sample,
{
fn to_sample_slice_mut(self) -> &'a mut [S];
}
pub trait DuplexSampleSlice<'a, S>: FromSampleSlice<'a, S> + ToSampleSlice<'a, S>
where
S: Sample,
{
}
pub trait DuplexSampleSliceMut<'a, S>: FromSampleSliceMut<'a, S> + ToSampleSliceMut<'a, S>
where
S: Sample,
{
}
pub trait DuplexSlice<'a, S, F>: DuplexSampleSlice<'a, S> + DuplexFrameSlice<'a, F>
where
S: Sample,
F: Frame<Sample = S>,
{
}
pub trait DuplexSliceMut<'a, S, F>:
DuplexSampleSliceMut<'a, S> + DuplexFrameSliceMut<'a, F>
where
S: Sample,
F: Frame<Sample = S>,
{
}
impl<'a, S> FromSampleSlice<'a, S> for &'a [S]
where
S: Sample,
{
#[inline]
fn from_sample_slice(slice: &'a [S]) -> Option<Self> {
Some(slice)
}
}
impl<'a, S> FromSampleSliceMut<'a, S> for &'a mut [S]
where
S: Sample,
{
#[inline]
fn from_sample_slice_mut(slice: &'a mut [S]) -> Option<Self> {
Some(slice)
}
}
impl<'a, S> ToSampleSlice<'a, S> for &'a [S]
where
S: Sample,
{
#[inline]
fn to_sample_slice(self) -> &'a [S] {
self
}
}
impl<'a, S> ToSampleSliceMut<'a, S> for &'a mut [S]
where
S: Sample,
{
#[inline]
fn to_sample_slice_mut(self) -> &'a mut [S] {
self
}
}
impl<'a, S, T> DuplexSampleSlice<'a, S> for T
where
S: Sample,
T: FromSampleSlice<'a, S> + ToSampleSlice<'a, S>,
{
}
impl<'a, S, T> DuplexSampleSliceMut<'a, S> for T
where
S: Sample,
T: FromSampleSliceMut<'a, S> + ToSampleSliceMut<'a, S>,
{
}
impl<'a, S, F, T> DuplexSlice<'a, S, F> for T
where
S: Sample,
F: Frame<Sample = S>,
T: DuplexSampleSlice<'a, S> + DuplexFrameSlice<'a, F>,
{
}
impl<'a, S, F, T> DuplexSliceMut<'a, S, F> for T
where
S: Sample,
F: Frame<Sample = S>,
T: DuplexSampleSliceMut<'a, S> + DuplexFrameSliceMut<'a, F>,
{
}
pub fn to_sample_slice<'a, T, S>(slice: T) -> &'a [S]
where
S: Sample,
T: ToSampleSlice<'a, S>,
{
slice.to_sample_slice()
}
pub fn to_sample_slice_mut<'a, T, S>(slice: T) -> &'a mut [S]
where
S: Sample,
T: ToSampleSliceMut<'a, S>,
{
slice.to_sample_slice_mut()
}
pub fn from_sample_slice<'a, T, S>(slice: &'a [S]) -> Option<T>
where
S: Sample,
T: FromSampleSlice<'a, S>,
{
T::from_sample_slice(slice)
}
pub fn from_sample_slice_mut<'a, T, S>(slice: &'a mut [S]) -> Option<T>
where
S: Sample,
T: FromSampleSliceMut<'a, S>,
{
T::from_sample_slice_mut(slice)
}
#[inline]
pub fn map_in_place<F, M>(a: &mut [F], mut map: M)
where
M: FnMut(F) -> F,
F: Frame,
{
for f in a {
*f = map(*f);
}
}
#[inline]
pub fn equilibrium<F>(a: &mut [F])
where
F: Frame,
{
map_in_place(a, |_| F::EQUILIBRIUM)
}
#[inline]
pub fn zip_map_in_place<FA, FB, M>(a: &mut [FA], b: &[FB], zip_map: M)
where
FA: Frame,
FB: Frame,
M: FnMut(FA, FB) -> FA,
{
assert_eq!(a.len(), b.len());
unsafe {
zip_map_in_place_unchecked(a, b, zip_map);
}
}
#[inline]
pub fn write<F>(a: &mut [F], b: &[F])
where
F: Frame,
{
zip_map_in_place(a, b, |_, b| b);
}
#[inline]
pub fn add_in_place<FA, FB>(a: &mut [FA], b: &[FB])
where
FA: Frame,
FB: Frame<Sample = <FA::Sample as Sample>::Signed, NumChannels = FA::NumChannels>,
{
zip_map_in_place(a, b, |a, b| a.add_amp(b));
}
#[inline]
pub fn add_in_place_with_amp_per_channel<FA, FB, A>(a: &mut [FA], b: &[FB], amp_per_channel: A)
where
FA: Frame,
FB: Frame<Sample = <FA::Sample as Sample>::Signed, NumChannels = FA::NumChannels>,
A: Frame<Sample = <FB::Sample as Sample>::Float, NumChannels = FB::NumChannels>,
{
zip_map_in_place(a, b, |af, bf| af.add_amp(bf.mul_amp(amp_per_channel)));
}
#[inline]
unsafe fn zip_map_in_place_unchecked<FA, FB, M>(a: &mut [FA], b: &[FB], mut zip_map: M)
where
FA: Frame,
FB: Frame,
M: FnMut(FA, FB) -> FA,
{
for i in 0..a.len() {
*a.get_unchecked_mut(i) = zip_map(*a.get_unchecked(i), *b.get_unchecked(i));
}
}