audioOutput_alsa: better period_size auto-configuration
We'll try setting an initial value of 50ms, and halve it each time snd_pcm_hw_params fails with -EPIPE. This way we'll can use a larger (50ms) period_size whenever a device supports it, and automatically pick smaller ones if we can't set larger ones. This removes the calculation borrowed from libao (svn) as well. Other minor things: "Alsa" => "ALSA" in error messages _US appended to *_TIME constants so we won't get confused (shank's request) git-svn-id: https://svn.musicpd.org/mpd/trunk@4438 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
parent
76528555dc
commit
24c1f46353
@ -25,12 +25,12 @@
|
|||||||
#define ALSA_PCM_NEW_HW_PARAMS_API
|
#define ALSA_PCM_NEW_HW_PARAMS_API
|
||||||
#define ALSA_PCM_NEW_SW_PARAMS_API
|
#define ALSA_PCM_NEW_SW_PARAMS_API
|
||||||
|
|
||||||
#define MPD_ALSA_BUFFER_TIME 500000
|
#define MPD_ALSA_BUFFER_TIME_US 500000
|
||||||
/* the default period time of xmms is 50 ms, so let's use that as well.
|
/* the default period time of xmms is 50 ms, so let's use that as well.
|
||||||
* a user can tweak this parameter via the "period_time" config parameter.
|
* a user can tweak this parameter via the "period_time" config parameter.
|
||||||
*/
|
*/
|
||||||
#define MPD_ALSA_PERIOD_TIME 50000
|
#define MPD_ALSA_PERIOD_TIME_US 50000
|
||||||
#define MPD_ALSA_SAMPLE_XFER 256
|
#define MPD_ALSA_RETRY_NR 5
|
||||||
|
|
||||||
#include "../conf.h"
|
#include "../conf.h"
|
||||||
#include "../log.h"
|
#include "../log.h"
|
||||||
@ -65,8 +65,8 @@ static AlsaData *newAlsaData(void)
|
|||||||
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->buffer_time = MPD_ALSA_BUFFER_TIME_US;
|
||||||
ret->period_time = MPD_ALSA_PERIOD_TIME;
|
ret->period_time = MPD_ALSA_PERIOD_TIME_US;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -139,7 +139,9 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
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;
|
||||||
int err;
|
int err;
|
||||||
char *cmd = NULL;
|
const char *cmd = NULL;
|
||||||
|
unsigned int period_time;
|
||||||
|
int retry = MPD_ALSA_RETRY_NR;
|
||||||
|
|
||||||
switch (audioFormat->bits) {
|
switch (audioFormat->bits) {
|
||||||
case 8:
|
case 8:
|
||||||
@ -155,7 +157,7 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
bitformat = SND_PCM_FORMAT_S32;
|
bitformat = SND_PCM_FORMAT_S32;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROR("Alsa device \"%s\" doesn't support %i bit audio\n",
|
ERROR("ALSA device \"%s\" doesn't support %i bit audio\n",
|
||||||
ad->device, audioFormat->bits);
|
ad->device, audioFormat->bits);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -173,6 +175,7 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
configure_hw:
|
||||||
/* configure HW params */
|
/* configure HW params */
|
||||||
snd_pcm_hw_params_alloca(&hwparams);
|
snd_pcm_hw_params_alloca(&hwparams);
|
||||||
|
|
||||||
@ -204,7 +207,7 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
|
|
||||||
err = snd_pcm_hw_params_set_format(ad->pcmHandle, hwparams, bitformat);
|
err = snd_pcm_hw_params_set_format(ad->pcmHandle, hwparams, bitformat);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
ERROR("Alsa device \"%s\" does not support %i bit audio: "
|
ERROR("ALSA device \"%s\" does not support %i bit audio: "
|
||||||
"%s\n", ad->device, (int)bitformat, snd_strerror(-err));
|
"%s\n", ad->device, (int)bitformat, snd_strerror(-err));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -212,7 +215,7 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
err = snd_pcm_hw_params_set_channels_near(ad->pcmHandle, hwparams,
|
err = snd_pcm_hw_params_set_channels_near(ad->pcmHandle, hwparams,
|
||||||
&channels);
|
&channels);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
ERROR("Alsa device \"%s\" does not support %i channels: "
|
ERROR("ALSA device \"%s\" does not support %i channels: "
|
||||||
"%s\n", ad->device, (int)audioFormat->channels,
|
"%s\n", ad->device, (int)audioFormat->channels,
|
||||||
snd_strerror(-err));
|
snd_strerror(-err));
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -222,7 +225,7 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
err = snd_pcm_hw_params_set_rate_near(ad->pcmHandle, hwparams,
|
err = snd_pcm_hw_params_set_rate_near(ad->pcmHandle, hwparams,
|
||||||
&sampleRate, NULL);
|
&sampleRate, NULL);
|
||||||
if (err < 0 || sampleRate == 0) {
|
if (err < 0 || sampleRate == 0) {
|
||||||
ERROR("Alsa device \"%s\" does not support %i Hz audio\n",
|
ERROR("ALSA device \"%s\" does not support %i Hz audio\n",
|
||||||
ad->device, (int)audioFormat->sampleRate);
|
ad->device, (int)audioFormat->sampleRate);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -234,8 +237,7 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!ad->period_time && sampleRate > 0)
|
period_time = ad->period_time;
|
||||||
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,
|
||||||
&ad->period_time, NULL);
|
&ad->period_time, NULL);
|
||||||
@ -244,8 +246,13 @@ static int alsa_openDevice(AudioOutput * audioOutput)
|
|||||||
|
|
||||||
cmd = "snd_pcm_hw_params";
|
cmd = "snd_pcm_hw_params";
|
||||||
err = snd_pcm_hw_params(ad->pcmHandle, hwparams);
|
err = snd_pcm_hw_params(ad->pcmHandle, hwparams);
|
||||||
if (err < 0)
|
if (err == -EPIPE && --retry > 0) {
|
||||||
|
ad->period_time = period_time >> 1;
|
||||||
|
goto configure_hw;
|
||||||
|
} else if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
if (retry != MPD_ALSA_RETRY_NR)
|
||||||
|
DEBUG("ALSA period_time set to %d\n", ad->period_time);
|
||||||
|
|
||||||
cmd = "snd_pcm_hw_params_get_buffer_size";
|
cmd = "snd_pcm_hw_params_get_buffer_size";
|
||||||
err = snd_pcm_hw_params_get_buffer_size(hwparams, &alsa_buffer_size);
|
err = snd_pcm_hw_params_get_buffer_size(hwparams, &alsa_buffer_size);
|
||||||
|
Loading…
Reference in New Issue
Block a user