From a39bfa4995f4e7febd7ba94f6958bdd58cf27359 Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Thu, 17 Dec 2020 17:52:21 +0100 Subject: [PATCH] acp: make sure each port's priority is updated when switching profiles UCM profiles can use the same ports, but with different priorities. One good example is a phone, having an earpiece and a speaker: - the default profile will put a higher priority on the speaker - the "voice call" profile will put a higher priority on the earpiece When switching to the "voice call" profile, we want pipewire to take into account the priority change, so that the earpiece gets the highest priority and is selected by default. As the ports have the same name in both profiles, we have a single instance of each port in memory, and therefore need to trigger a port update when the profile is changed, so that the priority set by the new profile is used. Moreover, the UCM code updates only the priority inside the `pa_device_port` structure, so this commit also makes sure we reflect this value into the `acp_port` structure when enabling a device. --- spa/plugins/alsa/acp/acp.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/spa/plugins/alsa/acp/acp.c b/spa/plugins/alsa/acp/acp.c index 42212a7ce..a5d791ce4 100644 --- a/spa/plugins/alsa/acp/acp.c +++ b/spa/plugins/alsa/acp/acp.c @@ -1155,7 +1155,7 @@ static int device_enable(pa_card *impl, pa_alsa_mapping *mapping, pa_alsa_device { const char *mod_name; bool ignore_dB = false; - uint32_t port_index; + uint32_t i, port_index; int res; if (impl->use_ucm && @@ -1173,6 +1173,12 @@ static int device_enable(pa_card *impl, pa_alsa_mapping *mapping, pa_alsa_device find_mixer(impl, dev, NULL, ignore_dB); + /* Synchronize priority values, as it may have changed when setting the profile */ + for (i = 0; i < impl->card.n_ports; i++) { + pa_device_port *p = (pa_device_port *)impl->card.ports[i]; + p->port.priority = p->priority; + } + port_index = acp_device_find_best_port_index(&dev->device, NULL); if (port_index == ACP_INVALID_INDEX) dev->active_port = NULL; @@ -1242,12 +1248,20 @@ int acp_card_set_profile(struct acp_card *card, uint32_t new_index) if (np->output_mappings) { PA_IDXSET_FOREACH(am, np->output_mappings, idx) { + if (impl->use_ucm) + /* Update ports priorities */ + pa_alsa_ucm_add_ports_combination(am->output.ports, &am->ucm_context, + true, impl->ports, np, NULL); device_enable(impl, am, &am->output); } } if (np->input_mappings) { PA_IDXSET_FOREACH(am, np->input_mappings, idx) { + if (impl->use_ucm) + /* Update ports priorities */ + pa_alsa_ucm_add_ports_combination(am->output.ports, &am->ucm_context, + false, impl->ports, np, NULL); device_enable(impl, am, &am->input); } }