From: Lennart Poettering Date: Fri, 5 Jun 2009 17:05:07 +0000 (+0200) Subject: core: add a suspend cause flags field X-Git-Tag: submit/2.0-panda/20130828.192557~1753 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=00797b8b6ea7978f862facb7181fb04895caf23c;p=profile%2Fivi%2Fpulseaudio-panda.git core: add a suspend cause flags field --- diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 59f5311..b1adc52 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -124,7 +124,7 @@ static pa_hook_result_t reserve_cb(pa_reserve_wrapper *r, void *forced, struct u pa_assert(r); pa_assert(u); - if (pa_sink_suspend(u->sink, TRUE) < 0) + if (pa_sink_suspend(u->sink, TRUE, PA_SUSPEND_APPLICATION) < 0) return PA_HOOK_CANCEL; return PA_HOOK_OK; diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index f1c1819..68f697d 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -122,7 +122,7 @@ static pa_hook_result_t reserve_cb(pa_reserve_wrapper *r, void *forced, struct u pa_assert(r); pa_assert(u); - if (pa_source_suspend(u->source, TRUE) < 0) + if (pa_source_suspend(u->source, TRUE, PA_SUSPEND_APPLICATION) < 0) return PA_HOOK_CANCEL; return PA_HOOK_OK; diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 02a7e1f..725faa0 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -593,7 +593,7 @@ static void unsuspend(struct userdata *u) { /* Let's resume */ for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { - pa_sink_suspend(o->sink, FALSE); + pa_sink_suspend(o->sink, FALSE, PA_SUSPEND_IDLE); if (PA_SINK_IS_OPENED(pa_sink_get_state(o->sink))) enable_output(o); @@ -873,7 +873,7 @@ static struct output *output_new(struct userdata *u, pa_sink *sink) { } if (PA_SINK_IS_OPENED(state) || state == PA_SINK_INIT) { - pa_sink_suspend(sink, FALSE); + pa_sink_suspend(sink, FALSE, PA_SUSPEND_IDLE); if (PA_SINK_IS_OPENED(pa_sink_get_state(sink))) if (output_create_sink_input(o) < 0) diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index b6139e4..9ac8705 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -567,7 +567,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo pa_sink *sink; if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK))) { - pa_bool_t success = pa_sink_suspend(sink, suspend) >= 0; + pa_bool_t success = pa_sink_suspend(sink, suspend, PA_SUSPEND_SESSION) >= 0; if (!success && !suspend) d->acl_race_fix = TRUE; /* resume failed, let's try again */ @@ -580,7 +580,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo pa_source *source; if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE))) { - pa_bool_t success = pa_source_suspend(source, suspend) >= 0; + pa_bool_t success = pa_source_suspend(source, suspend, PA_SUSPEND_SESSION) >= 0; if (!success && !suspend) d->acl_race_fix = TRUE; /* resume failed, let's try again */ @@ -593,7 +593,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo pa_card *card; if ((card = pa_namereg_get(u->core, d->card_name, PA_NAMEREG_CARD))) { - pa_bool_t success = pa_card_suspend(card, suspend) >= 0; + pa_bool_t success = pa_card_suspend(card, suspend, PA_SUSPEND_SESSION) >= 0; if (!success && !suspend) d->acl_race_fix = TRUE; /* resume failed, let's try again */ @@ -637,21 +637,21 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo pa_sink *sink; if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK))) - pa_sink_suspend(sink, FALSE); + pa_sink_suspend(sink, FALSE, PA_SUSPEND_SESSION); } if (d->source_name) { pa_source *source; if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE))) - pa_source_suspend(source, FALSE); + pa_source_suspend(source, FALSE, PA_SUSPEND_SESSION); } if (d->card_name) { pa_card *card; if ((card = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_CARD))) - pa_card_suspend(card, FALSE); + pa_card_suspend(card, FALSE, PA_SUSPEND_SESSION); } } diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c index cc69d74..c5b7891 100644 --- a/src/modules/module-suspend-on-idle.c +++ b/src/modules/module-suspend-on-idle.c @@ -86,14 +86,14 @@ static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval d->userdata->core->mainloop->time_restart(d->time_event, NULL); - if (d->sink && pa_sink_check_suspend(d->sink) <= 0 && pa_sink_get_state(d->sink) != PA_SINK_SUSPENDED) { + if (d->sink && pa_sink_check_suspend(d->sink) <= 0 && !(d->sink->suspend_cause & PA_SUSPEND_IDLE)) { pa_log_info("Sink %s idle for too long, suspending ...", d->sink->name); - pa_sink_suspend(d->sink, TRUE); + pa_sink_suspend(d->sink, TRUE, PA_SUSPEND_IDLE); } - if (d->source && pa_source_check_suspend(d->source) <= 0 && pa_source_get_state(d->source) != PA_SOURCE_SUSPENDED) { + if (d->source && pa_source_check_suspend(d->source) <= 0 && !(d->source->suspend_cause & PA_SUSPEND_IDLE)) { pa_log_info("Source %s idle for too long, suspending ...", d->source->name); - pa_source_suspend(d->source, TRUE); + pa_source_suspend(d->source, TRUE, PA_SUSPEND_IDLE); } } @@ -127,13 +127,13 @@ static void resume(struct device_info *d) { d->userdata->core->mainloop->time_restart(d->time_event, NULL); if (d->sink) { - pa_sink_suspend(d->sink, FALSE); + pa_sink_suspend(d->sink, FALSE, PA_SUSPEND_IDLE); pa_log_debug("Sink %s becomes busy.", d->sink->name); } if (d->source) { - pa_source_suspend(d->source, FALSE); + pa_source_suspend(d->source, FALSE, PA_SUSPEND_IDLE); pa_log_debug("Source %s becomes busy.", d->source->name); } diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c index 8101a92..59b8cda 100644 --- a/src/pulsecore/card.c +++ b/src/pulsecore/card.c @@ -244,19 +244,20 @@ int pa_card_set_profile(pa_card *c, const char *name, pa_bool_t save) { return 0; } -int pa_card_suspend(pa_card *c, pa_bool_t suspend) { +int pa_card_suspend(pa_card *c, pa_bool_t suspend, pa_suspend_cause_t cause) { pa_sink *sink; pa_source *source; uint32_t idx; int ret = 0; pa_assert(c); + pa_assert(cause != 0); for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) - ret -= pa_sink_suspend(sink, suspend) < 0; + ret -= pa_sink_suspend(sink, suspend, cause) < 0; for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) - ret -= pa_source_suspend(source, suspend) < 0; + ret -= pa_source_suspend(source, suspend, cause) < 0; return ret; } diff --git a/src/pulsecore/card.h b/src/pulsecore/card.h index 3b7608f..415ab67 100644 --- a/src/pulsecore/card.h +++ b/src/pulsecore/card.h @@ -99,6 +99,6 @@ void pa_card_free(pa_card *c); int pa_card_set_profile(pa_card *c, const char *name, pa_bool_t save); -int pa_card_suspend(pa_card *c, pa_bool_t suspend); +int pa_card_suspend(pa_card *c, pa_bool_t suspend, pa_suspend_cause_t cause); #endif diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index dad647a..644de96 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -1278,7 +1278,7 @@ static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *b return -1; } - if ((r = pa_sink_suspend(sink, suspend)) < 0) + if ((r = pa_sink_suspend(sink, suspend, PA_SUSPEND_USER)) < 0) pa_strbuf_printf(buf, "Failed to resume/suspend sink: %s\n", pa_strerror(r)); return 0; @@ -1314,7 +1314,7 @@ static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf return -1; } - if ((r = pa_source_suspend(source, suspend)) < 0) + if ((r = pa_source_suspend(source, suspend, PA_SUSPEND_USER)) < 0) pa_strbuf_printf(buf, "Failed to resume/suspend source: %s\n", pa_strerror(r)); return 0; @@ -1339,10 +1339,10 @@ static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, p return -1; } - if ((r = pa_sink_suspend_all(c, suspend)) < 0) + if ((r = pa_sink_suspend_all(c, suspend, PA_SUSPEND_USER)) < 0) pa_strbuf_printf(buf, "Failed to resume/suspend all sinks: %s\n", pa_strerror(r)); - if ((r = pa_source_suspend_all(c, suspend)) < 0) + if ((r = pa_source_suspend_all(c, suspend, PA_SUSPEND_USER)) < 0) pa_strbuf_printf(buf, "Failed to resume/suspend all sources: %s\n", pa_strerror(r)); return 0; diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c index 604678b..bc863f0 100644 --- a/src/pulsecore/cli-text.c +++ b/src/pulsecore/cli-text.c @@ -232,6 +232,7 @@ char *pa_sink_list_to_string(pa_core *c) { "\tdriver: <%s>\n" "\tflags: %s%s%s%s%s%s%s%s\n" "\tstate: %s\n" + "\tsuspend cause: %s%s%s%s\n" "\tvolume: %s%s%s\n" "\t balance %0.2f\n" "\tbase volume: %s%s%s\n" @@ -258,6 +259,10 @@ char *pa_sink_list_to_string(pa_core *c) { sink->flags & PA_SINK_FLAT_VOLUME ? "FLAT_VOLUME " : "", sink->flags & PA_SINK_DYNAMIC_LATENCY ? "DYNAMIC_LATENCY" : "", sink_state_to_string(pa_sink_get_state(sink)), + sink->suspend_cause & PA_SUSPEND_USER ? "USER " : "", + sink->suspend_cause & PA_SUSPEND_APPLICATION ? "APPLICATION " : "", + sink->suspend_cause & PA_SUSPEND_IDLE ? "IDLE " : "", + sink->suspend_cause & PA_SUSPEND_SESSION ? "SESSION" : "", pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink, FALSE, FALSE)), sink->flags & PA_SINK_DECIBEL_VOLUME ? "\n\t " : "", sink->flags & PA_SINK_DECIBEL_VOLUME ? pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), pa_sink_get_volume(sink, FALSE, FALSE)) : "", @@ -335,6 +340,7 @@ char *pa_source_list_to_string(pa_core *c) { "\tdriver: <%s>\n" "\tflags: %s%s%s%s%s%s%s\n" "\tstate: %s\n" + "\tsuspend cause: %s%s%s%s\n" "\tvolume: %s%s%s\n" "\t balance %0.2f\n" "\tbase volume: %s%s%s\n" @@ -358,6 +364,10 @@ char *pa_source_list_to_string(pa_core *c) { source->flags & PA_SOURCE_LATENCY ? "LATENCY " : "", source->flags & PA_SOURCE_DYNAMIC_LATENCY ? "DYNAMIC_LATENCY" : "", source_state_to_string(pa_source_get_state(source)), + source->suspend_cause & PA_SUSPEND_USER ? "USER " : "", + source->suspend_cause & PA_SUSPEND_APPLICATION ? "APPLICATION " : "", + source->suspend_cause & PA_SUSPEND_IDLE ? "IDLE " : "", + source->suspend_cause & PA_SUSPEND_SESSION ? "SESSION" : "", pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source, FALSE)), source->flags & PA_SOURCE_DECIBEL_VOLUME ? "\n\t " : "", source->flags & PA_SOURCE_DECIBEL_VOLUME ? pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), pa_source_get_volume(source, FALSE)) : "", diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index c679444..09a880c 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -27,6 +27,16 @@ typedef struct pa_core pa_core; +/* This is a bitmask that encodes the cause why a sink/source is + * suspended. */ +typedef enum pa_suspend_cause { + PA_SUSPEND_USER = 1, /* Exposed to the user via some protocol */ + PA_SUSPEND_APPLICATION = 2, /* Used by the device reservation logic */ + PA_SUSPEND_IDLE = 4, /* Used by module-suspend-on-idle */ + PA_SUSPEND_SESSION = 8, /* Used by module-hal for mark inactive sessions */ + PA_SUSPEND_ALL = 0xFFFF /* Magic cause that can be used to resume forcibly */ +} pa_suspend_cause_t; + #include #include #include diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index 7e7126e..ad7cd04 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -947,10 +947,10 @@ static int esd_proto_standby_or_resume(connection *c, esd_proto_t request, const connection_write(c, &ok, sizeof(int32_t)); if (request == ESD_PROTO_STANDBY) - ok = pa_sink_suspend_all(c->protocol->core, TRUE) >= 0; + ok = pa_sink_suspend_all(c->protocol->core, TRUE, PA_SUSPEND_USER) >= 0; else { pa_assert(request == ESD_PROTO_RESUME); - ok = pa_sink_suspend_all(c->protocol->core, FALSE) >= 0; + ok = pa_sink_suspend_all(c->protocol->core, FALSE, PA_SUSPEND_USER) >= 0; } connection_write(c, &ok, sizeof(int32_t)); diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index d4a9952..e9e2d60 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -4098,7 +4098,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa pa_log_debug("%s all sinks", b ? "Suspending" : "Resuming"); - if (pa_sink_suspend_all(c->protocol->core, b) < 0) { + if (pa_sink_suspend_all(c->protocol->core, b, PA_SUSPEND_USER) < 0) { pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID); return; } @@ -4112,7 +4112,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY); - if (pa_sink_suspend(sink, b) < 0) { + if (pa_sink_suspend(sink, b, PA_SUSPEND_USER) < 0) { pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID); return; } @@ -4125,7 +4125,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa pa_log_debug("%s all sources", b ? "Suspending" : "Resuming"); - if (pa_source_suspend_all(c->protocol->core, b) < 0) { + if (pa_source_suspend_all(c->protocol->core, b, PA_SUSPEND_USER) < 0) { pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID); return; } @@ -4140,7 +4140,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa CHECK_VALIDITY(c->pstream, source, tag, PA_ERR_NOENTITY); - if (pa_source_suspend(source, b) < 0) { + if (pa_source_suspend(source, b, PA_SUSPEND_USER) < 0) { pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID); return; } diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 28b3440..3c4adc6 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -190,6 +190,7 @@ pa_sink* pa_sink_new( s->core = core; s->state = PA_SINK_INIT; s->flags = flags; + s->suspend_cause = 0; s->name = pa_xstrdup(name); s->proplist = pa_proplist_copy(data->proplist); s->driver = pa_xstrdup(pa_path_get_filename(data->driver)); @@ -499,11 +500,19 @@ int pa_sink_update_status(pa_sink*s) { } /* Called from main context */ -int pa_sink_suspend(pa_sink *s, pa_bool_t suspend) { +int pa_sink_suspend(pa_sink *s, pa_bool_t suspend, pa_suspend_cause_t cause) { pa_sink_assert_ref(s); pa_assert(PA_SINK_IS_LINKED(s->state)); + pa_assert(cause != 0); if (suspend) + s->suspend_cause |= cause; + else + s->suspend_cause &= ~cause; + + pa_log_debug("Suspend cause of sink %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming"); + + if (s->suspend_cause) return sink_set_state(s, PA_SINK_SUSPENDED); else return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE); @@ -1823,17 +1832,18 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse } /* Called from main thread */ -int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend) { +int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause) { pa_sink *sink; uint32_t idx; int ret = 0; pa_core_assert_ref(c); + pa_assert(cause != 0); for (sink = PA_SINK(pa_idxset_first(c->sinks, &idx)); sink; sink = PA_SINK(pa_idxset_next(c->sinks, &idx))) { int r; - if ((r = pa_sink_suspend(sink, suspend)) < 0) + if ((r = pa_sink_suspend(sink, suspend, cause)) < 0) ret = r; } diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index e33b3cf..4dce3f9 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -56,6 +56,7 @@ struct pa_sink { pa_core *core; pa_sink_state_t state; pa_sink_flags_t flags; + pa_suspend_cause_t suspend_cause; char *name; char *driver; /* may be NULL */ @@ -252,8 +253,8 @@ size_t pa_sink_get_max_rewind(pa_sink *s); size_t pa_sink_get_max_request(pa_sink *s); int pa_sink_update_status(pa_sink*s); -int pa_sink_suspend(pa_sink *s, pa_bool_t suspend); -int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend); +int pa_sink_suspend(pa_sink *s, pa_bool_t suspend, pa_suspend_cause_t cause); +int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause); void pa_sink_update_flat_volume(pa_sink *s, pa_cvolume *new_volume); void pa_sink_propagate_flat_volume(pa_sink *s); diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 8aeb560..4ade18f 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -180,6 +180,7 @@ pa_source* pa_source_new( s->core = core; s->state = PA_SOURCE_INIT; s->flags = flags; + s->suspend_cause = 0; s->name = pa_xstrdup(name); s->proplist = pa_proplist_copy(data->proplist); s->driver = pa_xstrdup(pa_path_get_filename(data->driver)); @@ -427,14 +428,22 @@ int pa_source_update_status(pa_source*s) { } /* Called from main context */ -int pa_source_suspend(pa_source *s, pa_bool_t suspend) { +int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause) { pa_source_assert_ref(s); pa_assert(PA_SOURCE_IS_LINKED(s->state)); + pa_assert(cause != 0); if (s->monitor_of) return -PA_ERR_NOTSUPPORTED; if (suspend) + s->suspend_cause |= cause; + else + s->suspend_cause &= ~cause; + + pa_log_debug("Suspend cause of source %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming"); + + if (suspend) return source_set_state(s, PA_SOURCE_SUSPENDED); else return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE); @@ -1032,12 +1041,13 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_ } /* Called from main thread */ -int pa_source_suspend_all(pa_core *c, pa_bool_t suspend) { +int pa_source_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause) { uint32_t idx; pa_source *source; int ret = 0; pa_core_assert_ref(c); + pa_assert(cause != 0); for (source = PA_SOURCE(pa_idxset_first(c->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(c->sources, &idx))) { int r; @@ -1045,7 +1055,7 @@ int pa_source_suspend_all(pa_core *c, pa_bool_t suspend) { if (source->monitor_of) continue; - if ((r = pa_source_suspend(source, suspend)) < 0) + if ((r = pa_source_suspend(source, suspend, cause)) < 0) ret = r; } diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index 2978f57..1fbed70 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -58,6 +58,7 @@ struct pa_source { pa_core *core; pa_source_state_t state; pa_source_flags_t flags; + pa_suspend_cause_t suspend_cause; char *name; char *driver; /* may be NULL */ @@ -231,8 +232,8 @@ void pa_source_get_latency_range(pa_source *s, pa_usec_t *min_latency, pa_usec_t size_t pa_source_get_max_rewind(pa_source *s); int pa_source_update_status(pa_source*s); -int pa_source_suspend(pa_source *s, pa_bool_t suspend); -int pa_source_suspend_all(pa_core *c, pa_bool_t suspend); +int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause); +int pa_source_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause); void pa_source_set_volume(pa_source *source, const pa_cvolume *volume); const pa_cvolume *pa_source_get_volume(pa_source *source, pa_bool_t force_refresh);