#![recursion_limit="512"]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc, core_intrinsics))]
#[cfg(feature = "std")]
extern crate core;
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
type BTreeMap<K, V> = alloc::btree_map::BTreeMap<K, V>;
#[cfg(feature = "std")]
type BTreeMap<K, V> = std::collections::BTreeMap<K, V>;
#[cfg(not(feature = "std"))]
type Vec<T> = alloc::vec::Vec<T>;
#[cfg(feature = "std")]
#[allow(dead_code)]
type Vec<T> = std::vec::Vec<T>;
#[cfg(not(feature = "std"))]
type VecDeque<T> = alloc::vec_deque::VecDeque<T>;
#[cfg(feature = "std")]
type VecDeque<T> = std::collections::vec_deque::VecDeque<T>;
#[cfg(not(feature = "std"))]
pub type Box<T> = alloc::boxed::Box<T>;
#[cfg(feature = "std")]
pub type Box<T> = std::boxed::Box<T>;
#[cfg(not(feature = "std"))]
type Rc<T> = alloc::rc::Rc<T>;
#[cfg(feature = "std")]
type Rc<T> = std::rc::Rc<T>;
pub use conv::{FromSample, ToSample, Duplex, FromSampleSlice, ToSampleSlice, DuplexSampleSlice,
FromSampleSliceMut, ToSampleSliceMut, DuplexSampleSliceMut, FromBoxedSampleSlice,
ToBoxedSampleSlice, DuplexBoxedSampleSlice, FromFrameSlice, ToFrameSlice,
DuplexFrameSlice, FromFrameSliceMut, ToFrameSliceMut, DuplexFrameSliceMut,
FromBoxedFrameSlice, ToBoxedFrameSlice, DuplexBoxedFrameSlice, DuplexSlice,
DuplexSliceMut, DuplexBoxedSlice};
pub use frame::Frame;
pub use signal::Signal;
pub use types::{I24, U24, I48, U48};
pub mod slice;
pub mod conv;
pub mod envelope;
pub mod frame;
pub mod peak;
pub mod ring_buffer;
pub mod rms;
pub mod signal;
pub mod types;
pub mod window;
pub mod interpolate;
mod ops {
pub mod f32 {
#[allow(unused_imports)]
use core;
#[cfg(not(feature = "std"))]
pub fn sqrt(x: f32) -> f32 {
unsafe { core::intrinsics::sqrtf32(x) }
}
#[cfg(feature = "std")]
pub fn sqrt(x: f32) -> f32 {
x.sqrt()
}
#[cfg(feature = "std")]
pub fn powf32(a: f32, b: f32) -> f32 {
a.powf(b)
}
#[cfg(not(feature = "std"))]
pub fn powf32(a: f32, b: f32) -> f32 {
unsafe { core::intrinsics::powf32(a, b) }
}
}
pub mod f64 {
#[allow(unused_imports)]
use core;
#[cfg(not(feature = "std"))]
pub fn floor(x: f64) -> f64 {
unsafe { core::intrinsics::floorf64(x) }
}
#[cfg(feature = "std")]
pub fn floor(x: f64) -> f64 {
x.floor()
}
#[cfg(not(feature = "std"))]
#[allow(dead_code)]
pub fn ceil(x: f64) -> f64 {
unsafe { core::intrinsics::ceilf64(x) }
}
#[cfg(feature = "std")]
#[allow(dead_code)]
pub fn ceil(x: f64) -> f64 {
x.ceil()
}
#[cfg(not(feature = "std"))]
pub fn sin(x: f64) -> f64 {
unsafe { core::intrinsics::sinf64(x) }
}
#[cfg(feature = "std")]
pub fn sin(x: f64) -> f64 {
x.sin()
}
#[cfg(not(feature = "std"))]
pub fn cos(x: f64) -> f64 {
unsafe { core::intrinsics::cosf64(x) }
}
#[cfg(feature = "std")]
pub fn cos(x: f64) -> f64 {
x.cos()
}
#[cfg(not(feature = "std"))]
pub fn sqrt(x: f64) -> f64 {
unsafe { core::intrinsics::sqrtf64(x) }
}
#[cfg(feature = "std")]
pub fn sqrt(x: f64) -> f64 {
x.sqrt()
}
}
}
pub trait Sample: Copy + Clone + PartialOrd + PartialEq {
type Signed: SignedSample + Duplex<Self>;
type Float: FloatSample + Duplex<Self>;
fn equilibrium() -> Self;
#[inline]
fn identity() -> Self::Float {
<Self::Float as FloatSample>::identity()
}
#[inline]
fn to_sample<S>(self) -> S
where
Self: ToSample<S>,
{
self.to_sample_()
}
#[inline]
fn from_sample<S>(s: S) -> Self
where
Self: FromSample<S>,
{
FromSample::from_sample_(s)
}
fn to_signed_sample(self) -> Self::Signed {
self.to_sample()
}
fn to_float_sample(self) -> Self::Float {
self.to_sample()
}
#[inline]
fn add_amp(self, amp: Self::Signed) -> Self {
let self_s = self.to_signed_sample();
(self_s + amp).to_sample()
}
#[inline]
fn mul_amp(self, amp: Self::Float) -> Self {
let self_f = self.to_float_sample();
(self_f * amp).to_sample()
}
}
macro_rules! impl_sample {
($($T:ty:
Signed: $Addition:ty,
Float: $Modulation:ty,
equilibrium: $equilibrium:expr),*) =>
{
$(
impl Sample for $T {
type Signed = $Addition;
type Float = $Modulation;
#[inline]
fn equilibrium() -> Self {
$equilibrium
}
}
)*
}
}
impl_sample!{
i8: Signed: i8, Float: f32, equilibrium: 0,
i16: Signed: i16, Float: f32, equilibrium: 0,
I24: Signed: I24, Float: f32, equilibrium: types::i24::EQUILIBRIUM,
i32: Signed: i32, Float: f32, equilibrium: 0,
I48: Signed: I48, Float: f64, equilibrium: types::i48::EQUILIBRIUM,
i64: Signed: i64, Float: f64, equilibrium: 0,
u8: Signed: i8, Float: f32, equilibrium: 128,
u16: Signed: i16, Float: f32, equilibrium: 32_768,
U24: Signed: i32, Float: f32, equilibrium: types::u24::EQUILIBRIUM,
u32: Signed: i32, Float: f32, equilibrium: 2_147_483_648,
U48: Signed: i64, Float: f64, equilibrium: types::u48::EQUILIBRIUM,
u64: Signed: i64, Float: f64, equilibrium: 9_223_372_036_854_775_808,
f32: Signed: f32, Float: f32, equilibrium: 0.0,
f64: Signed: f64, Float: f64, equilibrium: 0.0
}
pub trait SignedSample
: Sample<Signed = Self>
+ core::ops::Add<Output = Self>
+ core::ops::Sub<Output = Self>
+ core::ops::Neg<Output = Self> {
}
macro_rules! impl_signed_sample { ($($T:ty)*) => { $( impl SignedSample for $T {} )* } }
impl_signed_sample!(i8 i16 I24 i32 I48 i64 f32 f64);
pub trait FloatSample
: Sample<Signed = Self, Float = Self>
+ SignedSample
+ core::ops::Mul<Output = Self>
+ core::ops::Div<Output = Self>
+ Duplex<f32>
+ Duplex<f64> {
fn identity() -> Self;
fn sample_sqrt(self) -> Self;
}
impl FloatSample for f32 {
#[inline]
fn identity() -> Self {
1.0
}
#[inline]
fn sample_sqrt(self) -> Self {
ops::f32::sqrt(self)
}
}
impl FloatSample for f64 {
#[inline]
fn identity() -> Self {
1.0
}
#[inline]
fn sample_sqrt(self) -> Self {
ops::f64::sqrt(self)
}
}