[pulseaudio-discuss] [PATCH 1/3] alsa-mixer: Implement a new path option: "mute-during-activation".
Tanu Kaskinen
tanu.kaskinen at digia.com
Thu Mar 22 02:29:10 PDT 2012
---
src/modules/alsa/alsa-mixer.c | 27 +++++++++++++++++++-
src/modules/alsa/alsa-mixer.h | 3 +-
src/modules/alsa/alsa-sink.c | 6 ++--
src/modules/alsa/alsa-source.c | 6 ++--
.../alsa/mixer/paths/analog-output.conf.common | 3 ++
5 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 102ec82..c325367 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -1195,7 +1195,7 @@ 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_path_select(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t device_is_muted) {
pa_alsa_element *e;
int r = 0;
@@ -1205,6 +1205,19 @@ int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m) {
pa_log_debug("Activating path %s", p->name);
pa_alsa_path_dump(p);
+ /* First turn on hw mute if available, to avoid noise
+ * when setting the mixer controls. */
+ if (p->mute_during_activation) {
+ PA_LLIST_FOREACH(e, p->elements) {
+ if (e->switch_use == PA_ALSA_SWITCH_MUTE)
+ /* If the muting fails here, that's not a critical problem for
+ * selecting a path, so we ignore the return value.
+ * element_set_switch() will print a warning anyway, so this
+ * won't be silent failure either. */
+ (void) element_set_switch(e, m, FALSE);
+ }
+ }
+
PA_LLIST_FOREACH(e, p->elements) {
switch (e->switch_use) {
@@ -1243,6 +1256,16 @@ int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m) {
return -1;
}
+ /* Finally restore hw mute to the device mute status. */
+ if (p->mute_during_activation) {
+ PA_LLIST_FOREACH(e, p->elements) {
+ if (e->switch_use == PA_ALSA_SWITCH_MUTE) {
+ if (element_set_switch(e, m, !device_is_muted) < 0)
+ return -1;
+ }
+ }
+ }
+
return 0;
}
@@ -2416,6 +2439,7 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa
{ "priority", pa_config_parse_unsigned, NULL, "General" },
{ "description", pa_config_parse_string, NULL, "General" },
{ "name", pa_config_parse_string, NULL, "General" },
+ { "mute-during-activation", pa_config_parse_bool, NULL, "General" },
/* [Option ...] */
{ "priority", option_parse_priority, NULL, NULL },
@@ -2451,6 +2475,7 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa
items[0].data = &p->priority;
items[1].data = &p->description;
items[2].data = &p->name;
+ items[3].data = &p->mute_during_activation;
if (!paths_dir)
paths_dir = get_default_paths_dir();
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index 59bd3fb..dbcc887 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -181,6 +181,7 @@ struct pa_alsa_path {
char *name;
char *description;
unsigned priority;
+ pa_bool_t mute_during_activation;
pa_bool_t probed:1;
pa_bool_t supported:1;
@@ -228,7 +229,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_path_select(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t device_is_muted);
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);
diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index c88f4cf..76ea205 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -1458,7 +1458,7 @@ static int sink_set_port_cb(pa_sink *s, pa_device_port *p) {
data = PA_DEVICE_PORT_DATA(p);
pa_assert_se(u->mixer_path = data->path);
- pa_alsa_path_select(u->mixer_path, u->mixer_handle);
+ pa_alsa_path_select(u->mixer_path, u->mixer_handle, s->muted);
mixer_volume_init(u);
@@ -1897,7 +1897,7 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
data = PA_DEVICE_PORT_DATA(u->sink->active_port);
u->mixer_path = data->path;
- pa_alsa_path_select(data->path, u->mixer_handle);
+ pa_alsa_path_select(data->path, u->mixer_handle, u->sink->muted);
if (data->setting)
pa_alsa_setting_select(data->setting, u->mixer_handle);
@@ -1910,7 +1910,7 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
if (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);
+ pa_alsa_path_select(u->mixer_path, u->mixer_handle, u->sink->muted);
if (u->mixer_path->settings)
pa_alsa_setting_select(u->mixer_path->settings, u->mixer_handle);
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index 3e59340..c5f54c3 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -1361,7 +1361,7 @@ static int source_set_port_cb(pa_source *s, pa_device_port *p) {
data = PA_DEVICE_PORT_DATA(p);
pa_assert_se(u->mixer_path = data->path);
- pa_alsa_path_select(u->mixer_path, u->mixer_handle);
+ pa_alsa_path_select(u->mixer_path, u->mixer_handle, s->muted);
mixer_volume_init(u);
@@ -1634,7 +1634,7 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
data = PA_DEVICE_PORT_DATA(u->source->active_port);
u->mixer_path = data->path;
- pa_alsa_path_select(data->path, u->mixer_handle);
+ pa_alsa_path_select(data->path, u->mixer_handle, u->source->muted);
if (data->setting)
pa_alsa_setting_select(data->setting, u->mixer_handle);
@@ -1647,7 +1647,7 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
if (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);
+ pa_alsa_path_select(u->mixer_path, u->mixer_handle, u->source->muted);
if (u->mixer_path->settings)
pa_alsa_setting_select(u->mixer_path->settings, u->mixer_handle);
diff --git a/src/modules/alsa/mixer/paths/analog-output.conf.common b/src/modules/alsa/mixer/paths/analog-output.conf.common
index 160f222..db5418c 100644
--- a/src/modules/alsa/mixer/paths/analog-output.conf.common
+++ b/src/modules/alsa/mixer/paths/analog-output.conf.common
@@ -56,6 +56,9 @@
; [General]
; priority = ... # Priority for this path
; description = ...
+; mute-during-activation = yes | no # If this path supports hardware mute, should the hw mute be used while activating this
+; # path? In some cases this can reduce extra noises during port switching, while in other
+; # cases this can increase such noises. Default: no.
;
; [Option ...:...] # For each option of an enumeration or switch element
; # that shall be exposed as a sink/source port. Needs to
--
1.7.8
More information about the pulseaudio-discuss
mailing list