alsa: optionally run entire pipeline non-blocking.
authorRyan C. Gordon <icculus@icculus.org>
Tue, 07 Aug 2018 16:49:18 -0400
changeset 120798ffd9de57415
parent 12078 16bb2e8488b8
child 12080 18ea018e00a0
alsa: optionally run entire pipeline non-blocking.
src/audio/alsa/SDL_alsa_audio.c
     1.1 --- a/src/audio/alsa/SDL_alsa_audio.c	Tue Aug 07 13:04:15 2018 -0400
     1.2 +++ b/src/audio/alsa/SDL_alsa_audio.c	Tue Aug 07 16:49:18 2018 -0400
     1.3 @@ -22,6 +22,10 @@
     1.4  
     1.5  #if SDL_AUDIO_DRIVER_ALSA
     1.6  
     1.7 +#ifndef SDL_ALSA_NON_BLOCKING
     1.8 +#define SDL_ALSA_NON_BLOCKING 0
     1.9 +#endif
    1.10 +
    1.11  /* Allow access to a raw mixing buffer */
    1.12  
    1.13  #include <sys/types.h>
    1.14 @@ -90,6 +94,7 @@
    1.15  static int (*ALSA_snd_device_name_hint) (int, const char *, void ***);
    1.16  static char* (*ALSA_snd_device_name_get_hint) (const void *, const char *);
    1.17  static int (*ALSA_snd_device_name_free_hint) (void **);
    1.18 +static snd_pcm_sframes_t (*ALSA_snd_pcm_avail)(snd_pcm_t *);
    1.19  #ifdef SND_CHMAP_API_VERSION
    1.20  static snd_pcm_chmap_t* (*ALSA_snd_pcm_get_chmap) (snd_pcm_t *);
    1.21  static int (*ALSA_snd_pcm_chmap_print) (const snd_pcm_chmap_t *map, size_t maxlen, char *buf);
    1.22 @@ -158,6 +163,7 @@
    1.23      SDL_ALSA_SYM(snd_device_name_hint);
    1.24      SDL_ALSA_SYM(snd_device_name_get_hint);
    1.25      SDL_ALSA_SYM(snd_device_name_free_hint);
    1.26 +    SDL_ALSA_SYM(snd_pcm_avail);
    1.27  #ifdef SND_CHMAP_API_VERSION
    1.28      SDL_ALSA_SYM(snd_pcm_get_chmap);
    1.29      SDL_ALSA_SYM(snd_pcm_chmap_print);
    1.30 @@ -243,7 +249,24 @@
    1.31  static void
    1.32  ALSA_WaitDevice(_THIS)
    1.33  {
    1.34 -    /* We're in blocking mode, so there's nothing to do here */
    1.35 +#if SDL_ALSA_NON_BLOCKING
    1.36 +    const snd_pcm_sframes_t needed = (snd_pcm_sframes_t) this->spec.samples;
    1.37 +    while (SDL_AtomicGet(&this->enabled)) {
    1.38 +        const snd_pcm_sframes_t rc = ALSA_snd_pcm_avail(this->hidden->pcm_handle);
    1.39 +        if ((rc < 0) && (rc != -EAGAIN)) {
    1.40 +            /* Hmm, not much we can do - abort */
    1.41 +            fprintf(stderr, "ALSA snd_pcm_avail failed (unrecoverable): %s\n",
    1.42 +                        ALSA_snd_strerror(rc));
    1.43 +            SDL_OpenedAudioDeviceDisconnected(this);
    1.44 +            return;
    1.45 +        } else if (rc < needed) {
    1.46 +            const Uint32 delay = ((needed - (SDL_max(rc, 0))) * 1000) / this->spec.freq;
    1.47 +            SDL_Delay(SDL_max(delay, 10));
    1.48 +        } else {
    1.49 +            break;  /* ready to go! */
    1.50 +        }
    1.51 +    }
    1.52 +#endif
    1.53  }
    1.54  
    1.55  
    1.56 @@ -672,9 +695,11 @@
    1.57          SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);
    1.58      }
    1.59  
    1.60 +    #if !SDL_ALSA_NON_BLOCKING
    1.61      if (!iscapture) {
    1.62          ALSA_snd_pcm_nonblock(pcm_handle, 0);
    1.63      }
    1.64 +    #endif
    1.65  
    1.66      /* We're ready to rock and roll. :-) */
    1.67      return 0;