From 166571566a9e42ffd175fea2164c16977e58511f Mon Sep 17 00:00:00 2001 From: vicrodh <103399283+vicrodh@users.noreply.github.com> Date: Tue, 13 Jan 2026 08:38:24 -0600 Subject: [PATCH] perf(rodio): set fixed ALSA buffer size on linux --- src-tauri/vendor/rodio/src/stream.rs | 36 +++++++++++++++++++--------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src-tauri/vendor/rodio/src/stream.rs b/src-tauri/vendor/rodio/src/stream.rs index f4dfc35cf..ba3dfa5c3 100644 --- a/src-tauri/vendor/rodio/src/stream.rs +++ b/src-tauri/vendor/rodio/src/stream.rs @@ -7,7 +7,7 @@ use crate::dynamic_mixer::{self, DynamicMixerController}; use crate::sink::Sink; use crate::source::Source; use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; -use cpal::{Sample, SupportedStreamConfig}; +use cpal::{BufferSize, Sample, SupportedBufferSize, SupportedStreamConfig}; /// `cpal::Stream` container. Also see the more useful `OutputStreamHandle`. /// @@ -210,9 +210,23 @@ impl CpalDeviceExt for cpal::Device { let error_callback = |err| eprintln!("an error occurred on output stream: {}", err); + let mut config = format.config(); + #[cfg(target_os = "linux")] + { + if let SupportedBufferSize::Range { min, max } = *format.buffer_size() { + // Aim for ~400ms buffer to reduce wakeups during music playback. + let target_frames = + (config.sample_rate.0 as u64).saturating_mul(2).saturating_div(5); + let clamped = target_frames + .clamp(min as u64, max as u64) + .min(u32::MAX as u64) as u32; + config.buffer_size = BufferSize::Fixed(clamped); + } + } + match format.sample_format() { cpal::SampleFormat::F32 => self.build_output_stream::( - &format.config(), + &config, move |data, _| { data.iter_mut() .for_each(|d| *d = mixer_rx.next().unwrap_or(0f32)) @@ -221,7 +235,7 @@ impl CpalDeviceExt for cpal::Device { None, ), cpal::SampleFormat::F64 => self.build_output_stream::( - &format.config(), + &config, move |data, _| { data.iter_mut() .for_each(|d| *d = mixer_rx.next().map(Sample::from_sample).unwrap_or(0f64)) @@ -230,7 +244,7 @@ impl CpalDeviceExt for cpal::Device { None, ), cpal::SampleFormat::I8 => self.build_output_stream::( - &format.config(), + &config, move |data, _| { data.iter_mut() .for_each(|d| *d = mixer_rx.next().map(Sample::from_sample).unwrap_or(0i8)) @@ -239,7 +253,7 @@ impl CpalDeviceExt for cpal::Device { None, ), cpal::SampleFormat::I16 => self.build_output_stream::( - &format.config(), + &config, move |data, _| { data.iter_mut() .for_each(|d| *d = mixer_rx.next().map(Sample::from_sample).unwrap_or(0i16)) @@ -248,7 +262,7 @@ impl CpalDeviceExt for cpal::Device { None, ), cpal::SampleFormat::I32 => self.build_output_stream::( - &format.config(), + &config, move |data, _| { data.iter_mut() .for_each(|d| *d = mixer_rx.next().map(Sample::from_sample).unwrap_or(0i32)) @@ -257,7 +271,7 @@ impl CpalDeviceExt for cpal::Device { None, ), cpal::SampleFormat::I64 => self.build_output_stream::( - &format.config(), + &config, move |data, _| { data.iter_mut() .for_each(|d| *d = mixer_rx.next().map(Sample::from_sample).unwrap_or(0i64)) @@ -266,7 +280,7 @@ impl CpalDeviceExt for cpal::Device { None, ), cpal::SampleFormat::U8 => self.build_output_stream::( - &format.config(), + &config, move |data, _| { data.iter_mut().for_each(|d| { *d = mixer_rx @@ -279,7 +293,7 @@ impl CpalDeviceExt for cpal::Device { None, ), cpal::SampleFormat::U16 => self.build_output_stream::( - &format.config(), + &config, move |data, _| { data.iter_mut().for_each(|d| { *d = mixer_rx @@ -292,7 +306,7 @@ impl CpalDeviceExt for cpal::Device { None, ), cpal::SampleFormat::U32 => self.build_output_stream::( - &format.config(), + &config, move |data, _| { data.iter_mut().for_each(|d| { *d = mixer_rx @@ -305,7 +319,7 @@ impl CpalDeviceExt for cpal::Device { None, ), cpal::SampleFormat::U64 => self.build_output_stream::( - &format.config(), + &config, move |data, _| { data.iter_mut().for_each(|d| { *d = mixer_rx