[pulseaudio-discuss] [PATCH 11/17] alsa: Create UCM ports in pa_alsa_profile_set_create_ports()
Tanu Kaskinen
tanu.kaskinen at linux.intel.com
Mon Dec 30 05:04:46 PST 2013
Now also UCM ports are created before any device prototypes or card
profiles are created.
There is some code duplication: alsa-ucm.c already had functions
ucm_add_ports_combination() and ucm_add_port_combination(), and now
this patch adds add_port_combination() that is very similar to
ucm_add_port_combination(), and pa_alsa_profile_set_create_ports()
is similar to ucm_add_ports_combination() (the recursion was replaced
with a loop, though, so it looks different, but it still does
essentially the same thing). The old ucm_* functions will be removed
later, so the duplication isn't permanenet. Port creation is now done
in the new functions, but the old ucm_* variants are still kept,
because they link profiles to ports and ports to sinks/sources, which
the new functions don't do (those things will be done later by the
core).
---
src/modules/alsa/alsa-mixer.c | 18 ++--
src/modules/alsa/alsa-mixer.h | 1 +
src/modules/alsa/alsa-ucm.c | 190 +++++++++++++++++++++++++++++-------------
src/modules/alsa/alsa-ucm.h | 2 +
4 files changed, 146 insertions(+), 65 deletions(-)
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index bd243ba..14bfd88 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -4639,16 +4639,24 @@ static void path_create_ports(pa_core *core, pa_alsa_path *path, pa_hashmap *por
}
void pa_alsa_profile_set_create_ports(pa_core *core, pa_alsa_profile_set *profile_set, pa_hashmap *ports) {
- pa_alsa_path *path;
void *state;
pa_assert(core);
pa_assert(profile_set);
pa_assert(ports);
- PA_HASHMAP_FOREACH(path, profile_set->output_paths, state)
- path_create_ports(core, path, ports);
+ if (profile_set->use_ucm) {
+ pa_alsa_mapping *mapping;
+
+ PA_HASHMAP_FOREACH(mapping, profile_set->mappings, state)
+ pa_alsa_ucm_mapping_create_ports(core, mapping, ports);
+ } else {
+ pa_alsa_path *path;
- PA_HASHMAP_FOREACH(path, profile_set->input_paths, state)
- path_create_ports(core, path, ports);
+ PA_HASHMAP_FOREACH(path, profile_set->output_paths, state)
+ path_create_ports(core, path, ports);
+
+ PA_HASHMAP_FOREACH(path, profile_set->input_paths, state)
+ path_create_ports(core, path, ports);
+ }
}
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index a39befe..6869261 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -318,6 +318,7 @@ struct pa_alsa_profile_set {
pa_hashmap *input_paths;
pa_hashmap *output_paths;
+ bool use_ucm;
bool auto_profiles;
bool ignore_dB:1;
bool probed:1;
diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c
index 302c8fc..2924506 100644
--- a/src/modules/alsa/alsa-ucm.c
+++ b/src/modules/alsa/alsa-ucm.c
@@ -676,23 +676,14 @@ static void ucm_add_port_combination(
pa_device_port *port;
int i;
- unsigned priority;
- double prio2;
char *name = NULL;
- char *desc = NULL;
const char *dev_name;
- const char *direction;
pa_alsa_ucm_device *dev;
dev = pdevices[0];
dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
name = pa_sprintf_malloc("%s%s", is_sink ? PA_UCM_PRE_TAG_OUTPUT : PA_UCM_PRE_TAG_INPUT, dev_name);
- desc = num == 1 ? pa_xstrdup(pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_DESCRIPTION))
- : pa_sprintf_malloc("Combination port for %s", dev_name);
-
- priority = is_sink ? dev->playback_priority : dev->capture_priority;
- prio2 = (priority == 0 ? 0 : 1.0/priority);
for (i = 1; i < num; i++) {
char *tmp;
@@ -703,57 +694,11 @@ static void ucm_add_port_combination(
tmp = pa_sprintf_malloc("%s+%s", name, dev_name);
pa_xfree(name);
name = tmp;
-
- tmp = pa_sprintf_malloc("%s,%s", desc, dev_name);
- pa_xfree(desc);
- desc = tmp;
-
- priority = is_sink ? dev->playback_priority : dev->capture_priority;
- if (priority != 0 && prio2 > 0)
- prio2 += 1.0/priority;
}
- /* Make combination ports always have lower priority, and use the formula
- 1/p = 1/p1 + 1/p2 + ... 1/pn.
- This way, the result will always be less than the individual components,
- yet higher components will lead to higher result. */
-
- if (num > 1)
- priority = prio2 > 0 ? 1.0/prio2 : 0;
-
port = pa_hashmap_get(ports, name);
- if (!port) {
- pa_device_port_new_data port_data;
-
- pa_device_port_new_data_init(&port_data);
- pa_device_port_new_data_set_name(&port_data, name);
- pa_device_port_new_data_set_description(&port_data, desc);
- pa_device_port_new_data_set_direction(&port_data, is_sink ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT);
- pa_node_new_data_set_fallback_name_prefix(&port_data.node_data, "alsa");
-
- port = pa_device_port_new(core, &port_data, 0);
- pa_device_port_new_data_done(&port_data);
-
- if (!port) {
- pa_log("Failed to create port %s.", name);
- goto fail;
- }
-
- pa_hashmap_put(ports, port->name, port);
- pa_dynarray_append(context->ports, port);
- pa_log_debug("Add port %s: %s", port->name, port->description);
- port->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
- }
-
- port->priority = priority;
-
+ pa_assert(port);
pa_xfree(name);
- name = NULL;
- pa_xfree(desc);
- desc = NULL;
-
- direction = is_sink ? "output" : "input";
- pa_log_debug("Port %s direction %s, priority %d", port->name, direction, priority);
if (cp) {
pa_log_debug("Adding profile %s to port %s.", cp->name, port->name);
@@ -766,10 +711,6 @@ static void ucm_add_port_combination(
}
return;
-
-fail:
- pa_xfree(name);
- pa_xfree(desc);
}
static int ucm_port_contains(const char *port_name, const char *dev_name, bool is_sink) {
@@ -1522,6 +1463,7 @@ pa_alsa_profile_set* pa_alsa_ucm_add_profile_set(pa_alsa_ucm_config *ucm, pa_cha
pa_alsa_profile_set *ps;
ps = pa_xnew0(pa_alsa_profile_set, 1);
+ ps->use_ucm = true;
ps->mappings = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
ps->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
ps->decibel_fixes = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
@@ -1678,6 +1620,131 @@ void pa_alsa_ucm_roled_stream_end(pa_alsa_ucm_config *ucm, const char *role, pa_
}
}
+static void add_port_combination(
+ pa_alsa_ucm_mapping_context *context,
+ bool is_sink,
+ pa_alsa_ucm_device **pdevices,
+ int num,
+ pa_hashmap *ports,
+ pa_core *core) {
+
+ pa_device_port *port;
+ int i;
+ unsigned priority;
+ double prio2;
+ char *name = NULL;
+ char *desc = NULL;
+ const char *dev_name;
+ const char *direction;
+ pa_alsa_ucm_device *dev;
+
+ dev = pdevices[0];
+ dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
+
+ name = pa_sprintf_malloc("%s%s", is_sink ? PA_UCM_PRE_TAG_OUTPUT : PA_UCM_PRE_TAG_INPUT, dev_name);
+ desc = num == 1 ? pa_xstrdup(pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_DESCRIPTION))
+ : pa_sprintf_malloc("Combination port for %s", dev_name);
+
+ priority = is_sink ? dev->playback_priority : dev->capture_priority;
+ prio2 = (priority == 0 ? 0 : 1.0/priority);
+
+ for (i = 1; i < num; i++) {
+ char *tmp;
+
+ dev = pdevices[i];
+ dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
+
+ tmp = pa_sprintf_malloc("%s+%s", name, dev_name);
+ pa_xfree(name);
+ name = tmp;
+
+ tmp = pa_sprintf_malloc("%s,%s", desc, dev_name);
+ pa_xfree(desc);
+ desc = tmp;
+
+ priority = is_sink ? dev->playback_priority : dev->capture_priority;
+ if (priority != 0 && prio2 > 0)
+ prio2 += 1.0/priority;
+ }
+
+ /* Make combination ports always have lower priority, and use the formula
+ 1/p = 1/p1 + 1/p2 + ... 1/pn.
+ This way, the result will always be less than the individual components,
+ yet higher components will lead to higher result. */
+
+ if (num > 1)
+ priority = prio2 > 0 ? 1.0/prio2 : 0;
+
+ port = pa_hashmap_get(ports, name);
+ if (!port) {
+ pa_device_port_new_data port_data;
+
+ pa_device_port_new_data_init(&port_data);
+ pa_device_port_new_data_set_name(&port_data, name);
+ pa_device_port_new_data_set_description(&port_data, desc);
+ pa_device_port_new_data_set_direction(&port_data, is_sink ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT);
+ pa_node_new_data_set_fallback_name_prefix(&port_data.node_data, "alsa");
+
+ port = pa_device_port_new(core, &port_data, 0);
+ pa_device_port_new_data_done(&port_data);
+
+ if (!port) {
+ pa_log("Failed to create port %s.", name);
+ goto fail;
+ }
+
+ pa_hashmap_put(ports, port->name, port);
+ pa_dynarray_append(context->ports, port);
+ pa_log_debug("Add port %s: %s", port->name, port->description);
+ }
+
+ port->priority = priority;
+
+ pa_xfree(name);
+ name = NULL;
+ pa_xfree(desc);
+ desc = NULL;
+
+ direction = is_sink ? "output" : "input";
+ pa_log_debug("Port %s direction %s, priority %d", port->name, direction, priority);
+
+ return;
+
+fail:
+ pa_xfree(name);
+ pa_xfree(desc);
+}
+
+void pa_alsa_ucm_mapping_create_ports(pa_core *core, pa_alsa_mapping *mapping, pa_hashmap *ports) {
+ pa_alsa_ucm_mapping_context *context;
+ bool is_sink;
+ pa_alsa_ucm_device **combination_devices;
+ pa_alsa_ucm_device *device;
+ uint32_t idx;
+ unsigned dev_num = 0;
+
+ pa_assert(core);
+ pa_assert(mapping);
+ pa_assert(ports);
+
+ context = &mapping->ucm_context;
+ is_sink = context->direction == PA_DIRECTION_OUTPUT;
+
+ if (pa_idxset_isempty(context->ucm_devices))
+ return;
+
+ combination_devices = pa_xnew0(pa_alsa_ucm_device *, pa_idxset_size(context->ucm_devices));
+
+ PA_IDXSET_FOREACH(device, context->ucm_devices, idx) {
+ if (ucm_check_conformance(combination_devices, dev_num, device)) {
+ combination_devices[dev_num++] = device;
+ add_port_combination(context, is_sink, combination_devices, dev_num, ports, core);
+ }
+ }
+
+ pa_xfree(combination_devices);
+}
+
#else /* HAVE_ALSA_UCM */
/* Dummy functions for systems without UCM support */
@@ -1732,4 +1799,7 @@ void pa_alsa_ucm_roled_stream_begin(pa_alsa_ucm_config *ucm, const char *role, p
void pa_alsa_ucm_roled_stream_end(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir) {
}
+void pa_alsa_ucm_mapping_create_ports(pa_core *core, pa_alsa_mapping *mapping, pa_hashmap *ports) {
+}
+
#endif
diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h
index 66b27a0..605b1a3 100644
--- a/src/modules/alsa/alsa-ucm.h
+++ b/src/modules/alsa/alsa-ucm.h
@@ -195,4 +195,6 @@ struct pa_alsa_ucm_mapping_context {
pa_dynarray *ports;
};
+void pa_alsa_ucm_mapping_create_ports(pa_core *core, pa_alsa_mapping *mapping, pa_hashmap *ports);
+
#endif
--
1.8.3.1
More information about the pulseaudio-discuss
mailing list