[pulseaudio-discuss] [PATCH v2 2/5] When switching ports, use the port default volume
David Henningsson
david.henningsson at canonical.com
Mon Apr 20 02:21:54 PDT 2015
On 2015-04-17 22:26, Tanu Kaskinen wrote:
> 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.
Now that pa_device_port has a default volume, then module-device-restore
should just set it for all ports at the card_new + PA_HOOK_EARLY
callback. There is no need for module-device-restore to do anything at
port_changed anymore; and thus no need to add the
pa_*_port_changed_hook_data struct either, unless I'm missing something.
There's also the point that now volume and mute are handled differently,
which I'm not really happy with.
> ---
> src/modules/dbus/iface-device.c | 4 ++--
> src/modules/module-device-restore.c | 32 ++++++++++++++------------------
> src/pulsecore/sink.c | 8 +++++++-
> src/pulsecore/sink.h | 10 ++++++++++
> src/pulsecore/source.c | 8 +++++++-
> src/pulsecore/source.h | 10 ++++++++++
> 6 files changed, 50 insertions(+), 22 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..ced2a14 100644
> --- a/src/modules/module-device-restore.c
> +++ b/src/modules/module-device-restore.c
> @@ -798,28 +798,26 @@ 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) {
> @@ -940,28 +938,26 @@ 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) {
> diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
> index 3776a5a..652401d 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,12 @@ 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.save_volume = 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);
>
> return 0;
> }
> diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
> index cb32782..4150c5a3 100644
> --- a/src/pulsecore/sink.h
> +++ b/src/pulsecore/sink.h
> @@ -337,6 +337,16 @@ typedef enum pa_sink_message {
> PA_SINK_MESSAGE_MAX
> } pa_sink_message_t;
>
> +typedef struct {
> + pa_sink *sink;
> +
> + /* This will be the new volume for the sink. If the hook callback wants to
> + * set the sink volume, it should do that by setting these variables
> + * instead of calling pa_sink_set_volume(). */
> + pa_cvolume volume;
> + bool save_volume;
> +} 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..17dd9a1 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,12 @@ 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.save_volume = 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);
>
> return 0;
> }
> diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
> index 7555a9f..b6e9d0e 100644
> --- a/src/pulsecore/source.h
> +++ b/src/pulsecore/source.h
> @@ -274,6 +274,16 @@ typedef enum pa_source_message {
> PA_SOURCE_MESSAGE_MAX
> } pa_source_message_t;
>
> +typedef struct {
> + pa_source *source;
> +
> + /* This will be the new volume for the source. If the hook callback wants
> + * to set the source volume, it should do that by setting these variables
> + * instead of calling pa_source_set_volume(). */
> + pa_cvolume volume;
> + bool save_volume;
> +} pa_source_port_changed_hook_data;
> +
> typedef struct pa_source_new_data {
> pa_suspend_cause_t suspend_cause;
>
>
--
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic
More information about the pulseaudio-discuss
mailing list