alsa-mixer: Implement a new path option: "mute-during-activation".

This commit is contained in:
Tanu Kaskinen 2012-03-22 11:29:10 +02:00 committed by Tanu Kaskinen
parent ea064162a5
commit 8417cac4f6
5 changed files with 40 additions and 8 deletions

View file

@ -1196,7 +1196,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, bool device_is_muted) {
pa_alsa_element *e;
int r = 0;
@ -1206,6 +1206,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 a silent failure either. */
(void) element_set_switch(e, m, FALSE);
}
}
PA_LLIST_FOREACH(e, p->elements) {
switch (e->switch_use) {
@ -1244,6 +1257,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;
}
@ -2353,12 +2376,14 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa
char *fn;
int r;
const char *n;
bool mute_during_activation = false;
pa_config_item items[] = {
/* [General] */
{ "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 },
@ -2395,6 +2420,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 = &mute_during_activation;
if (!paths_dir)
paths_dir = get_default_paths_dir();
@ -2407,6 +2433,8 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa
if (r < 0)
goto fail;
p->mute_during_activation = mute_during_activation;
if (path_verify(p) < 0)
goto fail;

View file

@ -188,6 +188,7 @@ struct pa_alsa_path {
pa_bool_t has_mute:1;
pa_bool_t has_volume:1;
pa_bool_t has_dB:1;
bool mute_during_activation:1;
/* These two are used during probing only */
pa_bool_t has_req_any:1;
pa_bool_t req_any_present:1;
@ -229,7 +230,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, bool 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);

View file

@ -1461,7 +1461,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);
@ -1905,7 +1905,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);
@ -1918,7 +1918,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);

View file

@ -1364,7 +1364,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);
@ -1642,7 +1642,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);
@ -1655,7 +1655,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);

View file

@ -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.
;
; [Properties] # Property list for this path. The list is merged into the port property list.
; <key> = <value> # Each property is defined on its own line.