[pulseaudio-discuss] [PATCH] Hack around a bug in the core causing volumes not to be set on port change.
David Henningsson
david.henningsson at canonical.com
Thu Oct 13 08:36:34 PDT 2011
Two problems:
1) Old volume is lingering in some variables after port change
2) If there's nothing in m-d-r database, volume is not updated for the new port
After some talk with Colin Guthrie this morning, I believe a better long-term
fix would be to have per port volumes stored in the core, and not retrieving
them from the database on port change, but such a change would be too heavy
for a stable release.
So this is more of a quick hack.
Signed-off-by: David Henningsson <david.henningsson at canonical.com>
---
Note: I don't know if upstream is interested; if not, see it just as information of
what I'm doing to fixup things downstream (i e Ubuntu 11.10).
diff --git a/src/modules/module-device-restore.c b/src/modules/module-device-restore.c
index de98035..685a691 100644
--- a/src/modules/module-device-restore.c
+++ b/src/modules/module-device-restore.c
@@ -812,6 +812,8 @@ static pa_hook_result_t sink_fixate_hook_callback(pa_core *c, pa_sink_new_data *
static pa_hook_result_t sink_port_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
char *name;
struct perportentry *e;
+ pa_cvolume old_volume;
+ pa_bool_t mute_was_set = FALSE, volume_was_set = FALSE, old_mute;
pa_assert(c);
pa_assert(sink);
@@ -820,6 +822,12 @@ static pa_hook_result_t sink_port_hook_callback(pa_core *c, pa_sink *sink, struc
name = pa_sprintf_malloc("sink:%s", sink->name);
+ /* Hack 1: First pick up the old volumes, then make sure they are not lingering any more */
+ old_volume = *pa_sink_get_volume(sink, FALSE);
+ old_mute = pa_sink_get_mute(sink, FALSE);
+ pa_sink_get_volume(sink, TRUE);
+ pa_sink_get_mute(sink, TRUE);
+
if ((e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL)))) {
if (u->restore_volume && e->volume_valid) {
@@ -832,6 +840,7 @@ static pa_hook_result_t sink_port_hook_callback(pa_core *c, pa_sink *sink, struc
pa_cvolume_remap(&v, &e->channel_map, &sink->channel_map);
pa_sink_set_volume(sink, &v, TRUE, FALSE);
sink->save_volume = TRUE;
+ volume_was_set = TRUE;
}
if (u->restore_muted && e->muted_valid) {
@@ -839,6 +848,7 @@ static pa_hook_result_t sink_port_hook_callback(pa_core *c, pa_sink *sink, struc
pa_log_info("Restoring mute state for sink %s.", sink->name);
pa_sink_set_mute(sink, e->muted, FALSE);
sink->save_muted = TRUE;
+ mute_was_set = TRUE;
}
perportentry_free(e);
@@ -846,6 +856,12 @@ static pa_hook_result_t sink_port_hook_callback(pa_core *c, pa_sink *sink, struc
pa_xfree(name);
+ /* Hack 2: Work around volume not set correctly in core on port change */
+ if (!volume_was_set)
+ pa_sink_set_volume(sink, &old_volume, TRUE, FALSE);
+ if (!mute_was_set)
+ pa_sink_set_mute(sink, old_mute, FALSE);
+
return PA_HOOK_OK;
}
@@ -953,6 +969,8 @@ static pa_hook_result_t source_fixate_hook_callback(pa_core *c, pa_source_new_da
static pa_hook_result_t source_port_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
char *name;
struct perportentry *e;
+ pa_cvolume old_volume;
+ pa_bool_t mute_was_set = FALSE, volume_was_set = FALSE, old_mute;
pa_assert(c);
pa_assert(source);
@@ -961,6 +979,12 @@ static pa_hook_result_t source_port_hook_callback(pa_core *c, pa_source *source,
name = pa_sprintf_malloc("source:%s", source->name);
+ /* Hack 1: First pick up the old volumes, then make sure they are not lingering any more */
+ old_volume = *pa_source_get_volume(source, FALSE);
+ old_mute = pa_source_get_mute(source, FALSE);
+ pa_source_get_volume(source, TRUE);
+ pa_source_get_mute(source, TRUE);
+
if ((e = perportentry_read(u, name, (source->active_port ? source->active_port->name : NULL)))) {
if (u->restore_volume && e->volume_valid) {
@@ -973,6 +997,7 @@ static pa_hook_result_t source_port_hook_callback(pa_core *c, pa_source *source,
pa_cvolume_remap(&v, &e->channel_map, &source->channel_map);
pa_source_set_volume(source, &v, TRUE, FALSE);
source->save_volume = TRUE;
+ volume_was_set = TRUE;
}
if (u->restore_muted && e->muted_valid) {
@@ -980,6 +1005,7 @@ static pa_hook_result_t source_port_hook_callback(pa_core *c, pa_source *source,
pa_log_info("Restoring mute state for source %s.", source->name);
pa_source_set_mute(source, e->muted, FALSE);
source->save_muted = TRUE;
+ mute_was_set = TRUE;
}
perportentry_free(e);
@@ -987,6 +1013,12 @@ static pa_hook_result_t source_port_hook_callback(pa_core *c, pa_source *source,
pa_xfree(name);
+ /* Hack 2: Work around volume not set correctly in core on port change */
+ if (!volume_was_set)
+ pa_source_set_volume(source, &old_volume, TRUE, FALSE);
+ if (!mute_was_set)
+ pa_source_set_mute(source, old_mute, FALSE);
+
return PA_HOOK_OK;
}
--
1.7.5.4
More information about the pulseaudio-discuss
mailing list