wavecraft_dsp/
processor.rs1use crate::gain::db_to_linear;
7
8pub struct GainProcessor {
15 sample_rate: f32,
16}
17
18impl GainProcessor {
19 pub fn new(sample_rate: f32) -> Self {
24 Self { sample_rate }
25 }
26
27 pub fn set_sample_rate(&mut self, sample_rate: f32) {
34 self.sample_rate = sample_rate;
35 }
36
37 #[inline]
39 pub fn sample_rate(&self) -> f32 {
40 self.sample_rate
41 }
42
43 #[inline]
57 pub fn process(&self, left: &mut [f32], right: &mut [f32], gain_db: f32) {
58 debug_assert_eq!(
59 left.len(),
60 right.len(),
61 "Left and right buffers must have equal length"
62 );
63
64 let gain_linear = db_to_linear(gain_db);
65
66 for sample in left.iter_mut() {
68 *sample *= gain_linear;
69 }
70
71 for sample in right.iter_mut() {
73 *sample *= gain_linear;
74 }
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn test_passthrough_at_0db() {
84 let processor = GainProcessor::new(44100.0);
85 let mut left = [0.5, -0.5, 0.25, -0.25];
86 let mut right = [0.3, -0.3, 0.1, -0.1];
87
88 let left_original = left;
89 let right_original = right;
90
91 processor.process(&mut left, &mut right, 0.0);
92
93 for (i, (l, r)) in left.iter().zip(right.iter()).enumerate() {
94 assert!(
95 (l - left_original[i]).abs() < 1e-6,
96 "Left sample {} changed at 0dB gain",
97 i
98 );
99 assert!(
100 (r - right_original[i]).abs() < 1e-6,
101 "Right sample {} changed at 0dB gain",
102 i
103 );
104 }
105 }
106
107 #[test]
108 fn test_gain_applied() {
109 let processor = GainProcessor::new(44100.0);
110 let mut left = [1.0, 1.0, 1.0, 1.0];
111 let mut right = [1.0, 1.0, 1.0, 1.0];
112
113 processor.process(&mut left, &mut right, -6.0);
115
116 let expected_gain = db_to_linear(-6.0);
117 for (i, (l, r)) in left.iter().zip(right.iter()).enumerate() {
118 assert!(
119 (l - expected_gain).abs() < 0.001,
120 "Left sample {} has incorrect gain",
121 i
122 );
123 assert!(
124 (r - expected_gain).abs() < 0.001,
125 "Right sample {} has incorrect gain",
126 i
127 );
128 }
129 }
130
131 #[test]
132 fn test_negative_gain() {
133 let processor = GainProcessor::new(44100.0);
134 let mut left = [1.0];
135 let mut right = [1.0];
136
137 processor.process(&mut left, &mut right, -12.0);
138
139 let expected = db_to_linear(-12.0);
140 assert!(
141 (left[0] - expected).abs() < 0.001,
142 "Attenuation not applied correctly"
143 );
144 }
145
146 #[test]
147 fn test_positive_gain() {
148 let processor = GainProcessor::new(44100.0);
149 let mut left = [0.5];
150 let mut right = [0.5];
151
152 processor.process(&mut left, &mut right, 6.0);
153
154 let expected = 0.5 * db_to_linear(6.0);
155 assert!(
156 (left[0] - expected).abs() < 0.001,
157 "Boost not applied correctly"
158 );
159 }
160
161 #[test]
162 fn test_sample_rate_update() {
163 let mut processor = GainProcessor::new(44100.0);
164 assert!((processor.sample_rate() - 44100.0).abs() < 1e-6);
165
166 processor.set_sample_rate(48000.0);
167 assert!((processor.sample_rate() - 48000.0).abs() < 1e-6);
168 }
169}