aboutsummaryrefslogtreecommitdiffstats
path: root/mumd/src/audio/transformers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'mumd/src/audio/transformers.rs')
-rw-r--r--mumd/src/audio/transformers.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/mumd/src/audio/transformers.rs b/mumd/src/audio/transformers.rs
new file mode 100644
index 0000000..25e28b8
--- /dev/null
+++ b/mumd/src/audio/transformers.rs
@@ -0,0 +1,49 @@
+/// A trait that represents a transform of a audio buffer in some way.
+pub trait Transformer {
+ /// Do the transform. Returning `None` is interpreted as "the buffer is unwanted".
+ /// The implementor is free to modify the buffer however it wants to.
+ fn transform<'a>(&mut self, buf: &'a mut [f32]) -> Option<&'a mut [f32]>;
+}
+
+/// A struct representing a noise gate transform.
+pub struct NoiseGate {
+ alltime_high: f32,
+ open: usize,
+ deactivation_delay: usize,
+}
+
+impl NoiseGate {
+ /// Create a new noise gate. `deactivation_delay` is defined in terms of
+ /// how many quiet frames it receives before closing the noise gate.
+ pub fn new(deactivation_delay: usize) -> Self {
+ Self {
+ alltime_high: 0.0,
+ open: 0,
+ deactivation_delay,
+ }
+ }
+}
+
+impl Transformer for NoiseGate {
+ fn transform<'a>(&mut self, buf: &'a mut [f32]) -> Option<&'a mut [f32]> {
+ const MUTE_PERCENTAGE: f32 = 0.1;
+
+ let max = buf.iter().map(|e| e.abs()).max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap();
+
+ if max > self.alltime_high {
+ self.alltime_high = max;
+ }
+
+ if max > self.alltime_high * MUTE_PERCENTAGE {
+ self.open = self.deactivation_delay;
+ } else if self.open > 0 {
+ self.open -= 1;
+ }
+
+ if self.open == 0 {
+ None
+ } else {
+ Some(buf)
+ }
+ }
+}