diff --git a/src/host/alsa/mod.rs b/src/host/alsa/mod.rs index bce4549ed..6ebc6eb7e 100644 --- a/src/host/alsa/mod.rs +++ b/src/host/alsa/mod.rs @@ -189,7 +189,7 @@ impl Device { let hw_params = set_hw_params_from_format(&handle, conf, sample_format)?; hw_params.can_pause() }; - let (_buffer_len, period_len) = set_sw_params_from_format(&handle, conf)?; + let (_buffer_len, period_len) = set_sw_params_from_format(&handle, conf, stream_type)?; handle.prepare()?; @@ -211,7 +211,12 @@ impl Device { _ => None, }; - handle.start()?; + // For capture streams, starts can't be delayed until the + // read calls since the input_stream_worker won't call those + // if the pcm is not started + if stream_type == alsa::Direction::Capture { + handle.start()? + } let stream_inner = StreamInner { channel: handle, @@ -905,9 +910,9 @@ fn set_hw_params_from_format<'a>( fn set_sw_params_from_format( pcm_handle: &alsa::pcm::PCM, config: &StreamConfig, + stream_type: alsa::Direction, ) -> Result<(usize, usize), BackendSpecificError> { let sw_params = pcm_handle.sw_params_current()?; - sw_params.set_start_threshold(0)?; let (buffer_len, period_len) = { let (buffer, period) = pcm_handle.get_params()?; @@ -916,6 +921,14 @@ fn set_sw_params_from_format( description: "initialization resulted in a null buffer".to_string(), }); } + match stream_type { + alsa::Direction::Playback => { + // Don't start playback until the buffer is filled + sw_params.set_start_threshold((buffer - period) as alsa::pcm::Frames)? + } + // For capture streams rely on an explicit start + alsa::Direction::Capture => sw_params.set_start_threshold(i32::MAX.into())?, + } sw_params.set_avail_min(period as alsa::pcm::Frames)?; let buffer = buffer as usize * config.channels as usize; let period = period as usize * config.channels as usize;