#![allow(
dead_code,
clippy::precedence,
clippy::type_complexity,
clippy::float_cmp,
clippy::len_zero,
clippy::double_neg,
clippy::many_single_char_names,
clippy::manual_range_contains
)]
use fundsp::audiounit::*;
use fundsp::prelude64::*;
use funutd::*;
fn check_wave(mut node: impl AudioUnit) {
node.allocate();
let wave = Wave::render(44100.0, 0.01, &mut node);
assert!(wave.channels() == 2);
assert!(wave.length() == 441);
node.reset();
for i in 0..441 {
let (tick_x, tick_y) = node.get_stereo();
let process_x = wave.at(0, i);
let process_y = wave.at(1, i);
let tolerance = 1.0e-4;
if tick_x - tolerance > process_x || tick_x + tolerance < process_x {
eprintln!(
"channel 0 index {} tick {} process {}",
i, tick_x, process_x
);
}
assert!(tick_x - tolerance <= process_x && tick_x + tolerance >= process_x);
if tick_y - tolerance > process_y || tick_y + tolerance < process_y {
eprintln!(
"channel 1 index {} tick {} process {}",
i, tick_y, process_y
);
}
assert!(tick_y - tolerance <= process_y && tick_y + tolerance >= process_y);
}
}
fn check_wave_big(node: Box<dyn AudioUnit>) {
assert_eq!(node.inputs(), 0);
assert_eq!(node.outputs(), 1);
let mut wave = Wave::with_capacity(1, 44100.0, 441);
wave.resize(441);
let mut big = BigBlockAdapter::new(node);
big.allocate();
big.process_big(441, &[], &mut [wave.channel_mut(0)]);
big.reset();
for i in 0..441 {
let tick_x = big.get_mono();
let process_x = wave.at(0, i);
let tolerance = 1.0e-4;
assert!(tick_x - tolerance <= process_x && tick_x + tolerance >= process_x);
}
}
fn check_wave_filter(input: &Wave, mut node: impl AudioUnit) {
node.allocate();
let wave = input.filter(1.1 * 0.5, &mut node);
assert!(wave.channels() == 2);
assert!(wave.length() == 22050 + 2205);
node.reset();
for i in 0..wave.length() {
let (tick_x, tick_y) = node.filter_stereo(input.at(0, i), input.at(1, i));
let process_x = wave.at(0, i);
let process_y = wave.at(1, i);
let tolerance = 1.0e-4;
assert!(
tick_x - tolerance <= process_x && tick_x + tolerance >= process_x,
"channel 0 at index {i} failed: tick {tick_x} process {process_x}"
);
assert!(
tick_y - tolerance <= process_y && tick_y + tolerance >= process_y,
"channel 1 at index {i} failed: tick {tick_y} process {process_y}"
);
}
}
fn is_equal<X, Y>(rnd: &mut Rnd, x: &mut An<X>, y: &mut An<Y>) -> bool
where
X: AudioNode,
Y: AudioNode<Inputs = X::Inputs, Outputs = X::Outputs>,
{
for _ in 0..1000 {
let input = Frame::<f32, X::Inputs>::generate(|_| (rnd.i64() % 3 - 1) as f32);
let output_x = x.tick(&input.clone());
let output_y = y.tick(&input.clone());
if output_x != output_y {
return false;
}
}
true
}
fn is_equal_unit<X, Y>(rnd: &mut Rnd, x: &mut X, y: &mut Y) -> bool
where
X: AudioUnit,
Y: AudioUnit,
{
assert!(2 == y.inputs() && x.inputs() == 2);
assert!(x.outputs() == 2 && 2 == y.outputs());
for _ in 0..1000 {
let input0 = (rnd.u64() & 0xf) as f32;
let input1 = (rnd.u64() & 0xf) as f32;
let output_x = x.filter_stereo(input0, input1);
let output_y = y.filter_stereo(input0, input1);
if output_x != output_y {
return false;
}
}
true
}
fn outputs_diverge<X>(rnd: &mut Rnd, x: &mut An<X>) -> bool
where
X: AudioNode,
{
assert!(x.outputs() <= 8);
let mut diverged: u64 = 0;
for _ in 0..10 {
let input = Frame::<f32, X::Inputs>::generate(|_| (rnd.i64() % 3 - 1) as f32);
let output = x.tick(&input);
for i in 0..x.outputs() {
for j in 0..x.outputs() {
if output[i] != output[j] {
diverged |= 1 << (i * 8 + j);
}
}
}
}
for i in 0..x.outputs() {
for j in 0..x.outputs() {
if i != j && diverged & (1 << (i * 8 + j)) == 0 {
return false;
}
}
}
true
}
#[test]
fn test_basic() {
let mut rnd = Rnd::new();
check_wave(noise() >> declick() | noise() + noise());
check_wave(noise().seed(1) * noise() | busi::<U4, _, _>(|i| mls_bits(10 + i)));
check_wave(pink().seed(2) & noise() | sine_hz(440.0) & -noise());
check_wave(
lfo(|t| xerp(110.0, 220.0, clamp01(t))) >> sine()
| (envelope(|t| xerp(220.0, 440.0, clamp01(t))) >> pass() >> sine()) & mls(),
);
check_wave(dc(1.0) >> lfo2(|t, x| t * x) | dc(1.0) >> envelope2(|t, x| t * x));
check_wave(
dc((1.0, 2.0)) >> lfo3(|t, x, y| t * x * y)
| dc((1.0, 2.0)) >> envelope3(|t, x, y| t * x * y),
);
check_wave(dc((110.0, 220.0)) >> multipass() >> -stackf::<U2, _, _>(|f| (f - 0.5) * sine()));
check_wave(
dc((110.0, 220.0, 440.0, 880.0))
>> multipass()
>> (sink() | -sine().phase(0.0) | sink() | sine()),
);
check_wave(dc((110.0, 220.0)) >> declick_s(0.1) + pass() >> (saw() ^ dsf_square_r(0.9)));
check_wave(
dc((20.0, 40.0)) >> reverse() >> pass() * pass() >> (dsf_saw_r(0.999) ^ square() * 0.1),
);
let seq = Sequencer::new(2, 2, ReplayMode::None);
check_wave((noise() | noise()) >> Net::wrap(Box::new(seq)));
check_wave(
dc((880.0, 440.0)) >> pass() - pass() >> branchf::<U2, _, _>(|f| (f - 0.5) * triangle()),
);
check_wave(
(noise() | dc(440.0)) >> pipei::<U3, _, _>(|_| !lowpole()) >> lowpole()
| ((mls() | dc(880.0)) >> !butterpass() >> butterpass()),
);
check_wave(
(brown().seed(2) | dc(440.0)) >> pipei::<U4, _, _>(|_| !peak_q(1.0)) >> bell_q(1.0, 2.0)
| ((mls() | dc(880.0)) >> !lowshelf_q(1.0, 0.5) >> highshelf_q(2.0, 2.0)),
);
check_wave(
(square_hz(110.0).phase(0.25) | dc(440.0))
>> pipei::<U4, _, _>(|_| !lowpass_q(1.0))
>> highpass_q(1.0)
| ((mls() | dc(880.0)) >> !bandpass_q(1.0) >> notch_q(2.0)),
);
check_wave(
dc((440.0, 880.0)) >> multisplit::<U2, U5>() >> sumi::<U10, _, _>(|_| saw() * 0.1)
| saw_hz(220.0).phase(0.5) * 0.1,
);
check_wave(
dc((440.0, 880.0)) >> multisplit::<U2, U3>() >> multijoin::<U2, U3>() >> (sine() | sine()),
);
check_wave((noise() >> split::<U16>() >> join()) | (noise() >> split::<U11>() >> join()));
check_wave(
noise() >> dbell_hz(Tanh(1.0), 1000.0, 10.0, 2.0)
| noise() >> dhighpass_hz(Softsign(1.0), 2000.0, 2.0),
);
check_wave(
noise() >> dresonator_hz(Tanh(0.5), 1000.0, 10.0)
| noise() >> dlowpass_hz(Softsign(0.5), 2000.0, 2.0),
);
check_wave(
noise() >> fbell_hz(Atan(1.0), 500.0, 50.0, 0.5)
| noise() >> flowpass_hz(Clip(1.0), 2000.0, 2.0),
);
check_wave(
noise() >> fresonator_hz(Atan(0.5), 500.0, 50.0)
| noise() >> fhighpass_hz(Softsign(0.2), 2000.0, 2.0),
);
check_wave(dc(440.0) >> ramp() | ramp_hz(-220.0).phase(0.5));
check_wave_big(Box::new(dc((110.0, 0.5)) >> pulse() * 0.2 >> delay(0.1)));
check_wave_big(Box::new(envelope(|t| exp(-t * 10.0))));
let feedback1 = noise()
>> Net::wrap(Box::new(FeedbackUnit::new(
0.01,
Box::new(0.5 * lowpass_hz(1000.0, 1.0)),
)));
let feedback2 = noise()
>> Net::wrap(Box::new(FeedbackUnit::new(
0.001,
Box::new(0.5 * highpass_hz(1000.0, 1.0)),
)));
check_wave(feedback1 | feedback2);
let mut sequencer = Sequencer::new(0, 2, ReplayMode::All);
sequencer.push(
0.1,
0.2,
Fade::Smooth,
0.01,
0.0,
Box::new(noise() | sine_hz(220.0)),
);
sequencer.push(
0.3,
0.4,
Fade::Smooth,
0.09,
0.08,
Box::new(sine_hz(110.0) | noise()),
);
sequencer.push(0.25, 0.5, Fade::Power, 0.0, 0.01, Box::new(mls() | noise()));
sequencer.push(0.6, 0.7, Fade::Power, 0.02, 0.03, Box::new(noise() | mls()));
check_wave(sequencer);
let mut net = Net::new(0, 2);
let id = net.push(Box::new(
noise() >> moog_hz(1500.0, 0.8) | noise() >> moog_hz(500.0, 0.4),
));
net.connect_output(id, 0, 0);
net.connect_output(id, 1, 1);
net.check();
check_wave(net);
let mut net = Net::new(0, 2);
net.chain(Box::new(noise() | noise()));
net.chain(Box::new(moog_hz(1500.0, 0.5) | moog_hz(1000.0, 0.6)));
net.chain(Box::new(lowpole_hz(1000.0) | lowpole_hz(500.0)));
net.check();
check_wave(net);
let mut net = Net::new(0, 2);
net.chain(Box::new(noise()));
net.chain(Box::new(lowpole_hz(1000.0) ^ lowpole_hz(500.0)));
net.chain(Box::new(lowpole_hz(1000.0) | lowpole_hz(500.0)));
net.check();
check_wave(net);
let mut net = Net::wrap(Box::new(sine_hz(42.)));
net = net.clone() | net;
let verb = Net::wrap(Box::new(reverb_stereo(10., 5., 0.5)));
net.chain(Box::new(verb));
net.check();
check_wave(net);
check_wave((noise() | envelope(|t| spline_noise(1, t * 10.0))) >> panner());
check_wave(impulse::<U2>());
check_wave(poly_saw_hz(440.0) | poly_square_hz(4400.0));
check_wave(poly_saw_hz(550.0).phase(0.75) | poly_square_hz(5500.0).phase(0.5));
check_wave(
dc((660.0, 0.1)) >> poly_pulse().phase(0.75) | poly_pulse_hz(6600.0, 0.9).phase(0.9),
);
let mut biq = biquad_bank();
biq.set(Setting::biquad(0.0, 0.0, 0.2, 0.2, 0.2).index(0));
biq.set(Setting::biquad(0.2, 0.2, 0.1, 0.3, 0.5).index(1));
check_wave((noise() | noise() | zero() | zero()) >> biq >> (pass() | pass() | sink() | sink()));
let dc42 = Net::wrap(Box::new(dc(42.)));
let dcs = dc42.clone() | dc42;
let reverb = Net::wrap(Box::new(reverb_stereo(40., 5., 1.)));
let filter = Net::wrap(Box::new(lowpass_hz(1729., 1.)));
let filters = filter.clone() | filter;
let net = dcs >> reverb >> filters;
net.check();
check_wave(net);
check_wave(
noise() >> convolve(&Wave::from_samples(44100.0, &[1.0, 0.9, 0.8]), 0)
| pink() >> convolve(&Wave::from_samples(44100.0, &[0.5, 0.4, 0.3]), 0),
);
let input = Wave::render(44100.0, 1.0, &mut (noise() | noise()));
check_wave_filter(&input, butterpass_hz(1000.0) | lowpole_hz(100.0));
check_wave_filter(&input, allpole_delay(0.5) | highpole_hz(500.0));
check_wave_filter(&input, pluck(60.0, 0.9, 0.8) | pluck(110.0, 0.5, 0.1));
check_wave_filter(
&input,
(pass() | dc((2000.0, 5.0, 0.8))) >> morph() | morph_hz(440.0, 1.0, 0.0),
);
check_wave_filter(&input, lowrez_hz(440.0, 0.5) | bandrez_hz(440.0, 0.5));
check_wave_filter(
&input,
resonator_hz(440.0, 110.0) | resonator_hz(880.0, 110.0),
);
let tap_node = (pass() | lfo(|t| (abs(spline_noise(4, t)), abs(spline_noise(5, t)))))
>> multitap::<U2>(0.0, 1.0);
check_wave_filter(&input, tap_node.clone() | tap_node.clone());
let tap_node = (pass() | lfo(|t| (abs(spline_noise(6, t)), abs(spline_noise(7, t)))))
>> multitap_linear::<U2>(0.0, 1.0);
check_wave_filter(&input, tap_node.clone() | tap_node.clone());
let mut cycle = Net::new(2, 1);
let id1 = cycle.chain(Box::new(join::<U2>()));
let id2 = cycle.chain(Box::new(pass()));
assert_eq!(cycle.error(), &None);
cycle.set_source(id1, 1, Source::Local(id2, 0));
assert_eq!(cycle.error(), &Some(NetError::Cycle));
cycle.set_source(id1, 1, Source::Global(0));
assert_eq!(cycle.error(), &None);
let mut d = constant(1.0);
assert!(d.inputs() == 0 && d.outputs() == 1);
assert!(d.get_mono() == 1.0);
let mut d = constant((2.0, 3.0));
assert!(d.inputs() == 0 && d.outputs() == 2);
assert!(d.get_stereo() == (2.0, 3.0));
assert!(d.get_mono() == 2.5);
let c = constant((2.0, 3.0)) * dc((2.0, 3.0));
let e = c >> (pass() | pass());
let mut f = e >> mul(0.5) + mul(0.5);
assert!(f.inputs() == 0 && f.outputs() == 1);
assert!(f.get_mono() == 6.5);
fn inouts<X: AudioNode>(x: An<X>) -> (usize, usize) {
(x.inputs(), x.outputs())
}
let v = 1.0;
let w = -2.0;
let x = 3.0;
let y = -4.0;
let z = 5.0;
assert!(is_equal(
&mut rnd,
&mut ((pass() ^ mul(y)) >> add(z) + sub(x)),
&mut (add(z) & mul(y) >> sub(x))
));
assert!(is_equal(
&mut rnd,
&mut ((pass() ^ mul(y) ^ add(w)) >> add(z) + sub(x) + mul(y)),
&mut (add(z) & mul(y) >> sub(x) & add(w) >> mul(y))
));
assert!(is_equal(
&mut rnd,
&mut ((pass() ^ mul(y) ^ add(w) ^ sub(x)) >> add(z) + sub(x) + mul(y) + add(z)),
&mut (add(z) & mul(y) >> sub(x) & add(w) >> mul(y) & sub(x) >> add(z))
));
let mut pass_through = pass() | pass();
let mut pass_through_net = Net::new(2, 2);
pass_through_net.pass_through(0, 0);
pass_through_net.pass_through(1, 1);
assert!(is_equal_unit(
&mut rnd,
&mut pass_through,
&mut pass_through_net
));
pass_through_net.check();
let mut swap_through = reverse::<U2>();
let mut swap_through_net = Net::new(2, 2);
swap_through_net.pass_through(0, 1);
swap_through_net.pass_through(1, 0);
assert!(is_equal_unit(
&mut rnd,
&mut swap_through,
&mut swap_through_net
));
swap_through_net.check();
let mut multiply_2_3 = mul(2.0) | mul(3.0);
let mut multiply_net = Net::new(2, 2);
let id0 = multiply_net.push(Box::new(mul(2.0)));
let idd = multiply_net.push(Box::new(sink()));
let ide = multiply_net.push(Box::new(sine()));
let id1 = multiply_net.push(Box::new(mul(3.0)));
multiply_net.connect_input(0, id0, 0);
multiply_net.connect_input(1, id1, 0);
multiply_net.connect_output(id0, 0, 0);
multiply_net.connect_output(id1, 0, 1);
assert!(is_equal_unit(
&mut rnd,
&mut multiply_2_3,
&mut multiply_net
));
multiply_net.remove(idd);
multiply_net.remove(ide);
multiply_net.check();
assert!(is_equal_unit(
&mut rnd,
&mut multiply_2_3,
&mut multiply_net
));
let mut add_2_3 = add((2.0, 3.0));
let mut add_net = Net::new(2, 2);
let id0 = add_net.push(Box::new(add((2.0, 3.0))));
let idd = add_net.push(Box::new(zero()));
let id1 = add_net.push(Box::new(multipass::<U2>()));
assert!(id0 != idd && id0 != id1 && idd != id1);
add_net.remove(idd);
add_net.pipe_input(id0);
add_net.pipe_all(id0, id1);
add_net.pipe_output(id1);
assert!(is_equal_unit(&mut rnd, &mut add_2_3, &mut add_net));
add_net.check();
let mut front_net = Net::new(0, 1);
let dc_id = front_net.chain(Box::new(dc(1.0)));
front_net.set_sample_rate(48000.0);
let mut back_net = front_net.backend();
assert_eq!(back_net.get_mono(), 1.0);
front_net.set(Setting::value(2.0).node(dc_id));
assert_eq!(back_net.get_mono(), 2.0);
front_net.replace(dc_id, Box::new(dc(3.0)));
assert_eq!(back_net.get_mono(), 2.0);
front_net.commit();
assert_eq!(back_net.get_mono(), 3.0);
assert!(is_equal(
&mut rnd,
&mut (dc(w) | dc(x)),
&mut (constant((w, x)))
));
assert!(is_equal(
&mut rnd,
&mut (dc(x) | dc(y) | dc(z)),
&mut (constant((x, y, z)))
));
assert!(is_equal(
&mut rnd,
&mut (dc(x) | dc(y) | dc(z) | dc(w)),
&mut (constant((x, y, z, w)))
));
assert!(is_equal(
&mut rnd,
&mut (dc(w) | dc(v) | dc(x) | dc(y) | dc(z)),
&mut (constant((w, v, x, y, z)))
));
assert!(is_equal(
&mut rnd,
&mut (dc((w, x)) | dc((y, z, w))),
&mut (constant((w, x, y, z, w)))
));
assert!(is_equal(
&mut rnd,
&mut (sink() | sink() | zero() | zero()),
&mut (zero() | zero() | sink() | sink())
));
assert!(is_equal(
&mut rnd,
&mut (sink() | zero() | sink() | zero() | zero() | sink() | zero()),
&mut (zero() | zero() | zero() | sink() | sink() | zero() | sink())
));
assert!(is_equal(
&mut rnd,
&mut (tick() >> tick() >> tick()),
&mut (delay(3.0 / 44100.0))
));
assert!(is_equal(
&mut rnd,
&mut (tick() >> tick() >> tick() >> tick() >> tick()),
&mut (delay(5.0 / 44100.0))
));
assert!(outputs_diverge(
&mut rnd,
&mut (noise()
| (!zero() >> noise())
| noise()
| (!zero() >> noise())
| noise()
| noise()
| noise())
));
assert!(outputs_diverge(
&mut rnd,
&mut (noise()
^ noise()
^ noise() & zero()
^ noise()
^ (noise() >> pass())
^ noise()
^ noise())
));
assert!(outputs_diverge(
&mut rnd,
&mut (mls()
| (!zero() >> mls())
| (!zero() >> !zero() >> mls())
| (mls() >> pass() >> pass())
| (mls() >> pass())
| mls())
));
assert!(outputs_diverge(
&mut rnd,
&mut (mls() + zero() ^ (mls() >> pass())
| (mls() >> pass()) ^ mls()
| mls() & zero() & zero()
| mls())
));
assert!(outputs_diverge(
&mut rnd,
&mut ((sine_hz(1.0) >> pass())
| sine_hz(1.0)
| (sine_hz(1.0) >> pass() >> pass())
| sine_hz(1.0)
| sine_hz(1.0))
));
assert!(outputs_diverge(
&mut rnd,
&mut (sine_hz(1.0) ^ sine_hz(1.0) ^ sine_hz(1.0) | sine_hz(1.0) | sine_hz(1.0))
));
assert!(outputs_diverge(
&mut rnd,
&mut (noise() | noise() & zero() | noise() & zero() | noise())
));
assert!(outputs_diverge(
&mut rnd,
&mut (noise() ^ (!zero() >> noise()) ^ (!zero() >> noise()) ^ noise())
));
assert!(outputs_diverge(
&mut rnd,
&mut (mls() + zero() | mls() + zero() | mls() + zero())
));
assert!(outputs_diverge(&mut rnd, &mut (mls() ^ mls() ^ mls())));
assert!(outputs_diverge(
&mut rnd,
&mut (sine_hz(1.0) - zero() | sine_hz(1.0) - zero())
));
assert!(outputs_diverge(
&mut rnd,
&mut (sine_hz(1.0) ^ sine_hz(1.0))
));
assert!(outputs_diverge(&mut rnd, &mut (noise() | noise())));
assert!(outputs_diverge(&mut rnd, &mut (mls() | mls())));
assert!(outputs_diverge(&mut rnd, &mut (saw() | saw())));
assert!(outputs_diverge(&mut rnd, &mut (square() | square())));
assert!(outputs_diverge(&mut rnd, &mut (triangle() | triangle())));
assert!(outputs_diverge(&mut rnd, &mut (pulse() | pulse())));
let net1 = Net::wrap(Box::new(noise()));
let net2 = Net::wrap(Box::new(noise()));
assert!(outputs_diverge(
&mut rnd,
&mut (unit::<U0, U2>(Box::new(net1 | net2)))
));
assert_eq!(
inouts(-(-sink()) - 42.0 ^ sink() & -(-(-sink())) * 3.15),
(1, 0)
);
assert_eq!(inouts(pass() ^ pass()), (1, 2)); assert_eq!(inouts(mul(0.5) + mul(0.5)), (2, 1)); assert_eq!(inouts(pass() ^ pass() ^ pass()), (1, 3)); assert_eq!(inouts(sink() | zero()), (1, 1)); assert_eq!(inouts(mul(0.0)), (1, 1)); assert_eq!(inouts(mul(db_amp(3.0))), (1, 1)); assert_eq!(inouts(sink() | pass()), (2, 1)); assert_eq!(inouts(pass() | sink()), (2, 1)); assert_eq!(inouts(sink() | zero() | pass()), (2, 2)); assert_eq!(inouts(mul(0.0) | pass()), (2, 2)); assert_eq!(inouts(mul((0.0, 1.0))), (2, 2)); assert_eq!(inouts(pass() | sink() | zero()), (2, 2)); assert_eq!(inouts(pass() | mul(0.0)), (2, 2)); assert_eq!(inouts(mul((1.0, 0.0))), (2, 2)); assert_eq!(inouts(!butterpass() >> lowpole()), (2, 1)); assert_eq!(
inouts(!butterpass() >> !butterpass() >> butterpass()),
(2, 1)
); assert_eq!(inouts(!resonator() >> resonator()), (3, 1)); assert_eq!(inouts(sine_hz(2.0) * 2.0 * 1.0 + 2.0 >> sine()), (0, 1)); assert_eq!(inouts((pass() ^ mul(2.0)) >> sine() + sine()), (1, 1)); assert_eq!(inouts(sine() & mul(2.0) >> sine()), (1, 1)); assert_eq!(inouts(envelope(|t| exp(-t)) * noise()), (0, 1)); assert_eq!(inouts(feedback(delay(0.5) * 0.5)), (1, 1)); assert_eq!(
inouts(sine() & mul(semitone_ratio(4.0)) >> sine() & mul(semitone_ratio(7.0)) >> sine()),
(1, 1)
); assert_eq!(
inouts(
dc(midi_hz(69.0)) >> sine() & dc(midi_hz(73.0)) >> sine() & dc(midi_hz(76.0)) >> sine()
),
(0, 1)
); assert_eq!(inouts(!zero()), (0, 0)); assert_eq!(inouts(!-!!!-(-!!!-!!-(-!zero()))), (0, 0)); }
#[test]
fn test_resynth() {
let window = 32;
let mut synth: An<Resynth<U1, U1, _>> = resynth(window, |fft| {
for i in 0..fft.bins() {
fft.set(0, i, fft.at(0, i));
}
});
let duration = 16.0 / DEFAULT_SR;
let input = Wave::render(DEFAULT_SR, duration, &mut noise());
let output = input.filter_latency(duration, &mut synth);
for i in window..input.length() {
let tolerance = 1.0e-6;
assert!(
input.at(0, i) - tolerance <= output.at(0, i)
&& input.at(0, i) + tolerance >= output.at(0, i)
);
}
}
fn within(x: f32, y: f32, tolerance: f32) -> bool {
if x + tolerance >= y && x - tolerance <= y {
true
} else {
println!("x {}, y {}, tolerance {}", x, y, tolerance);
false
}
}
#[test]
fn test_convolver() {
let mut response = Wave::new(1, 44100.0);
let tolerance = 1.0e-4;
response.push(1.00);
response.push(0.75);
response.push(0.50);
response.push(0.25);
let mut convolver = convolve(&response, 0);
assert!(within(convolver.filter_mono(0.0), 0.00, tolerance));
assert!(within(convolver.filter_mono(1.0), 1.00, tolerance));
assert!(within(convolver.filter_mono(0.0), 0.75, tolerance));
assert!(within(convolver.filter_mono(0.0), 0.50, tolerance));
assert!(within(convolver.filter_mono(0.0), 0.25, tolerance));
}
#[test]
fn test_sequencer_passthrough() {
let mut sequencer = Sequencer::new(1, 1, ReplayMode::None);
sequencer.push(0.0, 1.0, Fade::Smooth, 0.0, 0.0, Box::new(pass()));
sequencer.push(
1.0 / 44100.0,
1.0,
Fade::Smooth,
0.0,
0.0,
Box::new(mul(2.0)),
);
assert!(sequencer.filter_mono(1.0) == 1.0);
assert!(sequencer.filter_mono(2.0) == 6.0);
assert!(sequencer.filter_mono(0.5) == 1.5);
}