audioOutput_alsa: add use_mmap, period_time, buffer_time options

ALSA support in libao supports configuring of these variables,
and some hardware setups may benefit from having these things
as tweakable.

git-svn-id: https://svn.musicpd.org/mpd/trunk@4363 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
Eric Wong 2006-07-16 16:52:19 +00:00
parent 3c8e88b053
commit 8224e837ef
2 changed files with 42 additions and 14 deletions

View File

@ -236,6 +236,26 @@ separate options. An example for oss: "dsp=/dev/dsp". An example for alsa09:
This specifies how many bytes to write to the audio device at once. Used only
by the ao output type. This parameter is to work around a bug in older
versions of libao on sound cards with very small buffers. The default is 1024.
.SH OPTIONAL ALSA OUTPUT PARAMETERS
.TP
.B use_mmap <yes or no>
Setting this allows you to use memory-mapped I/O. Certain hardware setups
may benefit from this, but most do not.
Most users do not need to set this.
.TP
.B buffer_time <time in microseconds>
This sets the length of the hardware sample buffer in microseconds.
Increasing it may help to reduce or eliminate skipping on certain setups.
Most users do not need to change this.
The default is 500000 microseconds (0.5 seconds).
.TP
.B period_time <time in microseconds>
This sets the time between hardware sample transfers in microseconds.
Increasing this can reduce CPU usage while lowering it can reduce underrun
errors on bandwidth-limited devices. Some users have reported good results
with this set to 50000, but not all devices support values this high.
Most users do not need to change this.
The default is 256000000 / sample_rate(kHz), or 5804us for CD-quality audio.
.SH REQUIRED SHOUT OUTPUT PARAMETERS
.TP
.B name <name>

View File

@ -46,6 +46,8 @@ typedef struct _AlsaData {
char * device;
snd_pcm_t * pcmHandle;
alsa_writei_t * writei;
unsigned int buffer_time;
unsigned int period_time;
int sampleSize;
int useMmap;
int canPause;
@ -59,6 +61,8 @@ static AlsaData * newAlsaData() {
ret->pcmHandle = NULL;
ret->writei = snd_pcm_writei;
ret->useMmap = 0;
ret->buffer_time = MPD_ALSA_BUFFER_TIME;
ret->period_time = MPD_ALSA_PERIOD_TIME;
return ret;
}
@ -70,17 +74,23 @@ static void freeAlsaData(AlsaData * ad) {
}
static int alsa_initDriver(AudioOutput * audioOutput, ConfigParam * param) {
BlockParam * bp = NULL;
AlsaData * ad;
if(param) bp = getBlockParam(param, "device");
AlsaData * ad = newAlsaData();
ad = newAlsaData();
if (param) {
BlockParam * bp = getBlockParam(param, "device");
ad->device = bp ? strdup(bp->value) : strdup("default");
if ((bp = getBlockParam(param, "use_mmap")) &&
(!strcasecmp(bp->value, "yes") ||
!strcasecmp(bp->value, "true")))
ad->useMmap = 1;
if ((bp = getBlockParam(param, "buffer_time")))
ad->buffer_time = atoi(bp->value);
if ((bp = getBlockParam(param, "period_time")))
ad->period_time = atoi(bp->value);
}
audioOutput->data = ad;
ad->device = bp ? strdup(bp->value) : strdup("default");
return 0;
}
@ -118,8 +128,6 @@ static int alsa_openDevice(AudioOutput * audioOutput)
unsigned int channels = audioFormat->channels;
snd_pcm_uframes_t alsa_buffer_size;
snd_pcm_uframes_t alsa_period_size;
unsigned int alsa_buffer_time = MPD_ALSA_BUFFER_TIME;
unsigned int alsa_period_time = MPD_ALSA_PERIOD_TIME;
int err;
char * cmd = NULL;
@ -210,14 +218,14 @@ static int alsa_openDevice(AudioOutput * audioOutput)
cmd = "snd_pcm_hw_params_set_buffer_time_near";
err = snd_pcm_hw_params_set_buffer_time_near(ad->pcmHandle, hwparams,
&alsa_buffer_time, 0);
&ad->buffer_time, 0);
if(err < 0) goto error;
if (!alsa_period_time && sampleRate > 0)
alsa_period_time = 1000000 * MPD_ALSA_SAMPLE_XFER / sampleRate;
if (!ad->period_time && sampleRate > 0)
ad->period_time = 1000000 * MPD_ALSA_SAMPLE_XFER / sampleRate;
cmd = "snd_pcm_hw_params_set_period_time_near";
err = snd_pcm_hw_params_set_period_time_near(ad->pcmHandle, hwparams,
&alsa_period_time, 0);
&ad->period_time, 0);
if(err < 0) goto error;
cmd = "snd_pcm_hw_params";