diff --git a/crates/livekit_client/src/livekit_client/playback.rs b/crates/livekit_client/src/livekit_client/playback.rs index c7882e1f20..c6b317e37f 100644 --- a/crates/livekit_client/src/livekit_client/playback.rs +++ b/crates/livekit_client/src/livekit_client/playback.rs @@ -265,6 +265,9 @@ impl AudioStack { num_channels: u32, ) -> Result<()> { use crate::livekit_client::playback::source::RodioExt; + const NUM_CHANNELS: usize = 1; + const LIVEKIT_BUFFER_SIZE: usize = (SAMPLE_RATE as usize / 100) * NUM_CHANNELS as usize; + thread::spawn(move || { let stream = rodio::microphone::MicrophoneBuilder::new() .default_device()? @@ -276,7 +279,7 @@ impl AudioStack { NonZero::new(SAMPLE_RATE).expect("constant is not zero"), ) .limit(LimitSettings::live_performance()) - .process_buffer(|buffer| { + .process_buffer::(|buffer| { let mut int_buffer: [i16; _] = buffer.map(|s| s.to_sample()); apm.lock() .process_stream(&mut int_buffer, sample_rate as i32, num_channels as i32) @@ -288,7 +291,11 @@ impl AudioStack { .automatic_gain_control(1.0, 4.0, 0.0, 5.0); loop { - let sampled = stream.by_ref().take(1000).map(|s| s.to_sample()).collect(); + let sampled = stream + .by_ref() + .take(LIVEKIT_BUFFER_SIZE) + .map(|s| s.to_sample()) + .collect(); if frame_tx .unbounded_send(AudioFrame { diff --git a/crates/livekit_client/src/livekit_client/playback/source.rs b/crates/livekit_client/src/livekit_client/playback/source.rs index b54bc7e821..89e1fd0b21 100644 --- a/crates/livekit_client/src/livekit_client/playback/source.rs +++ b/crates/livekit_client/src/livekit_client/playback/source.rs @@ -73,40 +73,40 @@ impl Source for LiveKitStream { } pub trait RodioExt: Source + Sized { - fn process_buffer(self, callback: F) -> ProcessBuffer + fn process_buffer(self, callback: F) -> ProcessBuffer where - F: FnMut(&mut [rodio::Sample; 200]); + F: FnMut(&mut [rodio::Sample; N]); } impl RodioExt for S { - fn process_buffer(self, callback: F) -> ProcessBuffer + fn process_buffer(self, callback: F) -> ProcessBuffer where - F: FnMut(&mut [rodio::Sample; 200]), + F: FnMut(&mut [rodio::Sample; N]), { ProcessBuffer { inner: self, callback, - buffer: [0.0; 200], - next: 200, + buffer: [0.0; N], + next: N, } } } -pub struct ProcessBuffer +pub struct ProcessBuffer where S: Source + Sized, - F: FnMut(&mut [rodio::Sample; 200]), + F: FnMut(&mut [rodio::Sample; N]), { inner: S, callback: F, - buffer: [rodio::Sample; 200], + buffer: [rodio::Sample; N], next: usize, } -impl Iterator for ProcessBuffer +impl Iterator for ProcessBuffer where S: Source + Sized, - F: FnMut(&mut [rodio::Sample; 200]), + F: FnMut(&mut [rodio::Sample; N]), { type Item = rodio::Sample; @@ -128,10 +128,10 @@ where } // TODO dvdsk this should be a spanless Source -impl Source for ProcessBuffer +impl Source for ProcessBuffer where S: Source + Sized, - F: FnMut(&mut [rodio::Sample; 200]), + F: FnMut(&mut [rodio::Sample; N]), { fn current_span_len(&self) -> Option { None