From 40540a150221b45be507f3a442b3d19ba3ba9742 Mon Sep 17 00:00:00 2001 From: David Reid Date: Sun, 10 May 2026 15:00:27 +1000 Subject: [PATCH] PulseAudio: Fix a format negotiation error. This addresses a case when PulseAudio may negotiate S24_32 which is not a format supported by miniaudio. This commit does two things to guard against this: * The requested format is now explicitly used instead of using the queried format from `pa_context_get_source_info_by_name()`. * The `PA_STREAM_FIX_FORMAT` stream flag is no longer used as that can possibly negotiate something different to what we request. I.e., it can possibly give us S24_32 which is not usable. --- miniaudio.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/miniaudio.h b/miniaudio.h index 509d7403..b6b68790 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -31080,7 +31080,6 @@ static ma_result ma_result_from_pulse(int result) } } -#if 0 static ma_pa_sample_format_t ma_format_to_pulse(ma_format format) { if (ma_is_little_endian()) { @@ -31107,7 +31106,6 @@ static ma_pa_sample_format_t ma_format_to_pulse(ma_format format) default: return MA_PA_SAMPLE_INVALID; } } -#endif static ma_format ma_format_from_pulse(ma_pa_sample_format_t format) { @@ -32140,6 +32138,9 @@ static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_confi ss = sourceInfo.sample_spec; cmap = sourceInfo.channel_map; + /* Use the requested format if we have one. */ + ss.format = ma_format_to_pulse(pDescriptorCapture->format); + /* Use the requested channel count if we have one. */ if (pDescriptorCapture->channels != 0) { ss.channels = pDescriptorCapture->channels; @@ -32165,7 +32166,7 @@ static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_confi } else { ss.format = MA_PA_SAMPLE_FLOAT32BE; } - streamFlags |= MA_PA_STREAM_FIX_FORMAT; + /*streamFlags |= MA_PA_STREAM_FIX_FORMAT;*/ /* Using PA_STREAM_FIX_FORMAT will make it so PulseAudio can possibly pick S24_32 which is not supported by miniaudio and will thus result in an error later on. By excluding it, PulseAudio should always pick F32. */ ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[PulseAudio] sample_spec.format not supported by miniaudio. Defaulting to PA_SAMPLE_FLOAT32.\n"); } if (ss.rate == 0) { @@ -32297,6 +32298,9 @@ static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_confi ss = sinkInfo.sample_spec; cmap = sinkInfo.channel_map; + /* Use the requested format if we have one. */ + ss.format = ma_format_to_pulse(pDescriptorPlayback->format); + /* Use the requested channel count if we have one. */ if (pDescriptorPlayback->channels != 0) { ss.channels = pDescriptorPlayback->channels; @@ -32323,7 +32327,7 @@ static ma_result ma_device_init__pulse(ma_device* pDevice, const ma_device_confi } else { ss.format = MA_PA_SAMPLE_FLOAT32BE; } - streamFlags |= MA_PA_STREAM_FIX_FORMAT; + /*streamFlags |= MA_PA_STREAM_FIX_FORMAT;*/ /* Using PA_STREAM_FIX_FORMAT will make it so PulseAudio can possibly pick S24_32 which is not supported by miniaudio and will thus result in an error later on. By excluding it, PulseAudio should always pick F32. */ ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[PulseAudio] sample_spec.format not supported by miniaudio. Defaulting to PA_SAMPLE_FLOAT32.\n"); } if (ss.rate == 0) {