diff options
| author | Eskil Q <eskilq@kth.se> | 2020-12-27 15:43:58 +0100 |
|---|---|---|
| committer | Eskil Q <eskilq@kth.se> | 2020-12-27 15:43:58 +0100 |
| commit | dbcc5373fab41d876f4495463d76c1ab28c9d670 (patch) | |
| tree | e65c28f2bfcbd5786c2c1da3660c7641545c2306 | |
| parent | f063ae0abc37952d718be961309a53c88ad2e0e0 (diff) | |
| download | mum-dbcc5373fab41d876f4495463d76c1ab28c9d670.tar.gz | |
create noise-gate struct
| -rw-r--r-- | Cargo.lock | 3 | ||||
| -rw-r--r-- | mumd/Cargo.toml | 3 | ||||
| -rw-r--r-- | mumd/src/audio.rs | 65 |
3 files changed, 71 insertions, 0 deletions
@@ -1161,7 +1161,10 @@ dependencies = [ "argparse", "bytes 0.5.6", "cpal", + "dasp_frame", "dasp_interpolate", + "dasp_ring_buffer", + "dasp_sample", "dasp_signal", "futures", "futures-util", diff --git a/mumd/Cargo.toml b/mumd/Cargo.toml index 7f014bd..e548559 100644 --- a/mumd/Cargo.toml +++ b/mumd/Cargo.toml @@ -23,6 +23,9 @@ bytes = "0.5" cpal = "0.13" dasp_interpolate = { version = "0.11", features = ["linear"] } dasp_signal = "0.11" +dasp_frame = "0.11" +dasp_sample = "0.11" +dasp_ring_buffer = "0.11" futures = "0.3" futures-util = "0.3" hound = "3.4" diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs index 8f9e2ab..bed9ceb 100644 --- a/mumd/src/audio.rs +++ b/mumd/src/audio.rs @@ -14,6 +14,9 @@ use std::collections::hash_map::Entry; use std::collections::{HashMap, VecDeque}; use std::sync::{Arc, Mutex}; use tokio::sync::{mpsc, watch}; +use dasp_frame::Frame; +use dasp_sample::{Sample, SignedSample}; +use dasp_ring_buffer::Fixed; //TODO? move to mumlib pub const EVENT_SOUNDS: &[(&'static [u8], NotificationEvents)] = &[ @@ -354,3 +357,65 @@ impl Audio { play_sounds.extend(samples.iter().skip(l)); } } + +struct NoiseGate<S: Signal> { + open: bool, + signal: S, + buffer: dasp_ring_buffer::Fixed<Vec<S::Frame>>, + activate_threshold: <<S::Frame as Frame>::Sample as Sample>::Float, + deactivate_threshold: <<S::Frame as Frame>::Sample as Sample>::Float, +} + +impl<S: Signal> NoiseGate<S> { + pub fn new(signal: S, activate_threshold: <<S::Frame as Frame>::Sample as Sample>::Float, deactivate_threshold: <<S::Frame as Frame>::Sample as Sample>::Float) -> NoiseGate<S> { + Self { + open: false, + signal, + buffer: Fixed::from(vec![<S::Frame as Frame>::EQUILIBRIUM; 4096]), + activate_threshold, + deactivate_threshold, + } + } +} + +impl<S: Signal> Signal for NoiseGate<S> { + type Frame = S::Frame; + + fn next(&mut self) -> Self::Frame { + let frame = self.signal.next(); + self.buffer.push(frame); + + if self.open && self.buffer + .iter() + .all(|f| f.to_float_frame() + .channels() + .all(|s| abs(s - <<<S::Frame as Frame>::Sample as Sample>::Float as Sample>::EQUILIBRIUM) <= self.deactivate_threshold)) { + self.open = false; + } else if !self.open && self.buffer + .iter() + .any(|f| f.to_float_frame() + .channels() + .any(|s| abs(s - <<<S::Frame as Frame>::Sample as Sample>::Float as Sample>::EQUILIBRIUM) >= self.activate_threshold)) { + self.open = true; + } + + if self.open { + frame + } else { + S::Frame::EQUILIBRIUM + } + } + + fn is_exhausted(&self) -> bool { + self.signal.is_exhausted() + } +} + +fn abs<S: SignedSample>(sample: S) -> S { + let zero = S::EQUILIBRIUM; + if sample >= zero { + sample + } else { + -sample + } +}
\ No newline at end of file |
