]> git.alsa-project.org Git - alsa-plugins.git/commitdiff
pulse: Add fallback option
authorTakashi Iwai <tiwai@suse.de>
Tue, 26 Jul 2011 12:26:26 +0000 (14:26 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 26 Jul 2011 12:26:26 +0000 (14:26 +0200)
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
pulse/ctl_pulse.c
pulse/pcm_pulse.c
pulse/pulse.c
pulse/pulse.h

index d5431b481c84d6f6d093a0da0710de699e9cd585..5b119f97c7f418edd8d5930ebc9dd2a6299f72c5 100644 (file)
@@ -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"
index 85863eded986c459b0bb26d9c9ebb4b5e56e2a04..8b5ff9e5086621f938af008dce33ddc6a23acdd9 100644 (file)
@@ -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;
 }
 
index 9105d4dfd611f655e1e4d64c94bbb469f59d7a52..15b29e05483cedcec5d5672fd31143cbaacd4425 100644 (file)
@@ -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;
 }
 
index f26363af4d3caae48d95c3eff52a771e81f55284..6d9613d841ddd39887bd51a28b577f52beea4b1f 100644 (file)
@@ -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);
 
index e98124f284cb848f39b30ef32400cd087d24fd7b..9f32a7f299f63f9dbd9ed7da7242b6c8f62afec2 100644 (file)
@@ -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);