rework device opening code: work around broken SND_PCM_NO_AUTO_xxx support in ALSA <= 1.0.17a

This commit is contained in:
Lennart Poettering 2008-08-31 16:25:37 +02:00
parent 34bcba63a2
commit 1c4ad4b64b

View file

@ -421,6 +421,8 @@ int pa_alsa_set_hw_params(
ret = 0;
snd_pcm_nonblock(pcm_handle, 1);
finish:
return ret;
@ -569,17 +571,23 @@ snd_pcm_t *pa_alsa_open_by_device_id(
continue;
d = pa_sprintf_malloc("%s:%s", device_table[i].name, dev_id);
for (;;) {
pa_log_debug("Trying %s...", d);
/* We don't pass SND_PCM_NONBLOCK here, since alsa-lib <=
* 1.0.17a would then ignore the SND_PCM_NO_xxx
* flags. Instead we enable nonblock mode afterwards via
* snd_pcm_nonblock(). Also see
* http://mailman.alsa-project.org/pipermail/alsa-devel/2008-August/010258.html */
if ((err = snd_pcm_open(&pcm_handle, d, mode,
SND_PCM_NONBLOCK|
/* SND_PCM_NONBLOCK| */
SND_PCM_NO_AUTO_RESAMPLE|
SND_PCM_NO_AUTO_CHANNELS|
SND_PCM_NO_AUTO_FORMAT |
SND_PCM_NO_SOFTVOL)) < 0) {
SND_PCM_NO_AUTO_FORMAT)) < 0) {
pa_log_info("Couldn't open PCM device %s: %s", d, snd_strerror(err));
pa_xfree(d);
continue;
break;
}
try_ss.channels = device_table[i].map.channels;
@ -587,12 +595,23 @@ snd_pcm_t *pa_alsa_open_by_device_id(
try_ss.format = ss->format;
if ((err = pa_alsa_set_hw_params(pcm_handle, &try_ss, nfrags, period_size, tsched_size, use_mmap, use_tsched, TRUE)) < 0) {
pa_log_info("PCM device %s refused our hw parameters: %s", d, snd_strerror(err));
if (!pa_startswith(d, "plug:") && !pa_startswith(d, "plughw:")) {
char *t;
t = pa_sprintf_malloc("plug:%s", d);
pa_xfree(d);
d = t;
snd_pcm_close(pcm_handle);
continue;
}
pa_log_info("PCM device %s refused our hw parameters: %s", d, snd_strerror(err));
snd_pcm_close(pcm_handle);
break;
}
*ss = try_ss;
*map = device_table[i].map;
pa_assert(map->channels == ss->channels);
@ -600,9 +619,12 @@ snd_pcm_t *pa_alsa_open_by_device_id(
return pcm_handle;
}
pa_xfree(d);
}
/* OK, we didn't find any good device, so let's try the raw plughw: stuff */
d = pa_sprintf_malloc("plughw:%s", dev_id);
d = pa_sprintf_malloc("hw:%s", dev_id);
pa_log_debug("Trying %s as last resort...", d);
pcm_handle = pa_alsa_open_by_device_string(d, dev, ss, map, mode, nfrags, period_size, tsched_size, use_mmap, use_tsched);
pa_xfree(d);
@ -636,8 +658,16 @@ snd_pcm_t *pa_alsa_open_by_device_string(
d = pa_xstrdup(device);
for (;;) {
pa_log_debug("Trying %s...", d);
if ((err = snd_pcm_open(&pcm_handle, d, mode, SND_PCM_NONBLOCK|
/* We don't pass SND_PCM_NONBLOCK here, since alsa-lib <=
* 1.0.17a would then ignore the SND_PCM_NO_xxx flags. Instead
* we enable nonblock mode afterwards via
* snd_pcm_nonblock(). Also see
* http://mailman.alsa-project.org/pipermail/alsa-devel/2008-August/010258.html */
if ((err = snd_pcm_open(&pcm_handle, d, mode,
/*SND_PCM_NONBLOCK|*/
SND_PCM_NO_AUTO_RESAMPLE|
SND_PCM_NO_AUTO_CHANNELS|
SND_PCM_NO_AUTO_FORMAT)) < 0) {
@ -648,12 +678,12 @@ snd_pcm_t *pa_alsa_open_by_device_string(
if ((err = pa_alsa_set_hw_params(pcm_handle, ss, nfrags, period_size, tsched_size, use_mmap, use_tsched, FALSE)) < 0) {
if (err == -EPERM) {
/* Hmm, some hw is very exotic, so we retry with plug, if without it didn't work */
if (pa_startswith(d, "hw:")) {
char *t = pa_sprintf_malloc("plughw:%s", d+3);
pa_log_debug("Opening the device as '%s' didn't work, retrying with '%s'.", d, t);
if (!pa_startswith(d, "plug:") && !pa_startswith(d, "plughw:")) {
char *t;
t = pa_sprintf_malloc("plug:%s", d);
pa_xfree(d);
d = t;
@ -666,7 +696,6 @@ snd_pcm_t *pa_alsa_open_by_device_string(
snd_pcm_close(pcm_handle);
return NULL;
}
}
*dev = d;