1pub struct NoiseGate {
14 open_threshold: f32,
16 close_threshold: f32,
18 sample_rate: f32,
20 release_rate: f32,
22 attack_rate: f32,
24 decay_rate: f32,
25 hold_time: f32,
27 channels: usize,
29 is_open: bool,
30 attenuation: f32,
31 level: f32,
32 held_time: f32,
33}
34
35impl NoiseGate {
36 pub fn new(
38 open_threshold: f32,
39 close_threshold: f32,
40 sample_rate: f32,
41 channels: usize,
42 release_rate: f32,
43 attack_rate: f32,
44 hold_time: f32
45 ) -> Self {
46 let threshold_diff = open_threshold - close_threshold;
47 let min_decay_period = (1.0 / 75.0) * sample_rate;
48
49 Self {
50 open_threshold: match open_threshold.is_finite() {
51 true => (10_f32).powf(open_threshold / 20.0),
52 false => 0.0,
53 },
54 close_threshold: match close_threshold.is_finite() {
55 true => (10_f32).powf(close_threshold / 20.0),
56 false => 0.0,
57 },
58 sample_rate: 1.0 / sample_rate,
59 channels: channels,
60 release_rate: 1.0 / (release_rate * 0.001 * sample_rate),
61 attack_rate: 1.0 / (attack_rate * 0.001 * sample_rate),
62 decay_rate: threshold_diff / min_decay_period,
63 hold_time: hold_time * 0.001,
64 is_open: false,
65 attenuation: 0.0,
66 level: 0.0,
67 held_time: 0.0,
68 }
69 }
70
71 pub fn update(
72 &mut self,
73 open_threshold: f32,
74 close_threshold: f32,
75 release_rate: f32,
76 attack_rate: f32,
77 hold_time: f32
78 ) {
79 let threshold_diff = open_threshold - close_threshold;
80 let min_decay_period = (1.0 / 75.0) * self.sample_rate;
81
82 self.open_threshold = match open_threshold.is_finite() {
83 true => (10_f32).powf(open_threshold / 20.0),
84 false => 0.0,
85 };
86 self.close_threshold = match close_threshold.is_finite() {
87 true => (10_f32).powf(close_threshold / 20.0),
88 false => 0.0,
89 };
90 self.release_rate = 1.0 / (release_rate * 0.001 * self.sample_rate);
91 self.attack_rate = 1.0 / (attack_rate * 0.001 * self.sample_rate);
92 self.decay_rate = threshold_diff / min_decay_period;
93 self.hold_time = hold_time * 0.001;
94 }
95
96 pub fn process_frame(&mut self, frame: &[f32]) -> Vec<f32> {
98 let mut channel_frames = Vec::<Vec<f32>>::new();
99 for _ in 0..self.channels {
100 channel_frames.push(Vec::<f32>::with_capacity(frame.len() / self.channels));
101 }
102
103 for c in 0..self.channels {
104 for (_, u) in frame.iter().enumerate().skip(c).step_by(self.channels) {
105 channel_frames[c].push(*u);
106 }
107 }
108
109 let mut resample = Vec::<f32>::with_capacity(frame.len());
110
111 for i in 0..channel_frames[0].len() {
112 let mut current_level = f32::abs(channel_frames[0][i]);
113
114 for j in 0..self.channels {
115 current_level = f32::max(current_level, channel_frames[j][i]);
116 }
117
118 if current_level > self.open_threshold && !self.is_open {
119 self.is_open = true;
120 }
121
122 if self.level < self.close_threshold && self.is_open {
123 self.held_time = 0.0;
124 self.is_open = false;
125 }
126
127 self.level = f32::max(self.level, current_level) - self.decay_rate;
128
129 if self.is_open {
130 self.attenuation = f32::min(1.0, self.attenuation + self.attack_rate);
131 } else {
132 self.held_time += self.sample_rate;
133 if self.held_time > self.hold_time {
134 self.attenuation = f32::max(0.0, self.attenuation - self.release_rate);
135 }
136 }
137
138 for c in 0..self.channels {
139 channel_frames[c][i] *= self.attenuation;
140 }
141 }
142
143 for i in 0..channel_frames[0].len() {
147 for c in 0..self.channels {
148 resample.push(channel_frames[c][i]);
149 }
150 }
151
152 return resample.into();
153 }
154}