diff options
| author | Eskil Q <eskilq@kth.se> | 2021-01-02 09:47:14 +0100 |
|---|---|---|
| committer | Eskil Q <eskilq@kth.se> | 2021-01-02 09:47:14 +0100 |
| commit | 08e64c1b9d622026bcbe1f80d2d5d64dd80af8f9 (patch) | |
| tree | 2cc40821848edbd570d7a63e0a71eab91ab9ed40 | |
| parent | 7fbbf89cc16734e59882ab71e2aed54e4c048733 (diff) | |
| download | mum-08e64c1b9d622026bcbe1f80d2d5d64dd80af8f9.tar.gz | |
add streaming version of NoiseGate
| -rw-r--r-- | mumd/src/audio.rs | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs index 828dbc5..0a2465e 100644 --- a/mumd/src/audio.rs +++ b/mumd/src/audio.rs @@ -21,7 +21,7 @@ use futures::Stream; use futures::task::{Context, Poll}; use std::pin::Pin; use tokio_stream::StreamExt; -use std::future::Future; +use std::future::{Future}; use std::mem; //TODO? move to mumlib @@ -373,7 +373,11 @@ struct NoiseGate<S: Signal> { } 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> { + 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, @@ -417,6 +421,72 @@ impl<S: Signal> Signal for NoiseGate<S> { } } +struct StreamingNoiseGate<S: StreamingSignal> { + 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: StreamingSignal> StreamingNoiseGate<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 + ) -> StreamingNoiseGate<S> { + Self { + open: false, + signal, + buffer: Fixed::from(vec![<S::Frame as Frame>::EQUILIBRIUM; 4096]), + activate_threshold, + deactivate_threshold, + } + } +} + +impl<S> StreamingSignal for StreamingNoiseGate<S> + where + S: StreamingSignal + Unpin, + <<<S as StreamingSignal>::Frame as Frame>::Sample as Sample>::Float: Unpin, + <S as StreamingSignal>::Frame: Unpin { + type Frame = S::Frame; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Frame> { + let s = self.get_mut(); + + let frame = match S::poll_next(Pin::new(&mut s.signal), cx) { + Poll::Ready(v) => v, + Poll::Pending => return Poll::Pending, + }; + s.buffer.push(frame); + + if s.open && s.buffer + .iter() + .all(|f| f.to_float_frame() + .channels() + .all(|sample| abs(sample - <<<S::Frame as Frame>::Sample as Sample>::Float as Sample>::EQUILIBRIUM) <= s.deactivate_threshold)) { + s.open = false; + } else if !s.open && s.buffer + .iter() + .any(|f| f.to_float_frame() + .channels() + .any(|sample| abs(sample - <<<S::Frame as Frame>::Sample as Sample>::Float as Sample>::EQUILIBRIUM) >= s.activate_threshold)) { + s.open = true; + } + + if s.open { + Poll::Ready(frame) + } else { + Poll::Ready(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 { |
