make SDL-1.2 to work with alsa-lib < 1.0.11 again SDL-1.2
authorOzkan Sezer <sezeroz@gmail.com>
Thu, 15 Aug 2019 20:32:32 +0300
branchSDL-1.2
changeset 13011edf8cb7ce974
parent 13010 a355b476255e
child 13012 a8557f8c3c01
make SDL-1.2 to work with alsa-lib < 1.0.11 again

(drop snd_pcm_recover() dependency added by commit df306a61a)
configure
configure.in
src/audio/alsa/SDL_alsa_audio.c
     1.1 --- a/configure	Thu Aug 15 17:02:10 2019 +0300
     1.2 +++ b/configure	Thu Aug 15 20:32:32 2019 +0300
     1.3 @@ -20802,7 +20802,7 @@
     1.4  { $as_echo "$as_me:$LINENO: result: $ALSA_LIBS" >&5
     1.5  $as_echo "$ALSA_LIBS" >&6; }
     1.6  
     1.7 -min_alsa_version=1.0.11
     1.8 +min_alsa_version=0.9.0
     1.9  { $as_echo "$as_me:$LINENO: checking for libasound headers version >= $min_alsa_version" >&5
    1.10  $as_echo_n "checking for libasound headers version >= $min_alsa_version... " >&6; }
    1.11  no_alsa=""
     2.1 --- a/configure.in	Thu Aug 15 17:02:10 2019 +0300
     2.2 +++ b/configure.in	Thu Aug 15 20:32:32 2019 +0300
     2.3 @@ -361,7 +361,7 @@
     2.4  AC_HELP_STRING([--enable-alsa], [support the ALSA audio API [[default=yes]]]),
     2.5                    , enable_alsa=yes)
     2.6      if test x$enable_audio = xyes -a x$enable_alsa = xyes; then
     2.7 -        AM_PATH_ALSA(1.0.11, have_alsa=yes, have_alsa=no)
     2.8 +        AM_PATH_ALSA(0.9.0, have_alsa=yes, have_alsa=no)
     2.9          # Restore all flags from before the ALSA detection runs
    2.10          CFLAGS="$alsa_save_CFLAGS"
    2.11          LDFLAGS="$alsa_save_LDFLAGS"
     3.1 --- a/src/audio/alsa/SDL_alsa_audio.c	Thu Aug 15 17:02:10 2019 +0300
     3.2 +++ b/src/audio/alsa/SDL_alsa_audio.c	Thu Aug 15 20:32:32 2019 +0300
     3.3 @@ -59,7 +59,7 @@
     3.4  static int (*SDL_NAME(snd_pcm_open))(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode);
     3.5  static int (*SDL_NAME(snd_pcm_close))(snd_pcm_t *pcm);
     3.6  static snd_pcm_sframes_t (*SDL_NAME(snd_pcm_writei))(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
     3.7 -static int (*SDL_NAME(snd_pcm_recover))(snd_pcm_t *pcm, int err, int silent);
     3.8 +static int (*SDL_NAME(snd_pcm_resume))(snd_pcm_t *pcm);
     3.9  static int (*SDL_NAME(snd_pcm_prepare))(snd_pcm_t *pcm);
    3.10  static int (*SDL_NAME(snd_pcm_drain))(snd_pcm_t *pcm);
    3.11  static const char *(*SDL_NAME(snd_strerror))(int errnum);
    3.12 @@ -86,10 +86,10 @@
    3.13  static int (*SDL_NAME(snd_pcm_sw_params_set_start_threshold))(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val);
    3.14  static int (*SDL_NAME(snd_pcm_sw_params))(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
    3.15  static int (*SDL_NAME(snd_pcm_nonblock))(snd_pcm_t *pcm, int nonblock);
    3.16 -static int (*SDL_NAME(snd_pcm_wait))(snd_pcm_t *pcm, int timeout);
    3.17  #define snd_pcm_hw_params_sizeof SDL_NAME(snd_pcm_hw_params_sizeof)
    3.18  #define snd_pcm_sw_params_sizeof SDL_NAME(snd_pcm_sw_params_sizeof)
    3.19  
    3.20 +
    3.21  /* cast funcs to char* first, to please GCC's strict aliasing rules. */
    3.22  static struct {
    3.23  	const char *name;
    3.24 @@ -98,7 +98,7 @@
    3.25  	{ "snd_pcm_open",	(void**)(char*)&SDL_NAME(snd_pcm_open)		},
    3.26  	{ "snd_pcm_close",	(void**)(char*)&SDL_NAME(snd_pcm_close)	},
    3.27  	{ "snd_pcm_writei",	(void**)(char*)&SDL_NAME(snd_pcm_writei)	},
    3.28 -	{ "snd_pcm_recover",	(void**)(char*)&SDL_NAME(snd_pcm_recover)	},
    3.29 +	{ "snd_pcm_resume",	(void**)(char*)&SDL_NAME(snd_pcm_resume)	},
    3.30  	{ "snd_pcm_prepare",	(void**)(char*)&SDL_NAME(snd_pcm_prepare)	},
    3.31  	{ "snd_pcm_drain",	(void**)(char*)&SDL_NAME(snd_pcm_drain)	},
    3.32  	{ "snd_strerror",	(void**)(char*)&SDL_NAME(snd_strerror)		},
    3.33 @@ -123,7 +123,6 @@
    3.34  	{ "snd_pcm_sw_params_set_start_threshold",	(void**)(char*)&SDL_NAME(snd_pcm_sw_params_set_start_threshold)	},
    3.35  	{ "snd_pcm_sw_params",	(void**)(char*)&SDL_NAME(snd_pcm_sw_params)	},
    3.36  	{ "snd_pcm_nonblock",	(void**)(char*)&SDL_NAME(snd_pcm_nonblock)	},
    3.37 -	{ "snd_pcm_wait",	(void**)(char*)&SDL_NAME(snd_pcm_wait)	},
    3.38  };
    3.39  
    3.40  static void UnloadALSALibrary(void) {
    3.41 @@ -303,6 +302,25 @@
    3.42  }
    3.43  
    3.44  
    3.45 +/* snd_pcm_recover() is available in alsa-lib >= 1.0.11 */
    3.46 +static int ALSA_pcm_recover(snd_pcm_t *handle, int err, int silent)
    3.47 +{
    3.48 +	(void) silent;
    3.49 +	if (err == -EINTR) return 0;
    3.50 +	if (err == -EPIPE) {		/* under-run */
    3.51 +		err = SDL_NAME(snd_pcm_prepare)(handle);
    3.52 +		return (err < 0)? err : 0;
    3.53 +	}
    3.54 +	if (err == -ESTRPIPE) {
    3.55 +		/* wait until suspend flag is released */
    3.56 +		while ((err = SDL_NAME(snd_pcm_resume)(handle)) == -EAGAIN)
    3.57 +			SDL_Delay(100);
    3.58 +		if (err < 0) err = SDL_NAME(snd_pcm_prepare)(handle);
    3.59 +		return (err < 0)? err : 0;
    3.60 +	}
    3.61 +	return err;
    3.62 +}
    3.63 +
    3.64  static void ALSA_PlayAudio(_THIS)
    3.65  {
    3.66  	int status;
    3.67 @@ -315,17 +333,14 @@
    3.68  	frames_left = ((snd_pcm_uframes_t) this->spec.samples);
    3.69  
    3.70  	while ( frames_left > 0 && this->enabled ) {
    3.71 -		/* This works, but needs more testing before going live */
    3.72 -		/*SDL_NAME(snd_pcm_wait)(pcm_handle, -1);*/
    3.73 -
    3.74  		status = SDL_NAME(snd_pcm_writei)(pcm_handle, sample_buf, frames_left);
    3.75  		if ( status < 0 ) {
    3.76  			if ( status == -EAGAIN ) {
    3.77 -				/* Apparently snd_pcm_recover() doesn't handle this case - does it assume snd_pcm_wait() above? */
    3.78 +				/* Apparently snd_pcm_recover() doesn't handle this case. Foo. */
    3.79  				SDL_Delay(1);
    3.80  				continue;
    3.81  			}
    3.82 -			status = SDL_NAME(snd_pcm_recover)(pcm_handle, status, 0);
    3.83 +			status = ALSA_pcm_recover(pcm_handle, status, 0);
    3.84  			if ( status < 0 ) {
    3.85  				/* Hmm, not much we can do - abort */
    3.86  				fprintf(stderr, "ALSA write failed (unrecoverable): %s\n", SDL_NAME(snd_strerror)(status));