aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Q <eskilq@kth.se>2020-12-27 15:43:58 +0100
committerEskil Q <eskilq@kth.se>2020-12-27 15:43:58 +0100
commitdbcc5373fab41d876f4495463d76c1ab28c9d670 (patch)
treee65c28f2bfcbd5786c2c1da3660c7641545c2306
parentf063ae0abc37952d718be961309a53c88ad2e0e0 (diff)
downloadmum-dbcc5373fab41d876f4495463d76c1ab28c9d670.tar.gz
create noise-gate struct
-rw-r--r--Cargo.lock3
-rw-r--r--mumd/Cargo.toml3
-rw-r--r--mumd/src/audio.rs65
3 files changed, 71 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 945a736..e8e5cd5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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