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:
parent
3c8e88b053
commit
8224e837ef
@ -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
|
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
|
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.
|
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
|
.SH REQUIRED SHOUT OUTPUT PARAMETERS
|
||||||
.TP
|
.TP
|
||||||
.B name <name>
|
.B name <name>
|
||||||
|
@ -46,6 +46,8 @@ typedef struct _AlsaData {
|
|||||||
char * device;
|
char * device;
|
||||||
snd_pcm_t * pcmHandle;
|
snd_pcm_t * pcmHandle;
|
||||||
alsa_writei_t * writei;
|
alsa_writei_t * writei;
|
||||||
|
unsigned int buffer_time;
|
||||||
|
unsigned int period_time;
|
||||||
int sampleSize;
|
int sampleSize;
|
||||||
int useMmap;
|
int useMmap;
|
||||||
int canPause;
|
int canPause;
|
||||||
@ -59,6 +61,8 @@ static AlsaData * newAlsaData() {
|
|||||||
ret->pcmHandle = NULL;
|
ret->pcmHandle = NULL;
|
||||||
ret->writei = snd_pcm_writei;
|
ret->writei = snd_pcm_writei;
|
||||||
ret->useMmap = 0;
|
ret->useMmap = 0;
|
||||||
|
ret->buffer_time = MPD_ALSA_BUFFER_TIME;
|
||||||
|
ret->period_time = MPD_ALSA_PERIOD_TIME;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -70,17 +74,23 @@ static void freeAlsaData(AlsaData * ad) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int alsa_initDriver(AudioOutput * audioOutput, ConfigParam * param) {
|
static int alsa_initDriver(AudioOutput * audioOutput, ConfigParam * param) {
|
||||||
BlockParam * bp = NULL;
|
AlsaData * ad = newAlsaData();
|
||||||
AlsaData * ad;
|
|
||||||
|
|
||||||
if(param) bp = getBlockParam(param, "device");
|
|
||||||
|
|
||||||
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;
|
audioOutput->data = ad;
|
||||||
|
|
||||||
ad->device = bp ? strdup(bp->value) : strdup("default");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,8 +128,6 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
unsigned int channels = audioFormat->channels;
|
unsigned int channels = audioFormat->channels;
|
||||||
snd_pcm_uframes_t alsa_buffer_size;
|
snd_pcm_uframes_t alsa_buffer_size;
|
||||||
snd_pcm_uframes_t alsa_period_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;
|
int err;
|
||||||
char * cmd = NULL;
|
char * cmd = NULL;
|
||||||
|
|
||||||
@ -210,14 +218,14 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
|
|
||||||
cmd = "snd_pcm_hw_params_set_buffer_time_near";
|
cmd = "snd_pcm_hw_params_set_buffer_time_near";
|
||||||
err = snd_pcm_hw_params_set_buffer_time_near(ad->pcmHandle, hwparams,
|
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(err < 0) goto error;
|
||||||
|
|
||||||
if (!alsa_period_time && sampleRate > 0)
|
if (!ad->period_time && sampleRate > 0)
|
||||||
alsa_period_time = 1000000 * MPD_ALSA_SAMPLE_XFER / sampleRate;
|
ad->period_time = 1000000 * MPD_ALSA_SAMPLE_XFER / sampleRate;
|
||||||
cmd = "snd_pcm_hw_params_set_period_time_near";
|
cmd = "snd_pcm_hw_params_set_period_time_near";
|
||||||
err = snd_pcm_hw_params_set_period_time_near(ad->pcmHandle, hwparams,
|
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;
|
if(err < 0) goto error;
|
||||||
|
|
||||||
cmd = "snd_pcm_hw_params";
|
cmd = "snd_pcm_hw_params";
|
||||||
|
Loading…
Reference in New Issue
Block a user