mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
alsa-ucm: Split out helpers for device set name, description, priority
Combination port logic calculates some useful properties for device groups that we could reuse while generating multiple profiles to support conflicting devices. Split them into their own functions. Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com> Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/596>
This commit is contained in:
parent
5245117781
commit
e8e2f4320c
1 changed files with 119 additions and 36 deletions
|
|
@ -1045,6 +1045,109 @@ fail:
|
|||
}
|
||||
}
|
||||
|
||||
static char *devset_name(pa_idxset *devices, const char *sep) {
|
||||
int i = 0;
|
||||
int num = pa_idxset_size(devices);
|
||||
pa_alsa_ucm_device *sorted[num], *dev;
|
||||
char *dev_names = NULL;
|
||||
char *tmp = NULL;
|
||||
uint32_t idx;
|
||||
|
||||
PA_IDXSET_FOREACH(dev, devices, idx) {
|
||||
sorted[i] = dev;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Sort by alphabetical order so as to have a deterministic naming scheme */
|
||||
qsort(&sorted[0], num, sizeof(pa_alsa_ucm_device *), pa_alsa_ucm_device_cmp);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
dev = sorted[i];
|
||||
const char *dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
|
||||
|
||||
if (!dev_names) {
|
||||
dev_names = pa_xstrdup(dev_name);
|
||||
} else {
|
||||
tmp = pa_sprintf_malloc("%s%s%s", dev_names, sep, dev_name);
|
||||
pa_xfree(dev_names);
|
||||
dev_names = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return dev_names;
|
||||
}
|
||||
|
||||
static char *devset_description(pa_idxset *devices, const char *sep) {
|
||||
int i = 0;
|
||||
int num = pa_idxset_size(devices);
|
||||
pa_alsa_ucm_device *sorted[num], *dev;
|
||||
char *dev_descs = NULL;
|
||||
char *tmp = NULL;
|
||||
uint32_t idx;
|
||||
|
||||
PA_IDXSET_FOREACH(dev, devices, idx) {
|
||||
sorted[i] = dev;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Sort by alphabetical order to match devset_name() */
|
||||
qsort(&sorted[0], num, sizeof(pa_alsa_ucm_device *), pa_alsa_ucm_device_cmp);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
dev = sorted[i];
|
||||
const char *dev_desc = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_DESCRIPTION);
|
||||
|
||||
if (!dev_descs) {
|
||||
dev_descs = pa_xstrdup(dev_desc);
|
||||
} else {
|
||||
tmp = pa_sprintf_malloc("%s%s%s", dev_descs, sep, dev_desc);
|
||||
pa_xfree(dev_descs);
|
||||
dev_descs = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return dev_descs;
|
||||
}
|
||||
|
||||
/* If invert is true, uses 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. */
|
||||
static unsigned devset_playback_priority(pa_idxset *devices, bool invert) {
|
||||
pa_alsa_ucm_device *dev;
|
||||
uint32_t idx;
|
||||
double priority = 0;
|
||||
|
||||
PA_IDXSET_FOREACH(dev, devices, idx) {
|
||||
if (dev->playback_priority > 0 && invert)
|
||||
priority += 1.0 / dev->playback_priority;
|
||||
else
|
||||
priority += dev->playback_priority;
|
||||
}
|
||||
|
||||
if (priority > 0 && invert)
|
||||
return 1.0 / priority;
|
||||
|
||||
return (unsigned) priority;
|
||||
}
|
||||
|
||||
static unsigned devset_capture_priority(pa_idxset *devices, bool invert) {
|
||||
pa_alsa_ucm_device *dev;
|
||||
uint32_t idx;
|
||||
double priority = 0;
|
||||
|
||||
PA_IDXSET_FOREACH(dev, devices, idx) {
|
||||
if (dev->capture_priority > 0 && invert)
|
||||
priority += 1.0 / dev->capture_priority;
|
||||
else
|
||||
priority += dev->capture_priority;
|
||||
}
|
||||
|
||||
if (priority > 0 && invert)
|
||||
return 1.0 / priority;
|
||||
|
||||
return (unsigned) priority;
|
||||
}
|
||||
|
||||
static void ucm_add_port_combination(
|
||||
pa_hashmap *hash,
|
||||
pa_alsa_ucm_mapping_context *context,
|
||||
|
|
@ -1059,9 +1162,7 @@ static void ucm_add_port_combination(
|
|||
int num = pa_idxset_size(devices);
|
||||
uint32_t idx;
|
||||
unsigned priority;
|
||||
double prio2;
|
||||
char *name, *desc;
|
||||
const char *dev_name;
|
||||
char *name, *desc, *tmp;
|
||||
const char *direction;
|
||||
const char *profile;
|
||||
pa_alsa_ucm_device *sorted[num], *dev;
|
||||
|
|
@ -1081,36 +1182,26 @@ static void ucm_add_port_combination(
|
|||
* for combination ports */
|
||||
qsort(&sorted[0], num, sizeof(pa_alsa_ucm_device *), pa_alsa_ucm_device_cmp);
|
||||
|
||||
name = devset_name(devices, "+");
|
||||
tmp = pa_sprintf_malloc("%s%s", is_sink ? PA_UCM_PRE_TAG_OUTPUT : PA_UCM_PRE_TAG_INPUT, name);
|
||||
pa_xfree(name);
|
||||
name = tmp;
|
||||
|
||||
desc = devset_description(devices, ", ");
|
||||
if (pa_idxset_size(devices) > 1) {
|
||||
tmp = pa_sprintf_malloc("Combination port for %s", desc);
|
||||
pa_xfree(desc);
|
||||
desc = tmp;
|
||||
}
|
||||
|
||||
/* Make combination ports always have lower priority */
|
||||
priority = is_sink ? devset_playback_priority(devices, true) : devset_capture_priority(devices, true);
|
||||
|
||||
dev = sorted[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);
|
||||
jack = ucm_get_jack(context->ucm, dev);
|
||||
type = dev->type;
|
||||
|
||||
for (i = 1; i < num; i++) {
|
||||
char *tmp;
|
||||
|
||||
dev = sorted[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;
|
||||
|
||||
jack2 = ucm_get_jack(context->ucm, dev);
|
||||
if (jack2) {
|
||||
if (jack && jack != jack2)
|
||||
|
|
@ -1126,14 +1217,6 @@ static void ucm_add_port_combination(
|
|||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue