[pulseaudio-discuss] [RFC Patch 2/3] Support UCM in Pulseaudio
Feng Wei
feng.wei at linaro.org
Tue Nov 15 19:51:22 PST 2011
add port for ucm
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index b6cf085..2cd37a9 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -3168,6 +3168,8 @@ static void mapping_free(pa_alsa_mapping *m) {
pa_xstrfreev(m->input_element);
pa_xstrfreev(m->output_element);
+ pa_xfree(m->ucm_devices);
+
pa_assert(!m->input_pcm);
pa_assert(!m->output_pcm);
@@ -3225,7 +3227,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 *mapping_get(pa_alsa_profile_set *ps, const char *name) {
pa_alsa_mapping *m;
if (!pa_startswith(name, "Mapping "))
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index c9d968a..fc206f5 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -47,6 +47,7 @@ typedef struct pa_alsa_profile_set pa_alsa_profile_set;
typedef struct pa_alsa_port_data pa_alsa_port_data;
#include "alsa-util.h"
+#include "alsa-ucm.h"
typedef enum pa_alsa_switch_use {
PA_ALSA_SWITCH_IGNORE,
@@ -226,6 +227,8 @@ void pa_alsa_path_set_dump(pa_alsa_path_set *s);
void pa_alsa_path_set_set_callback(pa_alsa_path_set *ps, snd_mixer_t
*m, snd_mixer_elem_callback_t cb, void *userdata);
void pa_alsa_path_set_free(pa_alsa_path_set *s);
+pa_alsa_mapping *mapping_get(pa_alsa_profile_set *ps, const char *name);
+
struct pa_alsa_mapping {
pa_alsa_profile_set *profile_set;
@@ -251,6 +254,11 @@ struct pa_alsa_mapping {
pa_sink *sink;
pa_source *source;
+
+ /* ucm device */
+ pa_alsa_ucm_config *ucm;
+ int ucm_devices_num;
+ pa_alsa_ucm_device **ucm_devices;
};
struct pa_alsa_profile {
diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 066f2dd..6cc43ee 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -1450,6 +1450,16 @@ static void mixer_volume_init(struct userdata *u) {
}
}
+static int sink_set_port_ucm_cb(pa_sink *s, pa_device_port *p) {
+ pa_alsa_port_data_ucm *data;
+
+ pa_assert(p);
+
+ data = PA_DEVICE_PORT_DATA(p);
+
+ return ucm_set_port(data);
+}
+
static int sink_set_port_cb(pa_sink *s, pa_device_port *p) {
struct userdata *u = s->userdata;
pa_alsa_port_data *data;
@@ -1846,6 +1856,18 @@ fail:
}
}
+/* FIXME: hardware volume/mute ??? */
+static int ucm_setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
+ pa_assert(u && u->sink);
+
+ if (u->sink->active_port) {
+ pa_alsa_port_data_ucm *data;
+ data = PA_DEVICE_PORT_DATA(u->sink->active_port);
+ return ucm_set_port(data);
+ }
+
+ return 0;
+}
static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
pa_bool_t need_mixer_callback = FALSE;
@@ -2113,7 +2135,8 @@ pa_sink *pa_alsa_sink_new(pa_module *m,
pa_modargs *ma, const char*driver, pa_ca
/* ALSA might tweak the sample spec, so recalculate the frame size */
frame_size = pa_frame_size(&ss);
- find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL),
ignore_dB);
+ if (!mapping->ucm)
+ find_mixer(u, mapping, pa_modargs_get_value(ma, "control",
NULL), ignore_dB);
pa_sink_new_data_init(&data);
data.driver = driver;
@@ -2158,7 +2181,9 @@ pa_sink *pa_alsa_sink_new(pa_module *m,
pa_modargs *ma, const char*driver, pa_ca
goto fail;
}
- if (u->mixer_path_set)
+ if (mapping->ucm)
+ ucm_add_ports(&data.ports, data.proplist, mapping);
+ else if (u->mixer_path_set)
pa_alsa_add_ports(&data.ports, u->mixer_path_set);
u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE |
PA_SINK_LATENCY | (u->use_tsched ? PA_SINK_DYNAMIC_LATENCY : 0) |
@@ -2186,7 +2211,10 @@ pa_sink *pa_alsa_sink_new(pa_module *m,
pa_modargs *ma, const char*driver, pa_ca
if (u->use_tsched)
u->sink->update_requested_latency = sink_update_requested_latency_cb;
u->sink->set_state = sink_set_state_cb;
- u->sink->set_port = sink_set_port_cb;
+ if (mapping->ucm)
+ u->sink->set_port = sink_set_port_ucm_cb;
+ else
+ u->sink->set_port = sink_set_port_cb;
u->sink->userdata = u;
pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
@@ -2238,7 +2266,11 @@ pa_sink *pa_alsa_sink_new(pa_module *m,
pa_modargs *ma, const char*driver, pa_ca
if (update_sw_params(u) < 0)
goto fail;
- if (setup_mixer(u, ignore_dB) < 0)
+ if (mapping->ucm) {
+ if (ucm_setup_mixer(u, ignore_dB) < 0)
+ goto fail;
+ }
+ else if (setup_mixer(u, ignore_dB) < 0)
goto fail;
pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index f03b76e..1a3812b 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -1301,6 +1301,16 @@ static void mixer_volume_init(struct userdata *u) {
}
}
+static int source_set_port_ucm_cb(pa_source *s, pa_device_port *p) {
+ pa_alsa_port_data_ucm *data;
+
+ pa_assert(p);
+
+ data = PA_DEVICE_PORT_DATA(p);
+
+ return ucm_set_port(data);
+}
+
static int source_set_port_cb(pa_source *s, pa_device_port *p) {
struct userdata *u = s->userdata;
pa_alsa_port_data *data;
@@ -1546,6 +1556,19 @@ fail:
}
}
+/* FIXME: hardware volume/mute ??? */
+static int ucm_setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
+ pa_assert(u && u->source);
+
+ if (u->source->active_port) {
+ pa_alsa_port_data_ucm *data;
+ data = PA_DEVICE_PORT_DATA(u->source->active_port);
+ return ucm_set_port(data);
+ }
+
+ return 0;
+}
+
static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
pa_bool_t need_mixer_callback = FALSE;
@@ -1802,7 +1825,8 @@ pa_source *pa_alsa_source_new(pa_module *m,
pa_modargs *ma, const char*driver, p
/* ALSA might tweak the sample spec, so recalculate the frame size */
frame_size = pa_frame_size(&ss);
- find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL),
ignore_dB);
+ if (mapping->ucm)
+ find_mixer(u, mapping, pa_modargs_get_value(ma, "control",
NULL), ignore_dB);
pa_source_new_data_init(&data);
data.driver = driver;
@@ -1847,7 +1871,9 @@ pa_source *pa_alsa_source_new(pa_module *m,
pa_modargs *ma, const char*driver, p
goto fail;
}
- if (u->mixer_path_set)
+ if (mapping->ucm)
+ ucm_add_ports(&data.ports, data.proplist, mapping);
+ else if (u->mixer_path_set)
pa_alsa_add_ports(&data.ports, u->mixer_path_set);
u->source = pa_source_new(m->core, &data,
PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|(u->use_tsched ?
PA_SOURCE_DYNAMIC_LATENCY : 0));
@@ -1874,7 +1900,10 @@ pa_source *pa_alsa_source_new(pa_module *m,
pa_modargs *ma, const char*driver, p
if (u->use_tsched)
u->source->update_requested_latency =
source_update_requested_latency_cb;
u->source->set_state = source_set_state_cb;
- u->source->set_port = source_set_port_cb;
+ if (mapping->ucm)
+ u->source->set_port = source_set_port_ucm_cb;
+ else
+ u->source->set_port = source_set_port_cb;
u->source->userdata = u;
pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
@@ -1918,7 +1947,11 @@ pa_source *pa_alsa_source_new(pa_module *m,
pa_modargs *ma, const char*driver, p
if (update_sw_params(u) < 0)
goto fail;
- if (setup_mixer(u, ignore_dB) < 0)
+ if (mapping->ucm) {
+ if (ucm_setup_mixer(u, ignore_dB) < 0)
+ goto fail;
+ }
+ else if (setup_mixer(u, ignore_dB) < 0)
goto fail;
pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);
--
Wei.Feng (irc wei_feng)
Linaro Multimedia Team
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
More information about the pulseaudio-discuss
mailing list