mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
device-restore: Restore volumes on port change.
This will allow for volumes to be saved separately for e.g. Headphones vs. Speakers. At present it is possible that no volume will be saved for the device prior to the port switch. In this case the volume will not change from the value set under the other port. In an ideal world we would save the volume before switching port, but that would require a new hook.
This commit is contained in:
parent
1ee97e57ca
commit
a13a402ed3
1 changed files with 89 additions and 0 deletions
|
|
@ -83,9 +83,11 @@ struct userdata {
|
|||
pa_hook_slot
|
||||
*sink_new_hook_slot,
|
||||
*sink_fixate_hook_slot,
|
||||
*sink_port_hook_slot,
|
||||
*sink_put_hook_slot,
|
||||
*source_new_hook_slot,
|
||||
*source_fixate_hook_slot,
|
||||
*source_port_hook_slot,
|
||||
*connection_unlink_hook_slot;
|
||||
pa_time_event *save_time_event;
|
||||
pa_database *database;
|
||||
|
|
@ -804,6 +806,46 @@ 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) {
|
||||
char *name;
|
||||
struct perportentry *e;
|
||||
|
||||
pa_assert(c);
|
||||
pa_assert(sink);
|
||||
pa_assert(u);
|
||||
pa_assert(u->restore_volume || u->restore_muted);
|
||||
|
||||
name = pa_sprintf_malloc("sink:%s:%s", sink->name, (sink->active_port ? sink->active_port->name : "null"));
|
||||
|
||||
if ((e = perportentry_read(u, name))) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
perportentry_free(e);
|
||||
}
|
||||
|
||||
pa_xfree(name);
|
||||
|
||||
return PA_HOOK_OK;
|
||||
}
|
||||
|
||||
static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
|
||||
char *name;
|
||||
struct perportentry *e;
|
||||
|
|
@ -905,6 +947,46 @@ 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) {
|
||||
char *name;
|
||||
struct perportentry *e;
|
||||
|
||||
pa_assert(c);
|
||||
pa_assert(source);
|
||||
pa_assert(u);
|
||||
pa_assert(u->restore_volume || u->restore_muted);
|
||||
|
||||
name = pa_sprintf_malloc("source:%s:%s", source->name, (source->active_port ? source->active_port->name : "null"));
|
||||
|
||||
if ((e = perportentry_read(u, name))) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
perportentry_free(e);
|
||||
}
|
||||
|
||||
pa_xfree(name);
|
||||
|
||||
return PA_HOOK_OK;
|
||||
}
|
||||
|
||||
#define EXT_VERSION 1
|
||||
|
||||
static void read_sink_format_reply(struct userdata *u, pa_tagstruct *reply, pa_sink *sink) {
|
||||
|
|
@ -1170,6 +1252,9 @@ int pa__init(pa_module*m) {
|
|||
if (restore_muted || restore_volume) {
|
||||
u->sink_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) sink_fixate_hook_callback, u);
|
||||
u->source_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) source_fixate_hook_callback, u);
|
||||
|
||||
u->sink_port_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) sink_port_hook_callback, u);
|
||||
u->source_port_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_PORT_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) source_port_hook_callback, u);
|
||||
}
|
||||
|
||||
if (restore_formats)
|
||||
|
|
@ -1224,6 +1309,10 @@ void pa__done(pa_module*m) {
|
|||
pa_hook_slot_free(u->sink_new_hook_slot);
|
||||
if (u->source_new_hook_slot)
|
||||
pa_hook_slot_free(u->source_new_hook_slot);
|
||||
if (u->sink_port_hook_slot)
|
||||
pa_hook_slot_free(u->sink_port_hook_slot);
|
||||
if (u->source_port_hook_slot)
|
||||
pa_hook_slot_free(u->source_port_hook_slot);
|
||||
if (u->sink_put_hook_slot)
|
||||
pa_hook_slot_free(u->sink_put_hook_slot);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue