Mercurial > sdl-ios-xcode
diff src/audio/alsa/SDL_alsa_audio.c @ 4333:55717a755897 SDL-1.2
Switched from setting the period size and count to setting the buffer size directly, based on feedback from the ALSA development list:
http://mailman.alsa-project.org/pipermail/alsa-devel/2009-October/022267.html
This has the nice side effect of reducing latency on my SBLive! card.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 13 Oct 2009 09:56:15 +0000 |
parents | 67e799ffcadf |
children | afadcd7d2319 |
line wrap: on
line diff
--- a/src/audio/alsa/SDL_alsa_audio.c Tue Oct 13 09:35:37 2009 +0000 +++ b/src/audio/alsa/SDL_alsa_audio.c Tue Oct 13 09:56:15 2009 +0000 @@ -46,6 +46,10 @@ /* The default ALSA audio driver */ #define DEFAULT_DEVICE "default" +/* Whether we should set the buffer size or the period size */ +/*#define SET_PERIOD_SIZE*/ +/*#define DEBUG_PERIOD_SIZE*/ + /* Audio driver functions */ static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec); static void ALSA_WaitAudio(_THIS); @@ -78,13 +82,13 @@ static int (*SDL_NAME(snd_pcm_hw_params_get_period_size))(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir); static int (*SDL_NAME(snd_pcm_hw_params_set_periods_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); static int (*SDL_NAME(snd_pcm_hw_params_get_periods))(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); +static int (*SDL_NAME(snd_pcm_hw_params_set_buffer_size_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); static int (*SDL_NAME(snd_pcm_hw_params_get_buffer_size))(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); static int (*SDL_NAME(snd_pcm_hw_params))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); /* */ static int (*SDL_NAME(snd_pcm_sw_params_current))(snd_pcm_t *pcm, snd_pcm_sw_params_t *swparams); 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); -static int (*SDL_NAME(snd_pcm_sw_params_set_avail_min))(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); static int (*SDL_NAME(snd_pcm_sw_params))(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); static int (*SDL_NAME(snd_pcm_nonblock))(snd_pcm_t *pcm, int nonblock); #define snd_pcm_hw_params_sizeof SDL_NAME(snd_pcm_hw_params_sizeof) @@ -114,11 +118,11 @@ { "snd_pcm_hw_params_get_period_size", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_get_period_size) }, { "snd_pcm_hw_params_set_periods_near", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_periods_near) }, { "snd_pcm_hw_params_get_periods", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_get_periods) }, + { "snd_pcm_hw_params_set_buffer_size_near", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_buffer_size_near) }, { "snd_pcm_hw_params_get_buffer_size", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_get_buffer_size) }, { "snd_pcm_hw_params", (void**)(char*)&SDL_NAME(snd_pcm_hw_params) }, { "snd_pcm_sw_params_current", (void**)(char*)&SDL_NAME(snd_pcm_sw_params_current) }, { "snd_pcm_sw_params_set_start_threshold", (void**)(char*)&SDL_NAME(snd_pcm_sw_params_set_start_threshold) }, - { "snd_pcm_sw_params_set_avail_min", (void**)(char*)&SDL_NAME(snd_pcm_sw_params_set_avail_min) }, { "snd_pcm_sw_params", (void**)(char*)&SDL_NAME(snd_pcm_sw_params) }, { "snd_pcm_nonblock", (void**)(char*)&SDL_NAME(snd_pcm_nonblock) }, }; @@ -368,8 +372,10 @@ snd_pcm_format_t format; snd_pcm_uframes_t frames; unsigned int rate; +#ifdef SET_PERIOD_SIZE unsigned int periods; - unsigned int channels; +#endif + unsigned int channels; Uint16 test_format; /* Open the audio device */ @@ -464,10 +470,11 @@ spec->freq = rate; /* Set the buffer size, in samples */ +#ifdef SET_PERIOD_SIZE frames = spec->samples; status = SDL_NAME(snd_pcm_hw_params_set_period_size_near)(pcm_handle, hwparams, &frames, NULL); if ( status < 0 ) { - SDL_SetError("Couldn't set audio frequency: %s", SDL_NAME(snd_strerror)(status)); + SDL_SetError("Couldn't set period size: %s", SDL_NAME(snd_strerror)(status)); ALSA_CloseAudio(this); return(-1); } @@ -475,7 +482,16 @@ spec->samples = frames; periods = 2; - SDL_NAME(snd_pcm_hw_params_set_periods_near)(pcm_handle, hwparams, &periods, NULL); + status = SDL_NAME(snd_pcm_hw_params_set_periods_near)(pcm_handle, hwparams, &periods, NULL); + if ( status < 0 ) { + SDL_SetError("Couldn't set period count: %s", SDL_NAME(snd_strerror)(status)); + ALSA_CloseAudio(this); + return(-1); + } +#else + frames = spec->samples * 2; + status = SDL_NAME(snd_pcm_hw_params_set_buffer_size_near)(pcm_handle, hwparams, &frames); +#endif /* "set" the hardware with the desired parameters */ status = SDL_NAME(snd_pcm_hw_params)(pcm_handle, hwparams); @@ -486,7 +502,7 @@ } /* This is useful for debugging... */ -#if 0 +#ifdef DEBUG_PERIOD_SIZE { snd_pcm_uframes_t bufsize; snd_pcm_sframes_t persize; unsigned int periods; int dir; SDL_NAME(snd_pcm_hw_params_get_buffer_size)(hwparams, &bufsize); SDL_NAME(snd_pcm_hw_params_get_period_size)(hwparams, &persize, &dir); @@ -510,12 +526,6 @@ ALSA_CloseAudio(this); return(-1); } - status = SDL_NAME(snd_pcm_sw_params_set_avail_min)(pcm_handle, swparams, frames); - if ( status < 0 ) { - SDL_SetError("Couldn't set avail min: %s", SDL_NAME(snd_strerror)(status)); - ALSA_CloseAudio(this); - return(-1); - } status = SDL_NAME(snd_pcm_sw_params)(pcm_handle, swparams); if ( status < 0 ) { SDL_SetError("Couldn't set software audio parameters: %s", SDL_NAME(snd_strerror)(status));