Ver Fonte

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.
Ryan C. Gordon há 3 semanas atrás
pai
commit
ae17b04c0d
1 ficheiros alterados com 8 adições e 1 exclusões
  1. 8 1
      src/audio/alsa/SDL_alsa_audio.c

+ 8 - 1
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;