diff --git a/lightningbeam-core/src/audio.rs b/lightningbeam-core/src/audio.rs index 92d157d..a81867a 100644 --- a/lightningbeam-core/src/audio.rs +++ b/lightningbeam-core/src/audio.rs @@ -57,6 +57,9 @@ impl StutterDetector { scheduling_threshold: AtomicU32::new(1200), // 1.2 stored in fixed point } } + pub fn reset(&mut self) { + *self = Self::new(); + } fn get_scheduling_threshold(&self) -> f32 { self.scheduling_threshold.load(Ordering::Relaxed) as f32 / 1000.0 } @@ -201,7 +204,7 @@ impl CpalAudioOutput { history.iter().sum::() / history.len() as u32 } }; - + // log::info!("Average delay: {:?}", avg_delay); // Determine stutter @@ -246,50 +249,58 @@ impl CpalAudioOutput { err_fn, None, )?; - + // Update current buffer size after stream creation let detector = self.stutter_detector.lock().unwrap(); detector.current_buffer_size.store(clamped_buffer_size, Ordering::Relaxed); Ok(stream) } - + fn recreate_stream(&mut self) -> Result<(), Box> { // Stop and destroy old stream first if let Some(old_stream) = self._stream.take() { - old_stream.pause()?; - // Explicitly drop the stream - drop(old_stream); + old_stream.pause()?; + // Explicitly drop the stream + drop(old_stream); } - + // Add a small delay to ensure resources are freed (especially important in WASM) #[cfg(not(target_arch = "wasm32"))] std::thread::sleep(std::time::Duration::from_millis(50)); #[cfg(target_arch = "wasm32")] { - use wasm_bindgen_futures::spawn_local; - use gloo_timers::future::sleep; - spawn_local(async { - sleep(std::time::Duration::from_millis(50)).await; - }); + use wasm_bindgen_futures::spawn_local; + use gloo_timers::future::sleep; + spawn_local(async { + sleep(std::time::Duration::from_millis(50)).await; + }); } - + // Recreate stream with current configuration let host = cpal::default_host(); let device = host.default_output_device() - .ok_or_else(|| "No output device available")?; + .ok_or_else(|| "No output device available")?; let supported_config = device.default_output_config()?; + { + let mut detector = self.stutter_detector.lock().unwrap(); + let desired_buffer_size = detector.desired_buffer_size.load(Ordering::Relaxed); + detector.reset(); + detector.desired_buffer_size.store(desired_buffer_size, Ordering::Relaxed); + } + // let mut history = detector.delay_history.lock().unwrap(); + self._stream = Some(self.build_stream::(&device, supported_config)?); // Restart playback if needed if self.audio_state == AudioState::Running { - self._stream.as_ref().unwrap().play()?; + self._stream.as_ref().unwrap().play()?; } - + Ok(()) -} + } } impl AudioOutput for CpalAudioOutput { diff --git a/src/pkg/lightningbeam_core.js b/src/pkg/lightningbeam_core.js index 42bafa0..d18ce67 100644 --- a/src/pkg/lightningbeam_core.js +++ b/src/pkg/lightningbeam_core.js @@ -624,7 +624,7 @@ function __wbg_get_imports() { const ret = false; return ret; }; - imports.wbg.__wbindgen_closure_wrapper207 = function(arg0, arg1, arg2) { + imports.wbg.__wbindgen_closure_wrapper208 = function(arg0, arg1, arg2) { const ret = makeMutClosure(arg0, arg1, 82, __wbg_adapter_20); return addHeapObject(ret); }; diff --git a/src/pkg/lightningbeam_core_bg.wasm b/src/pkg/lightningbeam_core_bg.wasm index e80499d..dc07e5d 100644 Binary files a/src/pkg/lightningbeam_core_bg.wasm and b/src/pkg/lightningbeam_core_bg.wasm differ