[pulseaudio-discuss] [PATCH v3 2/6] When switching ports, use the port default volume
Tanu Kaskinen
tanu.kaskinen at linux.intel.com
Mon Apr 27 04:34:02 PDT 2015
If two ports have different default volumes, and module-device-restore
doesn't have an opinion on the port volume, we should change the
sink/source volume to the new port's default volume when switching
ports, instead of keeping the volume at whatever it happened to be
when the old port was active.
This introduces pa_sink/source_port_changed_hook_data, because I
wanted to call pa_sink/source_set_volume() only once in
pa_sink/source_set_port(), instead of calling it also in
module-device-restore's hook callback. The extended hook data allows
module-device-restore to communicate to the core that the volume
should be set to a non-default value. Mute handling is changed too to
match the new way volume is handled.
---
src/modules/dbus/iface-device.c | 4 ++--
src/modules/module-device-restore.c | 42 ++++++++++++++++---------------------
src/pulsecore/sink.c | 11 +++++++++-
src/pulsecore/sink.h | 12 +++++++++++
src/pulsecore/source.c | 11 +++++++++-
src/pulsecore/source.h | 12 +++++++++++
6 files changed, 64 insertions(+), 28 deletions(-)
diff --git a/src/modules/dbus/iface-device.c b/src/modules/dbus/iface-device.c
index 2c370a8..911890d 100644
--- a/src/modules/dbus/iface-device.c
+++ b/src/modules/dbus/iface-device.c
@@ -1190,8 +1190,8 @@ static pa_hook_result_t port_changed_cb(void *hook_data, void *call_data, void *
DBusMessage *signal_msg = NULL;
pa_device_port *new_active_port = NULL;
- if ((d->type == PA_DEVICE_TYPE_SINK && d->sink != call_data) ||
- (d->type == PA_DEVICE_TYPE_SOURCE && d->source != call_data))
+ if ((d->type == PA_DEVICE_TYPE_SINK && d->sink != ((pa_sink_port_changed_hook_data *) call_data)->sink) ||
+ (d->type == PA_DEVICE_TYPE_SOURCE && d->source != ((pa_source_port_changed_hook_data *) call_data)->source))
return PA_HOOK_OK;
new_active_port = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->active_port : d->source->active_port;
diff --git a/src/modules/module-device-restore.c b/src/modules/module-device-restore.c
index 8d7b34b..a24f804 100644
--- a/src/modules/module-device-restore.c
+++ b/src/modules/module-device-restore.c
@@ -798,35 +798,32 @@ static pa_hook_result_t sink_fixate_hook_callback(pa_core *c, pa_sink_new_data *
return PA_HOOK_OK;
}
-static pa_hook_result_t sink_port_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
+static pa_hook_result_t sink_port_hook_callback(pa_core *c, pa_sink_port_changed_hook_data *data, struct userdata *u) {
+ pa_sink *sink;
char *name;
struct perportentry *e;
pa_assert(c);
- pa_assert(sink);
+ pa_assert(data);
pa_assert(u);
pa_assert(u->restore_volume || u->restore_muted);
+ sink = data->sink;
name = pa_sprintf_malloc("sink:%s", sink->name);
if ((e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL)))) {
if (u->restore_volume && e->volume_valid) {
- pa_cvolume v;
-
pa_log_info("Restoring volume for sink %s.", sink->name);
- v = e->volume;
- pa_cvolume_remap(&v, &e->channel_map, &sink->channel_map);
- pa_sink_set_volume(sink, &v, true, false);
-
- sink->save_volume = true;
+ data->volume = e->volume;
+ pa_cvolume_remap(&data->volume, &e->channel_map, &sink->channel_map);
+ data->save_volume = true;
}
if (u->restore_muted && e->muted_valid) {
-
pa_log_info("Restoring mute state for sink %s.", sink->name);
- pa_sink_set_mute(sink, e->muted, false);
- sink->save_muted = true;
+ data->mute = e->muted;
+ data->save_mute = true;
}
perportentry_free(e);
@@ -940,35 +937,32 @@ static pa_hook_result_t source_fixate_hook_callback(pa_core *c, pa_source_new_da
return PA_HOOK_OK;
}
-static pa_hook_result_t source_port_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
+static pa_hook_result_t source_port_hook_callback(pa_core *c, pa_source_port_changed_hook_data *data, struct userdata *u) {
+ pa_source *source;
char *name;
struct perportentry *e;
pa_assert(c);
- pa_assert(source);
+ pa_assert(data);
pa_assert(u);
pa_assert(u->restore_volume || u->restore_muted);
+ source = data->source;
name = pa_sprintf_malloc("source:%s", source->name);
if ((e = perportentry_read(u, name, (source->active_port ? source->active_port->name : NULL)))) {
if (u->restore_volume && e->volume_valid) {
- pa_cvolume v;
-
pa_log_info("Restoring volume for source %s.", source->name);
- v = e->volume;
- pa_cvolume_remap(&v, &e->channel_map, &source->channel_map);
- pa_source_set_volume(source, &v, true, false);
-
- source->save_volume = true;
+ data->volume = e->volume;
+ pa_cvolume_remap(&data->volume, &e->channel_map, &source->channel_map);
+ data->save_volume = true;
}
if (u->restore_muted && e->muted_valid) {
-
pa_log_info("Restoring mute state for source %s.", source->name);
- pa_source_set_mute(source, e->muted, false);
- source->save_muted = true;
+ data->mute = e->muted;
+ data->save_mute = true;
}
perportentry_free(e);
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 3776a5a..6962e3d 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -3310,6 +3310,7 @@ size_t pa_sink_get_max_request(pa_sink *s) {
int pa_sink_set_port(pa_sink *s, const char *name, bool save) {
pa_device_port *port;
int ret;
+ pa_sink_port_changed_hook_data hook_data;
pa_sink_assert_ref(s);
pa_assert_ctl_context();
@@ -3350,7 +3351,15 @@ int pa_sink_set_port(pa_sink *s, const char *name, bool save) {
pa_sink_set_latency_offset(s, s->active_port->latency_offset);
- pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], s);
+ hook_data.sink = s;
+ pa_cvolume_set(&hook_data.volume, s->sample_spec.channels, port->default_volume);
+ hook_data.mute = false;
+ hook_data.save_volume = false;
+ hook_data.save_mute = false;
+ pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], &hook_data);
+
+ pa_sink_set_volume(s, &hook_data.volume, true, hook_data.save_volume);
+ pa_sink_set_mute(s, hook_data.mute, hook_data.save_mute);
return 0;
}
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index cb32782..9de0fac 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -337,6 +337,18 @@ typedef enum pa_sink_message {
PA_SINK_MESSAGE_MAX
} pa_sink_message_t;
+typedef struct {
+ pa_sink *sink;
+
+ /* If the hook callback wants to set the sink volume or mute, it should do
+ * do that by setting these variables instead of calling
+ * pa_sink_set_volume/mute(). */
+ pa_cvolume volume;
+ bool mute;
+ bool save_volume;
+ bool save_mute;
+} pa_sink_port_changed_hook_data;
+
typedef struct pa_sink_new_data {
pa_suspend_cause_t suspend_cause;
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index b06e7fa..a93f2a4 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -2589,6 +2589,7 @@ size_t pa_source_get_max_rewind(pa_source *s) {
int pa_source_set_port(pa_source *s, const char *name, bool save) {
pa_device_port *port;
int ret;
+ pa_source_port_changed_hook_data hook_data;
pa_source_assert_ref(s);
pa_assert_ctl_context();
@@ -2627,7 +2628,15 @@ int pa_source_set_port(pa_source *s, const char *name, bool save) {
s->active_port = port;
s->save_port = save;
- pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PORT_CHANGED], s);
+ hook_data.source = s;
+ pa_cvolume_set(&hook_data.volume, s->sample_spec.channels, port->default_volume);
+ hook_data.mute = false;
+ hook_data.save_volume = false;
+ hook_data.save_mute = false;
+ pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PORT_CHANGED], &hook_data);
+
+ pa_source_set_volume(s, &hook_data.volume, true, hook_data.save_volume);
+ pa_source_set_mute(s, hook_data.mute, hook_data.save_mute);
return 0;
}
diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
index 7555a9f..e9977c9 100644
--- a/src/pulsecore/source.h
+++ b/src/pulsecore/source.h
@@ -274,6 +274,18 @@ typedef enum pa_source_message {
PA_SOURCE_MESSAGE_MAX
} pa_source_message_t;
+typedef struct {
+ pa_source *source;
+
+ /* If the hook callback wants to set the source volume or mute, it should
+ * do that by setting these variables instead of calling
+ * pa_source_set_volume/mute(). */
+ pa_cvolume volume;
+ bool mute;
+ bool save_volume;
+ bool save_mute;
+} pa_source_port_changed_hook_data;
+
typedef struct pa_source_new_data {
pa_suspend_cause_t suspend_cause;
--
1.9.3
More information about the pulseaudio-discuss
mailing list