From 3ed663b4d1ae2a98d79b6f3cecb55d15cb611ab1 Mon Sep 17 00:00:00 2001 From: Alex P Date: Fri, 21 Nov 2025 00:28:35 +0200 Subject: [PATCH] Enable ALSA software resampling for hw: devices Use snd_pcm_hw_params_set_rate_resample(1) to enable ALSA's rate plugin, which provides software resampling even with hw: device interface. This fixes audio distortion when HDMI sources output non-48kHz rates (e.g., 44.1kHz from SBCs). ALSA now automatically resamples any input rate to the configured 48kHz that Opus expects. The rate plugin is available because ALSA is compiled with --with-pcm-plugins=rate in install_audio_deps.sh --- internal/audio/c/audio.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/internal/audio/c/audio.c b/internal/audio/c/audio.c index e7ed9a68..21b4c7d5 100644 --- a/internal/audio/c/audio.c +++ b/internal/audio/c/audio.c @@ -376,21 +376,11 @@ static int configure_alsa_device(snd_pcm_t *handle, const char *device_name, uin err = snd_pcm_hw_params_set_channels(handle, params, num_channels); if (err < 0) return err; - // Force exact rate for Opus compatibility (ALSA resamples if hardware differs) + err = snd_pcm_hw_params_set_rate_resample(handle, params, 1); + if (err < 0) return err; + err = snd_pcm_hw_params_set_rate(handle, params, sample_rate, 0); - if (err < 0) { - fprintf(stderr, "WARNING: %s: Failed to set %u Hz: %s, falling back to nearest\n", - device_name, sample_rate, snd_strerror(err)); - fflush(stderr); - - unsigned int actual_rate = sample_rate; - err = snd_pcm_hw_params_set_rate_near(handle, params, &actual_rate, 0); - if (err < 0) return err; - - fprintf(stderr, "WARNING: %s: Using %u Hz (Opus may fail if non-standard)\n", - device_name, actual_rate); - fflush(stderr); - } + if (err < 0) return err; uint16_t actual_frame_size = frame_size;