mod approx;
mod biquad;
mod interpolation;
mod oversampling;
mod rand;
mod trig_clock;
mod waveshapers;
mod low_freq;
mod delay;
mod oscillators;
mod filters;
pub use approx::*;
pub use biquad::{Biquad, BiquadCoefs};
pub use interpolation::*;
pub use oversampling::Oversampling;
pub use rand::*;
pub use trig_clock::*;
pub use waveshapers::*;
pub use low_freq::*;
pub use delay::*;
pub use oscillators::*;
pub use filters::*;
use num_traits::{cast::FromPrimitive, cast::ToPrimitive, Float, FloatConst};
macro_rules! trait_alias {
($name:ident = $base1:ident + $($base2:ident +)+) => {
pub trait $name: $base1 $(+ $base2)+ { }
impl<T: $base1 $(+ $base2)+> $name for T { }
};
}
trait_alias!(Flt = Float + FloatConst + ToPrimitive + FromPrimitive +);
#[allow(dead_code)]
#[inline]
fn f<F: Flt>(x: f64) -> F {
F::from_f64(x).unwrap()
}
#[allow(dead_code)]
#[inline]
fn fclamp<F: Flt>(x: F, mi: F, mx: F) -> F {
x.max(mi).min(mx)
}
#[allow(dead_code)]
#[inline]
fn fclampc<F: Flt>(x: F, mi: f64, mx: f64) -> F {
x.max(f(mi)).min(f(mx))
}
pub fn note_to_freq(note: f32) -> f32 {
440.0 * (2.0_f32).powf((note - 69.0) / 12.0)
}
pub fn gain2coef(gain: f32) -> f32 {
if gain > -90.0 {
10.0_f32.powf(gain * 0.05)
} else {
0.0
}
}
#[inline]
pub fn sqrt4_to_pow4(x: f32, v: f32) -> f32 {
if v > 0.75 {
let xsq1 = x.sqrt();
let xsq = xsq1.sqrt();
let v = (v - 0.75) * 4.0;
xsq1 * (1.0 - v) + xsq * v
} else if v > 0.5 {
let xsq = x.sqrt();
let v = (v - 0.5) * 4.0;
x * (1.0 - v) + xsq * v
} else if v > 0.25 {
let xx = x * x;
let v = (v - 0.25) * 4.0;
x * v + xx * (1.0 - v)
} else {
let xx = x * x;
let xxxx = xx * xx;
let v = v * 4.0;
xx * v + xxxx * (1.0 - v)
}
}
#[macro_export]
macro_rules! fa_distort {
($formatter: expr, $v: expr, $denorm_v: expr) => {{
let s = match ($v.round() as usize) {
0 => "Off",
1 => "TanH",
2 => "B.D.Jong",
3 => "Fold",
_ => "?",
};
write!($formatter, "{}", s)
}};
}
#[inline]
pub fn apply_distortion(s: f32, damt: f32, dist_type: u8) -> f32 {
match dist_type {
1 => (damt.clamp(0.01, 1.0) * 100.0 * s).tanh(),
2 => f_distort(1.0, damt * damt * damt * 1000.0, s),
3 => {
let damt = damt.clamp(0.0, 0.99);
let damt = 1.0 - damt * damt;
f_fold_distort(1.0, damt, s) * (1.0 / damt)
}
_ => s,
}
}