[Patch to alsa-plugins]
Added "fallback" option to give the PCM / controller name as a fallback when connecting to PA server fails.
Signed-off-by: Takashi Iwai tiwai@suse.de --- doc/README-pulse | 19 +++++++++++++++++++ pulse/ctl_pulse.c | 17 ++++++++++++++++- pulse/pcm_pulse.c | 17 ++++++++++++++++- pulse/pulse.c | 7 ++++--- pulse/pulse.h | 2 +- 5 files changed, 56 insertions(+), 6 deletions(-)
diff --git a/doc/README-pulse b/doc/README-pulse index d5431b4..5b119f9 100644 --- a/doc/README-pulse +++ b/doc/README-pulse @@ -39,3 +39,22 @@ you need to do this with PCM:s then specify two PCM:s with different "device".
If you do not specify any source and/or sink, then the server's defaults will be used. + +When "fallback" option is set, the plugin will try to open the given PCM +(or control) automatically when connecting to PA server fails. Typically, +it should point to "sysdefault", which was introduced recently in alsa-lib, +so that the system-default setup is used even when you overwrite "default" +PCM and control definitions. + + pcm.pulse { + type pulse + fallback "sysdefault" + } + + ctl.pulse { + type pulse + fallback "sysdefault" + } + + pcm.!default "pulse" + ctl.!default "pulse" diff --git a/pulse/ctl_pulse.c b/pulse/ctl_pulse.c index 85863ed..8b5ff9e 100644 --- a/pulse/ctl_pulse.c +++ b/pulse/ctl_pulse.c @@ -647,6 +647,7 @@ SND_CTL_PLUGIN_DEFINE_FUNC(pulse) const char *device = NULL; const char *source = NULL; const char *sink = NULL; + const char *fallback_name = NULL; int err; snd_ctl_pulse_t *ctl; pa_operation *o; @@ -687,10 +688,20 @@ SND_CTL_PLUGIN_DEFINE_FUNC(pulse) } continue; } + if (strcmp(id, "fallback") == 0) { + if (snd_config_get_string(n, &fallback_name) < 0) { + SNDERR("Invalid value for %s", id); + return -EINVAL; + } + continue; + } SNDERR("Unknown field %s", id); return -EINVAL; }
+ if (fallback_name && name && !strcmp(name, fallback_name)) + fallback_name = NULL; /* no fallback for the same name */ + ctl = calloc(1, sizeof(*ctl)); if (!ctl) return -ENOMEM; @@ -701,7 +712,7 @@ SND_CTL_PLUGIN_DEFINE_FUNC(pulse) goto error; }
- err = pulse_connect(ctl->p, server); + err = pulse_connect(ctl->p, server, !fallback_name); if (err < 0) goto error;
@@ -794,6 +805,10 @@ error: free(ctl->sink); free(ctl);
+ if (fallback_name) + return snd_ctl_open_fallback(handlep, root, + fallback_name, name, mode); + return err; }
diff --git a/pulse/pcm_pulse.c b/pulse/pcm_pulse.c index 9105d4d..15b29e0 100644 --- a/pulse/pcm_pulse.c +++ b/pulse/pcm_pulse.c @@ -982,6 +982,7 @@ SND_PCM_PLUGIN_DEFINE_FUNC(pulse) snd_config_iterator_t i, next; const char *server = NULL; const char *device = NULL; + const char *fallback_name = NULL; int handle_underrun = 0; int err; snd_pcm_pulse_t *pcm; @@ -1016,10 +1017,20 @@ SND_PCM_PLUGIN_DEFINE_FUNC(pulse) handle_underrun = err; continue; } + if (strcmp(id, "fallback") == 0) { + if (snd_config_get_string(n, &fallback_name) < 0) { + SNDERR("Invalid value for %s", id); + return -EINVAL; + } + continue; + } SNDERR("Unknown field %s", id); return -EINVAL; }
+ if (fallback_name && name && !strcmp(name, fallback_name)) + fallback_name = NULL; /* no fallback for the same name */ + pcm = calloc(1, sizeof(*pcm)); if (!pcm) return -ENOMEM; @@ -1041,7 +1052,7 @@ SND_PCM_PLUGIN_DEFINE_FUNC(pulse)
pcm->handle_underrun = handle_underrun;
- err = pulse_connect(pcm->p, server); + err = pulse_connect(pcm->p, server, !fallback_name); if (err < 0) goto error;
@@ -1074,6 +1085,10 @@ error: free(pcm->device); free(pcm);
+ if (fallback_name) + return snd_pcm_open_fallback(pcmp, root, fallback_name, name, + stream, mode); + return err; }
diff --git a/pulse/pulse.c b/pulse/pulse.c index f26363a..6d9613d 100644 --- a/pulse/pulse.c +++ b/pulse/pulse.c @@ -188,7 +188,7 @@ void pulse_free(snd_pulse_t * p) free(p); }
-int pulse_connect(snd_pulse_t * p, const char *server) +int pulse_connect(snd_pulse_t * p, const char *server, int show_error) { int err; pa_context_state_t state; @@ -225,8 +225,9 @@ int pulse_connect(snd_pulse_t * p, const char *server) return 0;
error: - SNDERR("PulseAudio: Unable to connect: %s\n", - pa_strerror(pa_context_errno(p->context))); + if (show_error) + SNDERR("PulseAudio: Unable to connect: %s\n", + pa_strerror(pa_context_errno(p->context)));
pa_threaded_mainloop_unlock(p->mainloop);
diff --git a/pulse/pulse.h b/pulse/pulse.h index e98124f..9f32a7f 100644 --- a/pulse/pulse.h +++ b/pulse/pulse.h @@ -42,7 +42,7 @@ int pulse_wait_operation(snd_pulse_t * p, pa_operation * o); snd_pulse_t *pulse_new(void); void pulse_free(snd_pulse_t * p);
-int pulse_connect(snd_pulse_t * p, const char *server); +int pulse_connect(snd_pulse_t * p, const char *server, int show_error);
void pulse_poll_activate(snd_pulse_t * p); void pulse_poll_deactivate(snd_pulse_t * p);