[pulseaudio-discuss] [PATCH 7/8] module-alsa-card: Report available ports before unavailable ones
David Henningsson
david.henningsson at canonical.com
Tue May 5 08:01:13 PDT 2015
In case the same jack causes one port to become available and another
one unavailable, the available should be reported first.
This is to avoid unnecessary changes: e g, consider a 'Headphone Jack'
making 'Headphone' available and 'Speaker' unavailable. In case the
unavailable change triggers first, and there is also a currently available
third port (e g 'Digital out'), the routing system might choose to route
to this port because neither of the 'Speaker' and 'Headphone' ports are
available.
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
---
src/modules/alsa/module-alsa-card.c | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 2af7979..c550bd4 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -306,7 +306,7 @@ static void init_profile(struct userdata *u) {
am->source = pa_alsa_source_new(u->module, u->modargs, __FILE__, u->card, am);
}
-static void report_port_state(pa_device_port *p, struct userdata *u) {
+static pa_available_t calc_port_state(pa_device_port *p, struct userdata *u) {
void *state;
pa_alsa_jack *jack;
pa_available_t pa = PA_AVAILABLE_UNKNOWN;
@@ -350,10 +350,14 @@ static void report_port_state(pa_device_port *p, struct userdata *u) {
pa = cpa;
}
}
-
- pa_device_port_set_available(p, pa);
+ return pa;
}
+struct temp_port_avail {
+ pa_device_port *port;
+ pa_available_t avail;
+};
+
static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
struct userdata *u = snd_mixer_elem_get_callback_private(melem);
snd_hctl_elem_t *elem = snd_mixer_elem_get_private(melem);
@@ -361,7 +365,7 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
bool plugged_in;
void *state;
pa_alsa_jack *jack;
- pa_device_port *port;
+ struct temp_port_avail *tp, *tports;
pa_assert(u);
@@ -378,20 +382,36 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
pa_log_debug("Jack '%s' is now %s", pa_strnull(snd_hctl_elem_get_name(elem)), plugged_in ? "plugged in" : "unplugged");
+ tports = tp = pa_xnew0(struct temp_port_avail, pa_hashmap_size(u->jacks)+1);
+
PA_HASHMAP_FOREACH(jack, u->jacks, state)
if (jack->melem == melem) {
jack->plugged_in = plugged_in;
if (u->use_ucm) {
pa_assert(u->card->ports);
- port = pa_hashmap_get(u->card->ports, jack->name);
- pa_assert(port);
+ tp->port = pa_hashmap_get(u->card->ports, jack->name);
+ pa_assert(tp->port);
}
else {
pa_assert(jack->path);
- pa_assert_se(port = jack->path->port);
+ pa_assert_se(tp->port = jack->path->port);
}
- report_port_state(port, u);
+
+ tp->avail = calc_port_state(tp->port, u);
+ tp++;
}
+
+ /* Report available ports before unavailable ones: in case port 1 becomes available when port 2 becomes unavailable,
+ this prevents an unnecessary switch port 1 -> port 3 -> port 2 */
+
+ for (tp = tports; tp->port; tp++)
+ if (tp->avail != PA_AVAILABLE_NO)
+ pa_device_port_set_available(tp->port, tp->avail);
+ for (tp = tports; tp->port; tp++)
+ if (tp->avail == PA_AVAILABLE_NO)
+ pa_device_port_set_available(tp->port, tp->avail);
+
+ pa_xfree(tports);
return 0;
}
--
1.9.1
More information about the pulseaudio-discuss
mailing list