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. --HG-- branch : SDL-1.2 extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%404080
This commit is contained in:
parent
9786668dab
commit
ec6a0f32bb
1 changed files with 22 additions and 12 deletions
|
@ -46,6 +46,10 @@
|
||||||
/* The default ALSA audio driver */
|
/* The default ALSA audio driver */
|
||||||
#define DEFAULT_DEVICE "default"
|
#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 */
|
/* Audio driver functions */
|
||||||
static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec);
|
static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec);
|
||||||
static void ALSA_WaitAudio(_THIS);
|
static void ALSA_WaitAudio(_THIS);
|
||||||
|
@ -78,13 +82,13 @@ static int (*SDL_NAME(snd_pcm_hw_params_set_period_size_near))(snd_pcm_t *pcm, s
|
||||||
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_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_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_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_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_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_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_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_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);
|
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)
|
#define snd_pcm_hw_params_sizeof SDL_NAME(snd_pcm_hw_params_sizeof)
|
||||||
|
@ -114,11 +118,11 @@ static struct {
|
||||||
{ "snd_pcm_hw_params_get_period_size", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_get_period_size) },
|
{ "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_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_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_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_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_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_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_sw_params", (void**)(char*)&SDL_NAME(snd_pcm_sw_params) },
|
||||||
{ "snd_pcm_nonblock", (void**)(char*)&SDL_NAME(snd_pcm_nonblock) },
|
{ "snd_pcm_nonblock", (void**)(char*)&SDL_NAME(snd_pcm_nonblock) },
|
||||||
};
|
};
|
||||||
|
@ -368,7 +372,9 @@ static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
snd_pcm_format_t format;
|
snd_pcm_format_t format;
|
||||||
snd_pcm_uframes_t frames;
|
snd_pcm_uframes_t frames;
|
||||||
unsigned int rate;
|
unsigned int rate;
|
||||||
|
#ifdef SET_PERIOD_SIZE
|
||||||
unsigned int periods;
|
unsigned int periods;
|
||||||
|
#endif
|
||||||
unsigned int channels;
|
unsigned int channels;
|
||||||
Uint16 test_format;
|
Uint16 test_format;
|
||||||
|
|
||||||
|
@ -464,10 +470,11 @@ static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
spec->freq = rate;
|
spec->freq = rate;
|
||||||
|
|
||||||
/* Set the buffer size, in samples */
|
/* Set the buffer size, in samples */
|
||||||
|
#ifdef SET_PERIOD_SIZE
|
||||||
frames = spec->samples;
|
frames = spec->samples;
|
||||||
status = SDL_NAME(snd_pcm_hw_params_set_period_size_near)(pcm_handle, hwparams, &frames, NULL);
|
status = SDL_NAME(snd_pcm_hw_params_set_period_size_near)(pcm_handle, hwparams, &frames, NULL);
|
||||||
if ( status < 0 ) {
|
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);
|
ALSA_CloseAudio(this);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
@ -475,7 +482,16 @@ static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
spec->samples = frames;
|
spec->samples = frames;
|
||||||
|
|
||||||
periods = 2;
|
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 */
|
/* "set" the hardware with the desired parameters */
|
||||||
status = SDL_NAME(snd_pcm_hw_params)(pcm_handle, hwparams);
|
status = SDL_NAME(snd_pcm_hw_params)(pcm_handle, hwparams);
|
||||||
|
@ -486,7 +502,7 @@ static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is useful for debugging... */
|
/* 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;
|
{ 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_buffer_size)(hwparams, &bufsize);
|
||||||
SDL_NAME(snd_pcm_hw_params_get_period_size)(hwparams, &persize, &dir);
|
SDL_NAME(snd_pcm_hw_params_get_period_size)(hwparams, &persize, &dir);
|
||||||
|
@ -510,12 +526,6 @@ static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
ALSA_CloseAudio(this);
|
ALSA_CloseAudio(this);
|
||||||
return(-1);
|
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);
|
status = SDL_NAME(snd_pcm_sw_params)(pcm_handle, swparams);
|
||||||
if ( status < 0 ) {
|
if ( status < 0 ) {
|
||||||
SDL_SetError("Couldn't set software audio parameters: %s", SDL_NAME(snd_strerror)(status));
|
SDL_SetError("Couldn't set software audio parameters: %s", SDL_NAME(snd_strerror)(status));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue