@@ -161,12 +161,14 @@ impl Audio {
.default_device()?
.default_config()?
.prefer_sample_rates([SAMPLE_RATE, SAMPLE_RATE.saturating_mul(nz!(2))])
- // .prefer_channel_counts([nz!(1), nz!(2)])
+ .prefer_channel_counts([nz!(1), nz!(2)])
.prefer_buffer_sizes(512..)
.open_stream()?;
info!("Opened microphone: {:?}", stream.config());
- let (replay, stream) = UniformSourceIterator::new(stream, CHANNEL_COUNT, SAMPLE_RATE)
+ let (replay, stream) = stream
+ // .suspicious_stereo_to_mono()
+ .constant_params(CHANNEL_COUNT, SAMPLE_RATE)
.limit(LimitSettings::live_performance())
.process_buffer::<BUFFER_SIZE, _>(move |buffer| {
let mut int_buffer: [i16; _] = buffer.map(|s| s.to_sample());
@@ -1,4 +1,5 @@
use std::{
+ f32,
sync::{
Arc, Mutex,
atomic::{AtomicBool, Ordering},
@@ -25,6 +26,13 @@ pub trait RodioExt: Source + Sized {
duration: Duration,
) -> Result<(Replay, Replayable<Self>), ReplayDurationTooShort>;
fn take_samples(self, n: usize) -> TakeSamples<Self>;
+ fn denoise(self) -> Result<Denoiser<Self>, DenoiserError>;
+ fn constant_params(
+ self,
+ channel_count: ChannelCount,
+ sample_rate: SampleRate,
+ ) -> UniformSourceIterator<Self>;
+ fn suspicious_stereo_to_mono(self) -> ToMono<Self>;
}
impl<S: Source> RodioExt for S {
@@ -101,8 +109,88 @@ impl<S: Source> RodioExt for S {
left_to_take: n,
}
}
+ fn denoise(self) -> Result<Denoiser<Self>, DenoiserError> {
+ let res = Denoiser::try_new(self);
+ log::info!("result of new: {res:?}");
+ res
+ }
+ fn constant_params(
+ self,
+ channel_count: ChannelCount,
+ sample_rate: SampleRate,
+ ) -> UniformSourceIterator<Self> {
+ UniformSourceIterator::new(self, channel_count, sample_rate)
+ }
+ fn suspicious_stereo_to_mono(self) -> ToMono<Self> {
+ ToMono {
+ input_channel_count: self.channels(),
+ inner: self,
+ mean: f32::EPSILON * 3.0,
+ }
+ }
+}
+
+/// constant source, only works on a single span
+pub struct ToMono<S> {
+ inner: S,
+ input_channel_count: ChannelCount,
+ /// running mean of second channel 'volume'
+ mean: f32,
+}
+impl<S> ToMono<S> {
+ fn real_stereo(&self) -> bool {
+ dbg!(self.mean);
+ dbg!(self.mean >= f32::EPSILON * 3.0)
+ }
+
+ fn update_mean(&mut self, second_channel: Sample) {
+ const HISTORY: f32 = 500.0;
+ self.mean *= (HISTORY - 1.0) / HISTORY;
+ self.mean += second_channel.abs() / HISTORY;
+ }
+}
+
+impl<S: Source> Source for ToMono<S> {
+ fn current_span_len(&self) -> Option<usize> {
+ None
+ }
+
+ fn channels(&self) -> ChannelCount {
+ rodio::nz!(1)
+ }
+
+ fn sample_rate(&self) -> SampleRate {
+ self.inner.sample_rate()
+ }
+
+ fn total_duration(&self) -> Option<Duration> {
+ self.inner.total_duration()
+ }
+}
+
+impl<S: Source> Iterator for ToMono<S> {
+ type Item = Sample;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.input_channel_count.get() {
+ 1 => self.next(),
+ 2 => {
+ let first_channel = self.next()?;
+ let second_channel = self.next()?;
+ self.update_mean(second_channel);
+
+ if self.real_stereo() {
+ Some((first_channel + second_channel) / 2.0)
+ } else {
+ Some(first_channel)
+ }
+ }
+ _ => todo!("unsupported channel count"),
+ }
+ }
}
+/// constant source, only works on a single span
pub struct TakeSamples<S> {
inner: S,
left_to_take: usize,
@@ -147,6 +235,7 @@ impl<S: Source> Source for TakeSamples<S> {
}
}
+/// constant source, only works on a single span
#[derive(Debug)]
struct ReplayQueue {
inner: ArrayQueue<Vec<Sample>>,
@@ -193,6 +282,7 @@ impl ReplayQueue {
}
}
+/// constant source, only works on a single span
pub struct ProcessBuffer<const N: usize, S, F>
where
S: Source + Sized,
@@ -260,6 +350,7 @@ where
}
}
+/// constant source, only works on a single span
pub struct InspectBuffer<const N: usize, S, F>
where
S: Source + Sized,
@@ -324,6 +415,7 @@ where
}
}
+/// constant source, only works on a single span
#[derive(Debug)]
pub struct Replayable<S: Source> {
inner: S,
@@ -375,6 +467,7 @@ impl<S: Source> Source for Replayable<S> {
}
}
+/// constant source, only works on a single span
#[derive(Debug)]
pub struct Replay {
rx: Arc<ReplayQueue>,