aboutsummaryrefslogtreecommitdiffstats
path: root/mumd/src/audio
diff options
context:
space:
mode:
authorEskil Queseth <eskilq@kth.se>2021-06-12 16:47:36 +0200
committerEskil Queseth <eskilq@kth.se>2021-06-12 16:47:36 +0200
commit5b2e2c4e266c61f35f7bcfbc603e02070b54e7d0 (patch)
treea772b2f3e1d7f1a67cb3bf6c8bf328c42e4b7e2b /mumd/src/audio
parent3cb2c612fb030278aaf5e4d49d42cf689bdc9cc0 (diff)
downloadmum-5b2e2c4e266c61f35f7bcfbc603e02070b54e7d0.tar.gz
FnMut -> Trait
Diffstat (limited to 'mumd/src/audio')
-rw-r--r--mumd/src/audio/input.rs10
-rw-r--r--mumd/src/audio/transformers.rs46
2 files changed, 41 insertions, 15 deletions
diff --git a/mumd/src/audio/input.rs b/mumd/src/audio/input.rs
index b0e621b..9c2d93c 100644
--- a/mumd/src/audio/input.rs
+++ b/mumd/src/audio/input.rs
@@ -4,13 +4,13 @@ use log::*;
use tokio::sync::watch;
use crate::audio::SAMPLE_RATE;
-use crate::audio::transformers::{create_noise_gate};
+use crate::audio::transformers::{NoiseGate, Transformer};
use crate::error::{AudioError, AudioStream};
use crate::state::StatePhase;
pub fn callback<T: Sample>(
mut input_sender: futures_channel::mpsc::Sender<Vec<u8>>,
- mut transformers: Vec<Box<dyn FnMut(&mut [f32]) -> Option<&mut [f32]> + Send + 'static>>,
+ mut transformers: Vec<Box<dyn Transformer + Send + 'static>>,
frame_size: u32,
sample_rate: u32,
channels: u16,
@@ -41,7 +41,7 @@ pub fn callback<T: Sample>(
buffer.extend(data.by_ref().take(buffer_size - buffer.len()));
let encoded = transformers
.iter_mut()
- .try_fold(&mut buffer[..], |acc, e| e(acc))
+ .try_fold(&mut buffer[..], |acc, e| e.transform(acc))
.map(|buf| opus_encoder.encode_vec_float(&*buf, buffer_size).unwrap());
if let Some(encoded) = encoded {
@@ -74,7 +74,7 @@ impl DefaultAudioInputDevice {
pub fn new(
input_volume: f32,
phase_watcher: watch::Receiver<StatePhase>,
- frame_size: u32,
+ frame_size: u32, // blocks of 2.5 ms
) -> Result<Self, AudioError> {
let sample_rate = SampleRate(SAMPLE_RATE);
@@ -104,7 +104,7 @@ impl DefaultAudioInputDevice {
let (volume_sender, input_volume_receiver) = watch::channel::<f32>(input_volume);
- let transformers = vec![Box::new(create_noise_gate(10, 0.6)) as Box<dyn FnMut(&mut [f32]) -> Option<&mut [f32]> + Send + 'static>];
+ let transformers = vec![Box::new(NoiseGate::new(200)) as Box<dyn Transformer + Send + 'static>];
let input_stream = match input_supported_sample_format {
SampleFormat::F32 => input_device.build_input_stream(
diff --git a/mumd/src/audio/transformers.rs b/mumd/src/audio/transformers.rs
index 5c9681b..6994a40 100644
--- a/mumd/src/audio/transformers.rs
+++ b/mumd/src/audio/transformers.rs
@@ -1,17 +1,43 @@
-use dasp_ring_buffer::Bounded;
+pub trait Transformer {
+ fn transform<'a>(&mut self, buf: &'a mut [f32]) -> Option<&'a mut [f32]>;
+}
+
+pub struct NoiseGate {
+ alltime_high: f32,
+ open: usize,
+ deactivation_delay: usize,
+}
+
+impl NoiseGate {
+ 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;
-pub fn create_noise_gate(chunks: usize, mute_percentage: f32) -> impl FnMut(&mut [f32]) -> Option<&mut [f32]> {
- let mut peaks = Bounded::from_full(vec![0.0; chunks]);
- let mut alltime_high: f32 = 0.0;
- move |buf: &mut [f32]| {
let max = buf.iter().map(|e| e.abs()).max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap();
- peaks.push(max);
- alltime_high = alltime_high.max(max);
- if peaks.iter().any(|e| *e >= alltime_high * mute_percentage) {
- Some(buf)
- } else {
+
+ 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)
}
}
}