From e8df86807ef247f01269cc63149faf9974fbb189 Mon Sep 17 00:00:00 2001 From: Colin Guthrie Date: Sun, 7 Aug 2011 01:08:28 +0200 Subject: [PATCH] stream-restore: Save/restore source output volume/mute --- src/modules/module-stream-restore.c | 92 ++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c index 19c09bb6..7bb30934 100644 --- a/src/modules/module-stream-restore.c +++ b/src/modules/module-stream-restore.c @@ -90,6 +90,7 @@ struct userdata { *sink_input_new_hook_slot, *sink_input_fixate_hook_slot, *source_output_new_hook_slot, + *source_output_fixate_hook_slot, *sink_put_hook_slot, *source_put_hook_slot, *sink_unlink_hook_slot, @@ -1322,6 +1323,26 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 } else entry = entry_new(); + if (source_output->save_volume && pa_source_output_is_volume_readable(source_output)) { + pa_assert(source_output->volume_writable); + + entry->channel_map = source_output->channel_map; + pa_source_output_get_volume(source_output, &entry->volume, FALSE); + entry->volume_valid = TRUE; + + volume_updated = !created_new_entry + && (!old->volume_valid + || !pa_channel_map_equal(&entry->channel_map, &old->channel_map) + || !pa_cvolume_equal(&entry->volume, &old->volume)); + } + + if (source_output->save_muted) { + entry->muted = pa_source_output_get_mute(source_output); + entry->muted_valid = TRUE; + + mute_updated = !created_new_entry && (!old->muted_valid || entry->muted != old->muted); + } + if (source_output->save_source) { pa_xfree(entry->device); entry->device = pa_xstrdup(source_output->source->name); @@ -1516,6 +1537,57 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou return PA_HOOK_OK; } +static pa_hook_result_t source_output_fixate_hook_callback(pa_core *c, pa_source_output_new_data *new_data, struct userdata *u) { + char *name; + struct entry *e; + + pa_assert(c); + pa_assert(new_data); + pa_assert(u); + pa_assert(u->restore_volume || u->restore_muted); + + if (!(name = get_name(new_data->proplist, "source-output"))) + return PA_HOOK_OK; + + if ((e = entry_read(u, name))) { + + if (u->restore_volume && e->volume_valid) { + if (!new_data->volume_writable) + pa_log_debug("Not restoring volume for source output %s, because its volume can't be changed.", name); + else if (new_data->volume_is_set) + pa_log_debug("Not restoring volume for source output %s, because already set.", name); + else { + pa_cvolume v; + + pa_log_info("Restoring volume for source output %s.", name); + + v = e->volume; + pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map); + pa_source_output_new_data_set_volume(new_data, &v); + + new_data->volume_is_absolute = FALSE; + new_data->save_volume = TRUE; + } + } + + if (u->restore_muted && e->muted_valid) { + + if (!new_data->muted_is_set) { + pa_log_info("Restoring mute state for source output %s.", name); + pa_source_output_new_data_set_muted(new_data, e->muted); + new_data->save_muted = TRUE; + } else + pa_log_debug("Not restoring mute state for source output %s, because already set.", name); + } + + entry_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) { pa_sink_input *si; uint32_t idx; @@ -1771,6 +1843,20 @@ static void entry_apply(struct userdata *u, const char *name, struct entry *e) { } pa_xfree(n); + if (u->restore_volume && e->volume_valid && so->volume_writable) { + pa_cvolume v; + + v = e->volume; + pa_log_info("Restoring volume for source output %s.", name); + pa_cvolume_remap(&v, &e->channel_map, &so->channel_map); + pa_source_output_set_volume(so, &v, TRUE, FALSE); + } + + if (u->restore_muted && e->muted_valid) { + pa_log_info("Restoring mute state for source output %s.", name); + pa_source_output_set_mute(so, e->muted, TRUE); + } + if (u->restore_device) { if (!e->device_valid) { if (so->save_source) { @@ -2148,8 +2234,10 @@ int pa__init(pa_module*m) { u->source_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) source_unlink_hook_callback, u); } - if (restore_volume || restore_muted) + if (restore_volume || restore_muted) { u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_fixate_hook_callback, u); + u->source_output_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_fixate_hook_callback, u); + } if (!(fname = pa_state_path("stream-volumes", TRUE))) goto fail; @@ -2254,6 +2342,8 @@ void pa__done(pa_module*m) { pa_hook_slot_free(u->sink_input_fixate_hook_slot); if (u->source_output_new_hook_slot) pa_hook_slot_free(u->source_output_new_hook_slot); + if (u->source_output_fixate_hook_slot) + pa_hook_slot_free(u->source_output_fixate_hook_slot); if (u->sink_put_hook_slot) pa_hook_slot_free(u->sink_put_hook_slot); -- 2.39.2