use pointillism::prelude::*;
struct SchroederUnit<S: Signal>(eff::dly::Exp<S, buf::Dyn<S::Sample>>)
where
S::Sample: Audio;
impl<S: Signal> SchroederUnit<S>
where
S::Sample: Audio,
{
fn new(sgn: S, gain: unt::Vol, delay: unt::Time) -> Self {
Self(eff::dly::Exp::new_exp_owned(sgn, delay, gain))
}
fn sgn(&self) -> &S {
&self.0.sgn
}
fn sgn_mut(&mut self) -> &mut S {
&mut self.0.sgn
}
fn gain(&self) -> unt::Vol {
self.0.vol()
}
}
impl<S: Signal> Signal for SchroederUnit<S>
where
S::Sample: Audio,
{
type Sample = S::Sample;
fn get(&self) -> Self::Sample {
let g = self.gain().gain;
self.0._get() * (1.0 - g * g) - self.sgn().get() * g
}
}
impl<S: SignalMut> SignalMut for SchroederUnit<S>
where
S::Sample: Audio,
{
fn advance(&mut self) {
self.0.advance();
}
fn retrigger(&mut self) {
self.0.retrigger();
}
}
impl<S: Base> Base for SchroederUnit<S>
where
S::Sample: Audio,
{
type Base = S::Base;
fn base(&self) -> &Self::Base {
self.sgn().base()
}
fn base_mut(&mut self) -> &mut Self::Base {
self.sgn_mut().base_mut()
}
}
fn main() {
let signal = eff::Vibrato::new(
gen::Loop::<smp::Stereo, _>::new(crv::Tri, unt::Freq::default()),
unt::Freq::from_raw_default(unt::RawFreq::A4),
gen::Loop::new(
map::Comp::new(crv::PosSaw, map::Linear::rescale_unit(0.5, 2.0)),
unt::Freq::from_hz_default(10.0),
),
);
let gain = unt::Vol::MDB3;
let decay = 10.0;
let delays: [unt::Time; 4] =
[347.17, 113.29, 37.31, 13.42].map_array(|&t| unt::Time::from_samples((t * decay) as u64));
let reverb_0 = SchroederUnit::new(signal, gain, delays[0]);
let reverb_1 = SchroederUnit::new(reverb_0, gain, delays[1]);
let reverb_2 = SchroederUnit::new(reverb_1, gain, delays[2]);
let mut reverb_3 = SchroederUnit::new(reverb_2, gain, delays[3]);
let length = unt::Time::from_sec_default(10.0);
Song::new(length, unt::SampleRate::CD, |time| {
let p = time / length;
(reverb_3.base().get() * p + reverb_3.next() * (1.0 - p)) / 2.0
})
.export("pointillism/examples/schroeder.wav");
}