From af916565fd99e2577b050fe6515ad78e5cd5a8b5 Mon Sep 17 00:00:00 2001 From: Matthew Gregan Date: Tue, 9 Nov 2021 12:49:38 +1300 Subject: [PATCH] WIP: Add cubeb_stream_get_max_request_size API. This is intended to support https://github.com/mozilla/audioipc-2/issues/124 --- include/cubeb/cubeb.h | 15 +++++++++++++++ src/cubeb-internal.h | 2 ++ src/cubeb.c | 16 ++++++++++++++++ src/cubeb_aaudio.cpp | 1 + src/cubeb_alsa.c | 1 + src/cubeb_audiounit.cpp | 1 + src/cubeb_jack.cpp | 1 + src/cubeb_kai.c | 1 + src/cubeb_opensl.c | 1 + src/cubeb_oss.c | 1 + src/cubeb_pulse.c | 1 + src/cubeb_sndio.c | 1 + src/cubeb_sun.c | 1 + src/cubeb_wasapi.cpp | 18 ++++++++++++++++++ src/cubeb_winmm.c | 1 + 15 files changed, 62 insertions(+) diff --git a/include/cubeb/cubeb.h b/include/cubeb/cubeb.h index f653f5b7..02539b9f 100644 --- a/include/cubeb/cubeb.h +++ b/include/cubeb/cubeb.h @@ -607,6 +607,7 @@ cubeb_stream_get_latency(cubeb_stream * stream, uint32_t * latency); @retval CUBEB_ERROR */ CUBEB_EXPORT int cubeb_stream_get_input_latency(cubeb_stream * stream, uint32_t * latency); + /** Set the volume for a stream. @param stream the stream for which to adjust the volume. @param volume a float between 0.0 (muted) and 1.0 (maximum volume) @@ -637,6 +638,20 @@ CUBEB_EXPORT int cubeb_stream_get_current_device(cubeb_stream * stm, cubeb_device ** const device); +/** Get the maximum request size for this stream in frames. This is the largest + value that will be presented or requested via `data_callback`'s `nframes` + parameter. Note: This value may change if the stream is automatically + reconfigured due to device changes. Callers of this API should use + cubeb_stream_register_device_changed_callback to monitor device changes and + requery this API after a device change. + @param stream the stream for which to retrieve max request size. + @param max_request_size the max request size in frames. + @retval CUBEB_OK + @retval CUBEB_ERROR_NOT_SUPPORTED */ +CUBEB_EXPORT int +cubeb_stream_get_max_request_size(cubeb_stream * stream, + uint32_t * max_request_size); + /** Destroy a cubeb_device structure. @param stream the stream passed in cubeb_stream_get_current_device @param devices the devices to destroy diff --git a/src/cubeb-internal.h b/src/cubeb-internal.h index 79326e1e..3e03003d 100644 --- a/src/cubeb-internal.h +++ b/src/cubeb-internal.h @@ -66,6 +66,8 @@ struct cubeb_ops { int (*stream_register_device_changed_callback)( cubeb_stream * stream, cubeb_device_changed_callback device_changed_callback); + int (*stream_get_max_request_size)(cubeb_stream * stream, + uint32_t * max_request_size); int (*register_device_collection_changed)( cubeb * context, cubeb_device_type devtype, cubeb_device_collection_changed_callback callback, void * user_ptr); diff --git a/src/cubeb.c b/src/cubeb.c index b3d32eea..6b542fc6 100644 --- a/src/cubeb.c +++ b/src/cubeb.c @@ -500,6 +500,22 @@ cubeb_stream_get_current_device(cubeb_stream * stream, return stream->context->ops->stream_get_current_device(stream, device); } +int +cubeb_stream_get_max_request_size(cubeb_stream * stream, + uint32_t * max_request_size) +{ + if (!stream || !max_request_size) { + return CUBEB_ERROR_INVALID_PARAMETER; + } + + if (!stream->context->ops->stream_get_max_request_size) { + return CUBEB_ERROR_NOT_SUPPORTED; + } + + return stream->context->ops->stream_get_max_request_size(stream, + max_request_size); +} + int cubeb_stream_device_destroy(cubeb_stream * stream, cubeb_device * device) { diff --git a/src/cubeb_aaudio.cpp b/src/cubeb_aaudio.cpp index 448ea918..a72e6719 100644 --- a/src/cubeb_aaudio.cpp +++ b/src/cubeb_aaudio.cpp @@ -1460,6 +1460,7 @@ const static struct cubeb_ops aaudio_ops = { /*.stream_get_current_device =*/NULL, /*.stream_device_destroy =*/NULL, /*.stream_register_device_changed_callback =*/NULL, + /*.stream_get_max_request_size =*/NULL, /*.register_device_collection_changed =*/NULL}; extern "C" /*static*/ int diff --git a/src/cubeb_alsa.c b/src/cubeb_alsa.c index 08772dd9..e367ced0 100644 --- a/src/cubeb_alsa.c +++ b/src/cubeb_alsa.c @@ -1487,4 +1487,5 @@ static struct cubeb_ops const alsa_ops = { .stream_get_current_device = NULL, .stream_device_destroy = NULL, .stream_register_device_changed_callback = NULL, + .stream_get_max_request_size = NULL, .register_device_collection_changed = NULL}; diff --git a/src/cubeb_audiounit.cpp b/src/cubeb_audiounit.cpp index 02cd1346..2c5ec8b6 100644 --- a/src/cubeb_audiounit.cpp +++ b/src/cubeb_audiounit.cpp @@ -3666,5 +3666,6 @@ cubeb_ops const audiounit_ops = { /*.stream_device_destroy =*/audiounit_stream_device_destroy, /*.stream_register_device_changed_callback =*/ audiounit_stream_register_device_changed_callback, + /*.stream_get_max_request_size = */ NULL, /*.register_device_collection_changed =*/ audiounit_register_device_collection_changed}; diff --git a/src/cubeb_jack.cpp b/src/cubeb_jack.cpp index 35902353..70d05816 100644 --- a/src/cubeb_jack.cpp +++ b/src/cubeb_jack.cpp @@ -175,6 +175,7 @@ static struct cubeb_ops const cbjack_ops = { .stream_get_current_device = cbjack_stream_get_current_device, .stream_device_destroy = cbjack_stream_device_destroy, .stream_register_device_changed_callback = NULL, + .stream_get_max_request_size = NULL, .register_device_collection_changed = NULL}; struct cubeb_stream { diff --git a/src/cubeb_kai.c b/src/cubeb_kai.c index 0a0d6766..a88ad725 100644 --- a/src/cubeb_kai.c +++ b/src/cubeb_kai.c @@ -366,4 +366,5 @@ static struct cubeb_ops const kai_ops = { /*.stream_get_current_device =*/NULL, /*.stream_device_destroy =*/NULL, /*.stream_register_device_changed_callback=*/NULL, + /*.stream_get_max_request_size =*/NULL, /*.register_device_collection_changed=*/NULL}; diff --git a/src/cubeb_opensl.c b/src/cubeb_opensl.c index 78096d5d..68c25703 100644 --- a/src/cubeb_opensl.c +++ b/src/cubeb_opensl.c @@ -1792,4 +1792,5 @@ static struct cubeb_ops const opensl_ops = { .stream_get_current_device = NULL, .stream_device_destroy = NULL, .stream_register_device_changed_callback = NULL, + .stream_get_max_request_size = NULL, .register_device_collection_changed = NULL}; diff --git a/src/cubeb_oss.c b/src/cubeb_oss.c index 083c37ff..80e66da1 100644 --- a/src/cubeb_oss.c +++ b/src/cubeb_oss.c @@ -1326,4 +1326,5 @@ static struct cubeb_ops const oss_ops = { .stream_get_current_device = oss_get_current_device, .stream_device_destroy = oss_stream_device_destroy, .stream_register_device_changed_callback = NULL, + .stream_get_max_request_size = NULL, .register_device_collection_changed = NULL}; diff --git a/src/cubeb_pulse.c b/src/cubeb_pulse.c index 31a2f93d..aafb6162 100644 --- a/src/cubeb_pulse.c +++ b/src/cubeb_pulse.c @@ -1696,5 +1696,6 @@ static struct cubeb_ops const pulse_ops = { .stream_get_current_device = pulse_stream_get_current_device, .stream_device_destroy = pulse_stream_device_destroy, .stream_register_device_changed_callback = NULL, + .stream_get_max_request_size = NULL, .register_device_collection_changed = pulse_register_device_collection_changed}; diff --git a/src/cubeb_sndio.c b/src/cubeb_sndio.c index d7fb7920..db563b45 100644 --- a/src/cubeb_sndio.c +++ b/src/cubeb_sndio.c @@ -666,4 +666,5 @@ static struct cubeb_ops const sndio_ops = { .stream_get_current_device = NULL, .stream_device_destroy = NULL, .stream_register_device_changed_callback = NULL, + .stream_get_max_request_size = NULL, .register_device_collection_changed = NULL}; diff --git a/src/cubeb_sun.c b/src/cubeb_sun.c index 3b7bef71..eeca1900 100644 --- a/src/cubeb_sun.c +++ b/src/cubeb_sun.c @@ -730,4 +730,5 @@ static struct cubeb_ops const sun_ops = { .stream_get_current_device = sun_get_current_device, .stream_device_destroy = sun_stream_device_destroy, .stream_register_device_changed_callback = NULL, + .stream_get_max_request_size = NULL, .register_device_collection_changed = NULL}; diff --git a/src/cubeb_wasapi.cpp b/src/cubeb_wasapi.cpp index 9cc8a262..6f42436a 100644 --- a/src/cubeb_wasapi.cpp +++ b/src/cubeb_wasapi.cpp @@ -2965,6 +2965,23 @@ wasapi_stream_set_volume(cubeb_stream * stm, float volume) return CUBEB_OK; } +// TODO: Need to implement stream_register_device_changed_callback. +int +wasapi_stream_get_max_request_size(cubeb_stream * stm, + uint32_t * max_request_size) +{ + auto_lock lock(stm->stream_reset_lock); + + if (!stm->output_client && !stm->input_client) { + return CUBEB_ERROR; + } + + *max_request_size = + std::max(stm->output_buffer_frame_count, stm->input_buffer_frame_count); + + return CUBEB_OK; +} + static char const * wstr_to_utf8(LPCWSTR str) { @@ -3382,6 +3399,7 @@ cubeb_ops const wasapi_ops = { /*.stream_get_current_device =*/NULL, /*.stream_device_destroy =*/NULL, /*.stream_register_device_changed_callback =*/NULL, + /*.stream_get_max_request_size =*/wasapi_stream_get_max_request_size, /*.register_device_collection_changed =*/ wasapi_register_device_collection_changed, }; diff --git a/src/cubeb_winmm.c b/src/cubeb_winmm.c index 169b7438..1052da7b 100644 --- a/src/cubeb_winmm.c +++ b/src/cubeb_winmm.c @@ -1179,4 +1179,5 @@ static struct cubeb_ops const winmm_ops = { /*.stream_get_current_device =*/NULL, /*.stream_device_destroy =*/NULL, /*.stream_register_device_changed_callback=*/NULL, + /*.stream_get_max_request_size = */ NULL, /*.register_device_collection_changed =*/NULL};