[alsa-devel] [PATCH 3/3] pulse: Add fallback option
Takashi Iwai
tiwai at suse.de
Tue Jul 26 14:36:11 CEST 2011
[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 at 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);
--
1.7.6
More information about the Alsa-devel
mailing list