[pulseaudio-discuss] [PATCH 2/2] chnages in pulseaudio alsa module to support UCM
jankovac503 at gmail.com
jankovac503 at gmail.com
Wed Nov 2 16:55:24 PDT 2011
From: Janos Kovacs <jankovac503 at gmail.com>
---
src/Makefile.am | 1 +
src/modules/alsa/alsa-mixer.c | 80 ++++++++++++---------
src/modules/alsa/alsa-mixer.h | 19 ++++-
src/modules/alsa/alsa-sink.c | 58 +++++++++++---
src/modules/alsa/alsa-source.c | 53 +++++++++++---
src/modules/alsa/module-alsa-card.c | 138 +++++++++++++++++++++--------------
6 files changed, 234 insertions(+), 115 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index b5de764..0c97b7a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1563,6 +1563,7 @@ libalsa_util_la_SOURCES = \
modules/alsa/alsa-mixer.c modules/alsa/alsa-mixer.h \
modules/alsa/alsa-sink.c modules/alsa/alsa-sink.h \
modules/alsa/alsa-source.c modules/alsa/alsa-source.h \
+ modules/alsa/alsa-ucm.c modules/alsa/alsa-ucm.h \
modules/reserve-wrap.c modules/reserve-wrap.h
libalsa_util_la_LDFLAGS = -avoid-version
libalsa_util_la_LIBADD = $(MODULE_LIBADD) $(ASOUNDLIB_LIBS)
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 9a5c066..c063fed 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -557,6 +557,11 @@ void pa_alsa_path_free(pa_alsa_path *p) {
pa_xfree(p->name);
pa_xfree(p->description);
+ pa_xfree(p->ucm_verb);
+ pa_xfree(p->ucm_device);
+
+ pa_xstrfreev(p->ucm_modifiers);
+
pa_xfree(p);
}
@@ -1232,14 +1237,14 @@ static int element_set_constant_volume(pa_alsa_element *e, snd_mixer_t *m) {
return r;
}
-int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m) {
+int pa_alsa_mixer_path_select(pa_alsa_path *p, snd_mixer_t *m) {
pa_alsa_element *e;
int r = 0;
pa_assert(m);
pa_assert(p);
- pa_log_debug("Activating path %s", p->name);
+ pa_log_debug("Activating mixer path %s", p->name);
pa_alsa_path_dump(p);
PA_LLIST_FOREACH(e, p->elements) {
@@ -3070,32 +3075,36 @@ static void path_set_condense(pa_alsa_path_set *ps, snd_mixer_t *m) {
pa_alsa_path *p2;
void *state2;
+ if (p->use_ucm)
+ continue;
+
PA_HASHMAP_FOREACH(p2, ps->paths, state2) {
pa_alsa_element *ea, *eb;
pa_bool_t is_subset = TRUE;
- if (p == p2)
+ if (p == p2 || p2->use_ucm)
continue;
/* Compare the elements of each set... */
- pa_assert_se(ea = p->elements);
- pa_assert_se(eb = p2->elements);
-
- while (is_subset) {
- if (pa_streq(ea->alsa_name, eb->alsa_name)) {
- if (element_is_subset(ea, eb, m)) {
- ea = ea->next;
- eb = eb->next;
- if ((ea && !eb) || (!ea && eb))
- is_subset = FALSE;
- else if (!ea && !eb)
- break;
- } else
- is_subset = FALSE;
-
- } else
- is_subset = FALSE;
- }
+ if (!(ea = p->elements) || !(eb = p2->elements))
+ is_subset= FALSE;
+ else {
+ while (is_subset) {
+ if (pa_streq(ea->alsa_name, eb->alsa_name)) {
+ if (element_is_subset(ea, eb, m)) {
+ ea = ea->next;
+ eb = eb->next;
+ if ((ea && !eb) || (!ea && eb))
+ is_subset = FALSE;
+ else if (!ea && !eb)
+ break;
+ } else
+ is_subset = FALSE;
+
+ } else
+ is_subset = FALSE;
+ }
+ }
if (is_subset) {
pa_log_debug("Removing path '%s' as it is a subset of '%s'.", p->name, p2->name);
@@ -3188,6 +3197,9 @@ static void profile_free(pa_alsa_profile *p) {
if (p->output_mappings)
pa_idxset_free(p->output_mappings, NULL, NULL);
+ pa_xfree(p->ucm_verb);
+ pa_xstrfreev(p->ucm_modifiers);
+
pa_xfree(p);
}
@@ -3242,7 +3254,7 @@ void pa_alsa_profile_set_free(pa_alsa_profile_set *ps) {
pa_xfree(ps);
}
-static pa_alsa_mapping *mapping_get(pa_alsa_profile_set *ps, const char *name) {
+pa_alsa_mapping *pa_alsa_mapping_get(pa_alsa_profile_set *ps, const char *name) {
pa_alsa_mapping *m;
if (!pa_startswith(name, "Mapping "))
@@ -3317,7 +3329,7 @@ static int mapping_parse_device_strings(
pa_assert(ps);
- if (!(m = mapping_get(ps, section))) {
+ if (!(m = pa_alsa_mapping_get(ps, section))) {
pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
return -1;
}
@@ -3345,7 +3357,7 @@ static int mapping_parse_channel_map(
pa_assert(ps);
- if (!(m = mapping_get(ps, section))) {
+ if (!(m = pa_alsa_mapping_get(ps, section))) {
pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
return -1;
}
@@ -3372,7 +3384,7 @@ static int mapping_parse_paths(
pa_assert(ps);
- if (!(m = mapping_get(ps, section))) {
+ if (!(m = pa_alsa_mapping_get(ps, section))) {
pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
return -1;
}
@@ -3402,7 +3414,7 @@ static int mapping_parse_element(
pa_assert(ps);
- if (!(m = mapping_get(ps, section))) {
+ if (!(m = pa_alsa_mapping_get(ps, section))) {
pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
return -1;
}
@@ -3432,7 +3444,7 @@ static int mapping_parse_direction(
pa_assert(ps);
- if (!(m = mapping_get(ps, section))) {
+ if (!(m = pa_alsa_mapping_get(ps, section))) {
pa_log("[%s:%u] Section name %s invalid.", filename, line, section);
return -1;
}
@@ -3466,7 +3478,7 @@ static int mapping_parse_description(
pa_assert(ps);
- if ((m = mapping_get(ps, section))) {
+ if ((m = pa_alsa_mapping_get(ps, section))) {
pa_xfree(m->description);
m->description = pa_xstrdup(rvalue);
} else if ((p = profile_get(ps, section))) {
@@ -3501,7 +3513,7 @@ static int mapping_parse_priority(
return -1;
}
- if ((m = mapping_get(ps, section)))
+ if ((m = pa_alsa_mapping_get(ps, section)))
m->priority = prio;
else if ((p = profile_get(ps, section)))
p->priority = prio;
@@ -3744,7 +3756,7 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile,
pa_alsa_path_set_dump(ps);
}
-static int mapping_verify(pa_alsa_mapping *m, const pa_channel_map *bonus) {
+int pa_alsa_mapping_verify(pa_alsa_mapping *m, const pa_channel_map *bonus) {
static const struct description_map well_known_descriptions[] = {
{ "analog-mono", N_("Analog Mono") },
@@ -3882,7 +3894,7 @@ static void profile_set_add_auto(pa_alsa_profile_set *ps) {
profile_set_add_auto_pair(ps, NULL, n);
}
-static int profile_verify(pa_alsa_profile *p) {
+int pa_alsa_profile_verify(pa_alsa_profile *p) {
static const struct description_map well_known_descriptions[] = {
{ "output:analog-mono+input:analog-mono", N_("Analog Mono Duplex") },
@@ -4067,7 +4079,7 @@ void pa_alsa_decibel_fix_dump(pa_alsa_decibel_fix *db_fix) {
pa_xfree(db_values);
}
-pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel_map *bonus) {
+pa_alsa_profile_set* pa_alsa_mixer_profile_set_new(const char *fname, const pa_channel_map *bonus) {
pa_alsa_profile_set *ps;
pa_alsa_profile *p;
pa_alsa_mapping *m;
@@ -4126,14 +4138,14 @@ pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel
goto fail;
PA_HASHMAP_FOREACH(m, ps->mappings, state)
- if (mapping_verify(m, bonus) < 0)
+ if (pa_alsa_mapping_verify(m, bonus) < 0)
goto fail;
if (ps->auto_profiles)
profile_set_add_auto(ps);
PA_HASHMAP_FOREACH(p, ps->profiles, state)
- if (profile_verify(p) < 0)
+ if (pa_alsa_profile_verify(p) < 0)
goto fail;
PA_HASHMAP_FOREACH(db_fix, ps->decibel_fixes, state)
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index 74d12d6..55d3e0c 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -169,6 +169,7 @@ struct pa_alsa_path {
pa_bool_t has_mute:1;
pa_bool_t has_volume:1;
pa_bool_t has_dB:1;
+ pa_bool_t use_ucm:1;
/* These two are used during probing only */
pa_bool_t has_req_any:1;
pa_bool_t req_any_present:1;
@@ -184,6 +185,11 @@ struct pa_alsa_path {
PA_LLIST_HEAD(pa_alsa_element, elements);
PA_LLIST_HEAD(pa_alsa_setting, settings);
+
+ /* UCM stuff used only if use_ucm were TRUE */
+ char *ucm_verb;
+ char *ucm_device;
+ char **ucm_modifiers;
};
/* A path set is simply a set of paths that are applicable to a
@@ -209,7 +215,7 @@ int pa_alsa_path_get_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_ma
int pa_alsa_path_get_mute(pa_alsa_path *path, snd_mixer_t *m, pa_bool_t *muted);
int pa_alsa_path_set_volume(pa_alsa_path *path, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v, pa_bool_t deferred_volume, pa_bool_t write_to_hw);
int pa_alsa_path_set_mute(pa_alsa_path *path, snd_mixer_t *m, pa_bool_t muted);
-int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m);
+int pa_alsa_mixer_path_select(pa_alsa_path *p, snd_mixer_t *m);
void pa_alsa_path_set_callback(pa_alsa_path *p, snd_mixer_t *m, snd_mixer_elem_callback_t cb, void *userdata);
void pa_alsa_path_free(pa_alsa_path *p);
@@ -262,6 +268,9 @@ struct pa_alsa_profile {
pa_idxset *input_mappings;
pa_idxset *output_mappings;
+
+ char *ucm_verb;
+ char **ucm_modifiers;
};
struct pa_alsa_decibel_fix {
@@ -290,16 +299,22 @@ struct pa_alsa_profile_set {
pa_bool_t auto_profiles;
pa_bool_t ignore_dB:1;
pa_bool_t probed:1;
+ pa_bool_t use_ucm;
};
void pa_alsa_mapping_dump(pa_alsa_mapping *m);
void pa_alsa_profile_dump(pa_alsa_profile *p);
void pa_alsa_decibel_fix_dump(pa_alsa_decibel_fix *db_fix);
-pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel_map *bonus);
+pa_alsa_profile_set* pa_alsa_mixer_profile_set_new(const char *fname, const pa_channel_map *bonus);
void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, const pa_sample_spec *ss, unsigned default_n_fragments, unsigned default_fragment_size_msec);
void pa_alsa_profile_set_free(pa_alsa_profile_set *s);
void pa_alsa_profile_set_dump(pa_alsa_profile_set *s);
+int pa_alsa_profile_verify(pa_alsa_profile *p);
+
+pa_alsa_mapping *pa_alsa_mapping_get(pa_alsa_profile_set *ps, const char *name);
+int pa_alsa_mapping_verify(pa_alsa_mapping *m, const pa_channel_map *bonus);
+
snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device);
diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 647b0cd..fc2455d 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -58,6 +58,7 @@
#include "alsa-util.h"
#include "alsa-sink.h"
+#include "alsa-ucm.h"
/* #define DEBUG_TIMING */
@@ -1445,15 +1446,24 @@ static void mixer_volume_init(struct userdata *u) {
static int sink_set_port_cb(pa_sink *s, pa_device_port *p) {
struct userdata *u = s->userdata;
pa_alsa_port_data *data;
+ struct pa_alsa_ucm_config *ucm;
+ pa_alsa_path *newpath, *oldpath;
+
pa_assert(u);
pa_assert(p);
pa_assert(u->mixer_handle);
data = PA_DEVICE_PORT_DATA(p);
+ ucm = pa_alsa_card_get_ucm_config(s->card);
+ oldpath = u->mixer_path;
+
+ pa_assert_se(u->mixer_path = newpath = data->path);
- pa_assert_se(u->mixer_path = data->path);
- pa_alsa_path_select(u->mixer_path, u->mixer_handle);
+ if (newpath->use_ucm)
+ pa_alsa_ucm_path_select(newpath, oldpath, ucm);
+ else
+ pa_alsa_mixer_path_select(newpath, u->mixer_handle);
mixer_volume_init(u);
@@ -1872,8 +1882,13 @@ fail:
static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
pa_bool_t need_mixer_callback = FALSE;
+ struct pa_alsa_ucm_config *ucm;
+ pa_alsa_path *path;
pa_assert(u);
+ pa_assert(u->sink);
+
+ ucm = pa_alsa_card_get_ucm_config(u->sink->card);
if (!u->mixer_handle)
return 0;
@@ -1885,9 +1900,12 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
* one that has been chosen as active */
data = PA_DEVICE_PORT_DATA(u->sink->active_port);
- u->mixer_path = data->path;
+ path = u->mixer_path = data->path;
- pa_alsa_path_select(data->path, u->mixer_handle);
+ if (path->use_ucm)
+ pa_alsa_ucm_path_select(path, NULL, ucm);
+ else
+ pa_alsa_mixer_path_select(path, u->mixer_handle);
if (data->setting)
pa_alsa_setting_select(data->setting, u->mixer_handle);
@@ -1897,13 +1915,16 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
if (!u->mixer_path && u->mixer_path_set)
u->mixer_path = pa_hashmap_first(u->mixer_path_set->paths);
- if (u->mixer_path) {
+ if ((path = u->mixer_path)) {
/* Hmm, we have only a single path, then let's activate it */
- pa_alsa_path_select(u->mixer_path, u->mixer_handle);
+ if (path->use_ucm)
+ pa_alsa_ucm_path_select(path, NULL, ucm);
+ else
+ pa_alsa_mixer_path_select(path, u->mixer_handle);
- if (u->mixer_path->settings)
- pa_alsa_setting_select(u->mixer_path->settings, u->mixer_handle);
+ if (path->settings)
+ pa_alsa_setting_select(path->settings, u->mixer_handle);
} else
return 0;
}
@@ -2088,7 +2109,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
} else if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
- if (!(profile_set = pa_alsa_profile_set_new(NULL, &map)))
+ if (!(profile_set = pa_alsa_mixer_profile_set_new(NULL, &map)))
goto fail;
if (!(u->pcm_handle = pa_alsa_open_by_device_id_auto(
@@ -2328,7 +2349,13 @@ fail:
}
static void userdata_free(struct userdata *u) {
+ struct pa_alsa_ucm_config *ucm;
+ struct pa_alsa_path *path;
+
pa_assert(u);
+ pa_assert(u->sink);
+ ucm = pa_alsa_card_get_ucm_config(u->sink->card);
+ pa_assert(ucm);
if (u->sink)
pa_sink_unlink(u->sink);
@@ -2363,10 +2390,15 @@ static void userdata_free(struct userdata *u) {
if (u->mixer_fdl)
pa_alsa_fdlist_free(u->mixer_fdl);
-/* if (u->mixer_path_set)
- pa_alsa_path_set_free(u->mixer_path_set); Owned by the profile set */
- if (u->mixer_path && !u->mixer_path_set)
- pa_alsa_path_free(u->mixer_path);
+ if ((path = u->mixer_path)) {
+ if (path->use_ucm)
+ pa_alsa_ucm_path_select(NULL, path, ucm);
+
+ /* if (u->mixer_path_set)
+ pa_alsa_path_set_free(u->mixer_path_set); Owned by the profile set */
+ if (!u->mixer_path_set)
+ pa_alsa_path_free(path);
+ }
if (u->mixer_handle)
snd_mixer_close(u->mixer_handle);
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index cff8ce1..4a0a64f 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -53,6 +53,7 @@
#include "alsa-util.h"
#include "alsa-source.h"
+#include "alsa-ucm.h"
/* #define DEBUG_TIMING */
@@ -1348,15 +1349,23 @@ static void mixer_volume_init(struct userdata *u) {
static int source_set_port_cb(pa_source *s, pa_device_port *p) {
struct userdata *u = s->userdata;
pa_alsa_port_data *data;
+ struct pa_alsa_ucm_config *ucm;
+ pa_alsa_path *newpath, *oldpath;
pa_assert(u);
pa_assert(p);
pa_assert(u->mixer_handle);
data = PA_DEVICE_PORT_DATA(p);
+ ucm = pa_alsa_card_get_ucm_config(s->card);
+ oldpath = u->mixer_path;
- pa_assert_se(u->mixer_path = data->path);
- pa_alsa_path_select(u->mixer_path, u->mixer_handle);
+ pa_assert_se(u->mixer_path = newpath = data->path);
+
+ if (newpath->use_ucm)
+ pa_alsa_ucm_path_select(newpath, oldpath, ucm);
+ else
+ pa_alsa_mixer_path_select(newpath, u->mixer_handle);
mixer_volume_init(u);
@@ -1613,8 +1622,13 @@ fail:
static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
pa_bool_t need_mixer_callback = FALSE;
+ struct pa_alsa_ucm_config *ucm;
+ pa_alsa_path *path;
pa_assert(u);
+ pa_assert(u->source);
+
+ ucm = pa_alsa_card_get_ucm_config(u->source->card);
if (!u->mixer_handle)
return 0;
@@ -1626,9 +1640,12 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
* one that has been chosen as active */
data = PA_DEVICE_PORT_DATA(u->source->active_port);
- u->mixer_path = data->path;
+ path = u->mixer_path = data->path;
- pa_alsa_path_select(data->path, u->mixer_handle);
+ if (path->use_ucm)
+ pa_alsa_ucm_path_select(path, NULL, ucm);
+ else
+ pa_alsa_mixer_path_select(path, u->mixer_handle);
if (data->setting)
pa_alsa_setting_select(data->setting, u->mixer_handle);
@@ -1638,13 +1655,16 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
if (!u->mixer_path && u->mixer_path_set)
u->mixer_path = pa_hashmap_first(u->mixer_path_set->paths);
- if (u->mixer_path) {
+ if ((path = u->mixer_path)) {
/* Hmm, we have only a single path, then let's activate it */
- pa_alsa_path_select(u->mixer_path, u->mixer_handle);
+ if (path->use_ucm)
+ pa_alsa_ucm_path_select(path, NULL, ucm);
+ else
+ pa_alsa_mixer_path_select(path, u->mixer_handle);
- if (u->mixer_path->settings)
- pa_alsa_setting_select(u->mixer_path->settings, u->mixer_handle);
+ if (path->settings)
+ pa_alsa_setting_select(path->settings, u->mixer_handle);
} else
return 0;
}
@@ -1822,7 +1842,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
} else if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
- if (!(profile_set = pa_alsa_profile_set_new(NULL, &map)))
+ if (!(profile_set = pa_alsa_mixer_profile_set_new(NULL, &map)))
goto fail;
if (!(u->pcm_handle = pa_alsa_open_by_device_id_auto(
@@ -2036,7 +2056,13 @@ fail:
}
static void userdata_free(struct userdata *u) {
+ struct pa_alsa_ucm_config *ucm;
+ struct pa_alsa_path *path;
+
pa_assert(u);
+ pa_assert(u->source);
+ ucm = pa_alsa_card_get_ucm_config(u->source->card);
+ pa_assert(ucm);
if (u->source)
pa_source_unlink(u->source);
@@ -2068,8 +2094,13 @@ static void userdata_free(struct userdata *u) {
if (u->mixer_fdl)
pa_alsa_fdlist_free(u->mixer_fdl);
- if (u->mixer_path && !u->mixer_path_set)
- pa_alsa_path_free(u->mixer_path);
+ if ((path = u->mixer_path)) {
+ if (path->use_ucm)
+ pa_alsa_ucm_path_select(NULL, path, ucm);
+
+ if (!u->mixer_path_set)
+ pa_alsa_path_free(path);
+ }
if (u->mixer_handle)
snd_mixer_close(u->mixer_handle);
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 6bcf48b..1bed403 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -39,6 +39,7 @@
#include "alsa-util.h"
#include "alsa-sink.h"
#include "alsa-source.h"
+#include "alsa-ucm.h"
#include "module-alsa-card-symdef.h"
PA_MODULE_AUTHOR("Lennart Poettering");
@@ -109,12 +110,23 @@ struct userdata {
pa_modargs *modargs;
pa_alsa_profile_set *profile_set;
-};
-struct profile_data {
- pa_alsa_profile *profile;
+ pa_alsa_ucm_config ucm;
};
+
+pa_alsa_ucm_config *pa_alsa_card_get_ucm_config(pa_card *card)
+{
+ struct userdata *u;
+ pa_alsa_ucm_config *ucm = NULL;
+
+
+ if (card && (u = card->userdata))
+ ucm = &u->ucm;
+
+ return ucm;
+}
+
static void add_profiles(struct userdata *u, pa_hashmap *h, pa_hashmap *ports) {
pa_alsa_profile *ap;
void *state;
@@ -184,59 +196,69 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
nd = PA_CARD_PROFILE_DATA(new_profile);
od = PA_CARD_PROFILE_DATA(c->active_profile);
- if (od->profile && od->profile->output_mappings)
- PA_IDXSET_FOREACH(am, od->profile->output_mappings, idx) {
- if (!am->sink)
- continue;
-
- if (nd->profile &&
- nd->profile->output_mappings &&
- pa_idxset_get_by_data(nd->profile->output_mappings, am, NULL))
- continue;
-
- sink_inputs = pa_sink_move_all_start(am->sink, sink_inputs);
- pa_alsa_sink_free(am->sink);
- am->sink = NULL;
- }
-
- if (od->profile && od->profile->input_mappings)
- PA_IDXSET_FOREACH(am, od->profile->input_mappings, idx) {
- if (!am->source)
- continue;
-
- if (nd->profile &&
- nd->profile->input_mappings &&
- pa_idxset_get_by_data(nd->profile->input_mappings, am, NULL))
- continue;
+ pa_assert(nd);
+ pa_assert(od);
+
+ if (od->profile) {
+ if (od->profile->output_mappings)
+ PA_IDXSET_FOREACH(am, od->profile->output_mappings, idx) {
+ if (!am->sink)
+ continue;
+
+ if (nd->profile &&
+ nd->profile->output_mappings &&
+ pa_idxset_get_by_data(nd->profile->output_mappings, am, NULL))
+ continue;
+
+ sink_inputs = pa_sink_move_all_start(am->sink, sink_inputs);
+ pa_alsa_sink_free(am->sink);
+ am->sink = NULL;
+ }
+
+ if (od->profile->input_mappings)
+ PA_IDXSET_FOREACH(am, od->profile->input_mappings, idx) {
+ if (!am->source)
+ continue;
+
+ if (nd->profile &&
+ nd->profile->input_mappings &&
+ pa_idxset_get_by_data(nd->profile->input_mappings, am, NULL))
+ continue;
+
+ source_outputs = pa_source_move_all_start(am->source, source_outputs);
+ pa_alsa_source_free(am->source);
+ am->source = NULL;
+ }
+ }
- source_outputs = pa_source_move_all_start(am->source, source_outputs);
- pa_alsa_source_free(am->source);
- am->source = NULL;
- }
+ if (u->ucm.enabled)
+ pa_alsa_ucm_profile_select(nd->profile, od->profile, &u->ucm);
- if (nd->profile && nd->profile->output_mappings)
- PA_IDXSET_FOREACH(am, nd->profile->output_mappings, idx) {
+ if (nd->profile) {
+ if (nd->profile->output_mappings)
+ PA_IDXSET_FOREACH(am, nd->profile->output_mappings, idx) {
- if (!am->sink)
- am->sink = pa_alsa_sink_new(c->module, u->modargs, __FILE__, c, am);
+ if (!am->sink)
+ am->sink = pa_alsa_sink_new(c->module, u->modargs, __FILE__, c, am);
- if (sink_inputs && am->sink) {
- pa_sink_move_all_finish(am->sink, sink_inputs, FALSE);
- sink_inputs = NULL;
- }
- }
+ if (sink_inputs && am->sink) {
+ pa_sink_move_all_finish(am->sink, sink_inputs, FALSE);
+ sink_inputs = NULL;
+ }
+ }
- if (nd->profile && nd->profile->input_mappings)
- PA_IDXSET_FOREACH(am, nd->profile->input_mappings, idx) {
+ if (nd->profile && nd->profile->input_mappings)
+ PA_IDXSET_FOREACH(am, nd->profile->input_mappings, idx) {
- if (!am->source)
- am->source = pa_alsa_source_new(c->module, u->modargs, __FILE__, c, am);
+ if (!am->source)
+ am->source = pa_alsa_source_new(c->module, u->modargs, __FILE__, c, am);
- if (source_outputs && am->source) {
- pa_source_move_all_finish(am->source, source_outputs, FALSE);
- source_outputs = NULL;
- }
- }
+ if (source_outputs && am->source) {
+ pa_source_move_all_finish(am->source, source_outputs, FALSE);
+ source_outputs = NULL;
+ }
+ }
+ }
if (sink_inputs)
pa_sink_move_all_fail(sink_inputs);
@@ -302,6 +324,7 @@ int pa__init(pa_module *m) {
const char *profile = NULL;
char *fn = NULL;
pa_bool_t namereg_fail = FALSE;
+ pa_channel_map *def_chmap;
pa_alsa_refcnt_inc();
@@ -340,18 +363,23 @@ int pa__init(pa_module *m) {
}
}
+ def_chmap = &u->core->default_channel_map;
+
+ if (!(u->profile_set = pa_alsa_ucm_profile_set_new(alsa_card_index, &u->ucm, def_chmap))) {
+
#ifdef HAVE_UDEV
- fn = pa_udev_get_property(alsa_card_index, "PULSE_PROFILE_SET");
+ fn = pa_udev_get_property(alsa_card_index, "PULSE_PROFILE_SET");
#endif
- if (pa_modargs_get_value(ma, "profile_set", NULL)) {
+ if (pa_modargs_get_value(ma, "profile_set", NULL)) {
+ pa_xfree(fn);
+ fn = pa_xstrdup(pa_modargs_get_value(ma, "profile_set", NULL));
+ }
+
+ u->profile_set = pa_alsa_mixer_profile_set_new(fn, &u->core->default_channel_map);
pa_xfree(fn);
- fn = pa_xstrdup(pa_modargs_get_value(ma, "profile_set", NULL));
}
- u->profile_set = pa_alsa_profile_set_new(fn, &u->core->default_channel_map);
- pa_xfree(fn);
-
u->profile_set->ignore_dB = ignore_dB;
if (!u->profile_set)
--
1.7.5.2
More information about the pulseaudio-discuss
mailing list