From ae17b04c0dcb272a5ecedaa130e691b9b972f843 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 24 Mar 2025 19:35:19 -0400 Subject: [PATCH] alsa: Don't start the hardware until the device thread is ready to do work. Otherwise, in the time it takes the thread to start and other init tasks to complete, we tend to get an underrun on some systems, which ALSA logs to stderr. So this is moved to an InitThread implementation, which runs from the device thread, right before it begins its main loop. Reference PR #12632. --- src/audio/alsa/SDL_alsa_audio.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c index 308eb23593..badbc43ec8 100644 --- a/src/audio/alsa/SDL_alsa_audio.c +++ b/src/audio/alsa/SDL_alsa_audio.c @@ -1187,7 +1187,6 @@ static bool ALSA_OpenDevice(SDL_AudioDevice *device) ALSA_snd_pcm_nonblock(cfg_ctx.device->hidden->pcm, 0); } #endif - ALSA_snd_pcm_start(cfg_ctx.device->hidden->pcm); return true; // We're ready to rock and roll. :-) err_cleanup_ctx: @@ -1200,6 +1199,13 @@ err_free_device_hidden: return false; } +static void ALSA_ThreadInit(SDL_AudioDevice *device) +{ + SDL_SetCurrentThreadPriority(device->recording ? SDL_THREAD_PRIORITY_HIGH : SDL_THREAD_PRIORITY_TIME_CRITICAL); + // do snd_pcm_start as close to the first time we PlayDevice as possible to prevent an underrun at startup. + ALSA_snd_pcm_start(device->hidden->pcm); +} + static ALSA_Device *hotplug_devices = NULL; static int hotplug_device_process(snd_ctl_t *ctl, snd_ctl_card_info_t *ctl_card_info, int dev_idx, @@ -1497,6 +1503,7 @@ static bool ALSA_Init(SDL_AudioDriverImpl *impl) impl->DetectDevices = ALSA_DetectDevices; impl->OpenDevice = ALSA_OpenDevice; + impl->ThreadInit = ALSA_ThreadInit; impl->WaitDevice = ALSA_WaitDevice; impl->GetDeviceBuf = ALSA_GetDeviceBuf; impl->PlayDevice = ALSA_PlayDevice;