[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