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