From: Arun Raghavan <git@xxxxxxxxxxxxxxxx> --- src/map-file | 1 + src/pulse/internal.h | 2 ++ src/pulse/stream.c | 22 ++++++++++++++++++++++ src/pulse/stream.h | 4 ++++ src/tests/api-test.c | 14 +++++++++++--- 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/map-file b/src/map-file index 8e61f53..afce508 100644 --- a/src/map-file +++ b/src/map-file @@ -328,6 +328,7 @@ pa_stream_set_state_callback; pa_stream_set_suspended_callback; pa_stream_set_underflow_callback; pa_stream_set_volume; +pa_stream_set_volume_changed_callback; pa_stream_set_write_callback; pa_stream_trigger; pa_stream_unref; diff --git a/src/pulse/internal.h b/src/pulse/internal.h index ac9d07e..a75ffbf 100644 --- a/src/pulse/internal.h +++ b/src/pulse/internal.h @@ -223,6 +223,8 @@ struct pa_stream { void *event_userdata; pa_stream_notify_cb_t buffer_attr_callback; void *buffer_attr_userdata; + pa_stream_notify_cb_t volume_changed_callback; + void *volume_changed_userdata; }; typedef void (*pa_operation_cb_t)(void); diff --git a/src/pulse/stream.c b/src/pulse/stream.c index bc49cbb..d9ca039 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -78,6 +78,8 @@ static void reset_callbacks(pa_stream *s) { s->event_userdata = NULL; s->buffer_attr_callback = NULL; s->buffer_attr_userdata = NULL; + s->volume_changed_callback = NULL; + s->volume_changed_userdata = NULL; } static pa_stream *pa_stream_new_with_proplist_internal( @@ -946,6 +948,9 @@ void pa_command_stream_volume_changed(pa_pdispatch *pd, uint32_t command, uint32 s->volume = volume; + if (s->volume_changed_callback) + s->volume_changed_callback(s, s->volume_changed_userdata); + finish: pa_context_unref(c); } @@ -3023,3 +3028,20 @@ int pa_stream_get_volume(pa_stream *s, pa_cvolume *v) { return 0; } + +void pa_stream_set_volume_changed_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata) { + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + + if (s->context->version < 31) + return; + + if (pa_detect_fork()) + return; + + if (s->state == PA_STREAM_TERMINATED || s->state == PA_STREAM_FAILED) + return; + + s->volume_changed_callback = cb; + s->volume_changed_userdata = userdata; +} diff --git a/src/pulse/stream.h b/src/pulse/stream.h index b4e6ff9..c9fdec7 100644 --- a/src/pulse/stream.h +++ b/src/pulse/stream.h @@ -835,6 +835,10 @@ int pa_stream_set_volume(pa_stream *s, pa_cvolume *v, pa_stream_success_cb_t cb, * \since 9.0 */ int pa_stream_get_volume(pa_stream *s, pa_cvolume *v); +/** Set the callback function that is called whenever the volume of the stream + * changes. \since 9.0 */ +void pa_stream_set_volume_changed_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata); + PA_C_DECL_END #endif diff --git a/src/tests/api-test.c b/src/tests/api-test.c index e7ae3df..c88d00b 100644 --- a/src/tests/api-test.c +++ b/src/tests/api-test.c @@ -32,7 +32,14 @@ #define CHANNELS 2 -static void stream_volume_callback(pa_stream *s, int success, void *userdata) { +static void volume_changed_callback(pa_stream *s, void *userdata) { + pa_cvolume v; + + fail_unless(pa_stream_get_volume(s, &v) == 0); + fail_unless(pa_cvolume_avg(&v) == (PA_VOLUME_NORM / 3)); +} + +static void set_stream_volume_callback(pa_stream *s, int success, void *userdata) { pa_cvolume v; bool disconnect = PA_PTR_TO_UINT(userdata); @@ -67,7 +74,8 @@ static void stream_state_callback(pa_stream *s, void *userdata) { fail_unless(pa_cvolume_avg(&v) == (PA_VOLUME_NORM / 2)); pa_cvolume_set(&v, CHANNELS, PA_VOLUME_NORM / 3); - fail_unless(pa_stream_set_volume(s, &v, stream_volume_callback, PA_UINT_TO_PTR(true)) == 0); + pa_stream_set_volume_changed_callback(s, volume_changed_callback, NULL); + fail_unless(pa_stream_set_volume(s, &v, set_stream_volume_callback, PA_UINT_TO_PTR(true)) == 0); break; default: @@ -100,7 +108,7 @@ static void context_state_callback(pa_context *c, void *userdata) { fail_unless(s != NULL); pa_cvolume_set(&v, CHANNELS, PA_VOLUME_NORM / 2); - fail_unless(pa_stream_set_volume(s, &v, stream_volume_callback, PA_UINT_TO_PTR(false)) == 0); + fail_unless(pa_stream_set_volume(s, &v, set_stream_volume_callback, PA_UINT_TO_PTR(false)) == 0); pa_stream_set_state_callback(s, stream_state_callback, NULL); if (playback) -- 2.5.0