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"
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;
}
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;
goto error;
}
- err = pulse_connect(ctl->p, server);
+ err = pulse_connect(ctl->p, server, !fallback_name);
if (err < 0)
goto error;
free(ctl->sink);
free(ctl);
+ if (fallback_name)
+ return snd_ctl_open_fallback(handlep, root,
+ fallback_name, name, mode);
+
return err;
}
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;
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;
pcm->handle_underrun = handle_underrun;
- err = pulse_connect(pcm->p, server);
+ err = pulse_connect(pcm->p, server, !fallback_name);
if (err < 0)
goto error;
free(pcm->device);
free(pcm);
+ if (fallback_name)
+ return snd_pcm_open_fallback(pcmp, root, fallback_name, name,
+ stream, mode);
+
return err;
}
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;
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);
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);