1use crate::algorithm::ParameterizedAlgorithm;
4use rill_core::Transcendental;
5
6pub trait Effect<T: Transcendental>: ParameterizedAlgorithm<T> {
8 fn num_inputs(&self) -> usize {
10 1
11 }
12
13 fn num_outputs(&self) -> usize {
15 1
16 }
17
18 fn process_stereo(&mut self, left: T, right: T) -> (T, T) {
20 let input = [left, right];
21 let mut output = [T::ZERO, T::ZERO];
22 let _ = self.process(Some(&input), &mut output);
23 (output[0], output[1])
24 }
25
26 fn process_block_vector(&mut self, input: &[T], output: &mut [T]) {
28 let _ = self.process(Some(input), output);
29 }
30}
31
32pub trait Bypassable<T: Transcendental>: Effect<T> {
34 fn set_bypass(&mut self, bypass: bool);
36
37 fn bypass(&self) -> bool;
39
40 fn process_with_bypass(&mut self, input: T) -> T {
42 if self.bypass() {
43 input
44 } else {
45 let mut output = [T::ZERO];
46 let _ = self.process(Some(&[input]), &mut output);
47 output[0]
48 }
49 }
50}
51
52pub trait DryWet<T: Transcendental>: Effect<T> {
54 fn set_dry_wet(&mut self, mix: f32);
56
57 fn dry_wet(&self) -> f32;
59
60 fn process_with_dry_wet(&mut self, input: T, dry: T) -> T {
62 let mut wet = [T::ZERO];
63 let _ = self.process(Some(&[input]), &mut wet);
64 let mix = T::from_f32(self.dry_wet());
65 let one_minus_mix = T::from_f32(1.0 - self.dry_wet());
66
67 dry.mul(one_minus_mix).add(wet[0].mul(mix))
68 }
69}
70
71pub trait Modulatable<T: Transcendental>: Effect<T> {
73 fn num_mod_inputs(&self) -> usize;
75
76 fn apply_modulation(&mut self, index: usize, value: T);
78
79 fn modulation_depth(&self, index: usize) -> f32;
81
82 fn set_modulation_depth(&mut self, index: usize, depth: f32);
84}