use rill_core::math::Transcendental;
use rill_core::traits::algorithm::Algorithm;
use rill_core_dsp::{
effect_algorithm, filter_algorithm, generator_algorithm, parameterized_algorithm,
simple_algorithm,
};
#[test]
fn test_simple_algorithm_f32() {
simple_algorithm! {
#[derive(Debug, Clone, Copy)]
pub struct TestGain<T: Transcendental> {
params: {
gain: T = T::from_f32(2.0),
},
state: {
last: T = T::ZERO,
},
process: |this, input| {
let out = input * this.gain;
this.last = out;
out
}
}
}
let mut gain = TestGain::<f32>::new(2.0);
let mut output = [0.0f32; 1];
gain.process(Some(&[1.0f32] as &[_]), &mut output).unwrap();
assert_eq!(output[0], 2.0);
assert_eq!(gain.last, 2.0);
}
#[test]
fn test_simple_algorithm_f64() {
simple_algorithm! {
#[derive(Debug, Clone, Copy)]
pub struct TestGain<T: Transcendental> {
params: {
gain: T = T::from_f32(2.0),
},
state: {
last: T = T::ZERO,
},
process: |this, input| {
let out = input * this.gain;
this.last = out;
out
}
}
}
let mut gain = TestGain::<f64>::new(2.0);
let mut output = [0.0f64; 1];
gain.process(Some(&[1.0] as &[_]), &mut output).unwrap();
assert_eq!(output[0], 2.0);
assert!((gain.last - 2.0).abs() < 1e-10);
}
#[test]
fn test_parameterized_algorithm() {
parameterized_algorithm! {
#[derive(Debug, Clone, Copy)]
pub struct TestParam<T: Transcendental> {
params: {
value: T = T::from_f32(1.0),
},
state: {
last: T = T::ZERO,
},
update: |_this| {
},
process: |this, input| {
let out = input * this.value;
this.last = out;
out
}
}
}
let mut algo = TestParam::<f32>::new(2.0);
let mut output = [0.0f32; 1];
algo.process(Some(&[1.0f32] as &[_]), &mut output).unwrap();
assert_eq!(output[0], 2.0);
}
#[test]
fn test_filter_algorithm() {
filter_algorithm! {
#[derive(Debug, Clone, Copy)]
pub struct TestFilter<T: Transcendental> {
params: {
cutoff: T = T::from_f32(1000.0),
q: T = T::from_f32(0.707),
},
coeffs: {
b0: T = T::ZERO,
b1: T = T::ZERO,
b2: T = T::ZERO,
a1: T = T::ZERO,
a2: T = T::ZERO,
},
state: {
x1: T = T::ZERO,
x2: T = T::ZERO,
y1: T = T::ZERO,
y2: T = T::ZERO,
},
update_coeffs: |this| {
this.b0 = T::ONE;
this.b1 = T::ZERO;
this.b2 = T::ZERO;
this.a1 = T::ZERO;
this.a2 = T::ZERO;
},
process: |_this, input| {
input
}
}
}
let mut filter = TestFilter::<f32>::new(1000.0, 0.707);
filter.init(44100.0);
let mut output = [0.0f32; 1];
filter
.process(Some(&[1.0f32] as &[_]), &mut output)
.unwrap();
assert_eq!(output[0], 1.0);
}
#[test]
fn test_effect_algorithm_f32() {
effect_algorithm! {
#[derive(Debug, Clone, Copy)]
pub struct TestEffect<T: Transcendental> {
params: {
amount: T = T::from_f32(0.5),
},
state: {
last: T = T::ZERO,
},
wet: T::from_f32(0.3),
process: |this, input| {
let out = input * this.amount;
this.last = out;
out
}
}
}
let mut effect = TestEffect::<f32>::new(0.5);
effect.set_wet(0.7);
let mut output = [0.0f32; 1];
effect
.process(Some(&[1.0f32] as &[_]), &mut output)
.unwrap();
let expected = 0.5 * 1.0 * 0.7 + 1.0 * 0.3;
assert!((output[0] - expected).abs() < 1e-6);
}
#[test]
fn test_effect_algorithm_f64() {
effect_algorithm! {
#[derive(Debug, Clone, Copy)]
pub struct TestEffect<T: Transcendental> {
params: {
amount: T = T::from_f32(0.5),
},
state: {
last: T = T::ZERO,
},
wet: T::from_f32(0.3),
process: |this, input| {
let out = input * this.amount;
this.last = out;
out
}
}
}
let mut effect = TestEffect::<f64>::new(0.5);
effect.set_wet(0.7);
let mut output = [0.0f64; 1];
effect.process(Some(&[1.0] as &[_]), &mut output).unwrap();
let expected = 0.5 * 1.0 * 0.7 + 1.0 * 0.3;
assert!((output[0] - expected).abs() < 1e-10);
}
#[test]
fn test_generator_algorithm_f32() {
generator_algorithm! {
#[derive(Debug, Clone, Copy)]
pub struct TestGen<T: Transcendental> {
params: {
value: T = T::from_f32(1.0),
},
state: {
counter: i32 = 0,
},
generate: |this| {
this.counter += 1;
this.value
}
}
}
let mut gen = TestGen::<f32>::new(1.0);
let mut output = [0.0f32; 1];
gen.process(None, &mut output).unwrap();
assert_eq!(output[0], 1.0);
assert_eq!(gen.counter, 1);
}
#[test]
fn test_generator_algorithm_f64() {
generator_algorithm! {
#[derive(Debug, Clone, Copy)]
pub struct TestGen<T: Transcendental> {
params: {
value: T = T::from_f32(1.0),
},
state: {
counter: i32 = 0,
},
generate: |this| {
this.counter += 1;
this.value
}
}
}
let mut gen = TestGen::<f64>::new(1.0);
let mut output = [0.0f64; 1];
gen.process(None, &mut output).unwrap();
assert_eq!(output[0], 1.0);
assert_eq!(gen.counter, 1);
}