diff options
author | Paul Adenot <[email protected]> | 2023-04-19 11:24:05 +0200 |
---|---|---|
committer | Paul Adenot <[email protected]> | 2023-04-19 13:37:43 +0200 |
commit | 479f8c5dec2c31ced12dbc4c64ff86ffb4ed50b7 (patch) | |
tree | 6943a73d5f891a2a53b3acc194c6e6b9c02b8fbb | |
parent | 55893cfa163ae4200f8b58d255f8b292b7554a47 (diff) | |
download | cubeb-479f8c5dec2c31ced12dbc4c64ff86ffb4ed50b7.tar.gz cubeb-479f8c5dec2c31ced12dbc4c64ff86ffb4ed50b7.zip |
Don't spin when waiting for streams to be stopped.
-rw-r--r-- | src/cubeb_aaudio.cpp | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/src/cubeb_aaudio.cpp b/src/cubeb_aaudio.cpp index 5f1319e..4d9b062 100644 --- a/src/cubeb_aaudio.cpp +++ b/src/cubeb_aaudio.cpp @@ -15,6 +15,7 @@ #include <cassert> #include <chrono> #include <condition_variable> +#include <cstdint> #include <cstring> #include <dlfcn.h> #include <inttypes.h> @@ -101,6 +102,7 @@ LIBAAUDIO_API_VISIT(MAKE_TYPEDEF) #endif const uint8_t MAX_STREAMS = 16; +const int64_t NS_PER_S = static_cast<int64_t>(1e9); using unique_lock = std::unique_lock<std::mutex>; using lock_guard = std::lock_guard<std::mutex>; @@ -190,15 +192,22 @@ struct AutoInCallback { cubeb_stream * stm; }; -// Returns when aaudio_stream's state is equal to desired_state +// Returns when aaudio_stream's state is equal to desired_state. +// poll_frequency_ns is the duration that is slept in between asking for +// state updates and getting the new state. +// When waiting for a stream to stop, it is best to pick a value similar +// to the callback time because STOPPED will happen after +// draining. static int wait_for_state_change(AAudioStream * aaudio_stream, - aaudio_stream_state_t desired_state) + aaudio_stream_state_t desired_state, + int64_t poll_frequency_ns) { aaudio_stream_state_t new_state; do { aaudio_result_t res = WRAP(AAudioStream_waitForStateChange)( - aaudio_stream, AAUDIO_STREAM_STATE_UNKNOWN, &new_state, 0); + aaudio_stream, AAUDIO_STREAM_STATE_UNKNOWN, &new_state, + poll_frequency_ns); if (res != AAUDIO_OK) { LOG("AAudioStream_waitForStateChanged: %s", WRAP(AAudio_convertResultToText)(res)); @@ -223,11 +232,14 @@ shutdown_with_error(cubeb_stream * stm) WRAP(AAudioStream_requestStop)(stm->ostream); } + int64_t poll_frequency_ns = NS_PER_S * stm->out_frame_size / stm->sample_rate; if (stm->istream) { - wait_for_state_change(stm->istream, AAUDIO_STREAM_STATE_STOPPED); + wait_for_state_change(stm->istream, AAUDIO_STREAM_STATE_STOPPED, + poll_frequency_ns); } if (stm->ostream) { - wait_for_state_change(stm->ostream, AAUDIO_STREAM_STATE_STOPPED); + wait_for_state_change(stm->ostream, AAUDIO_STREAM_STATE_STOPPED, + poll_frequency_ns); } assert(!stm->in_data_callback.load()); @@ -1250,8 +1262,8 @@ aaudio_stream_start(cubeb_stream * stm) break; // If the state switched [DRAINING -> STOPPING] or [DRAINING/STOPPING -> - // STOPPED] in the meantime, we can simply overwrite that since we restarted - // the stream. + // STOPPED] in the meantime, we can simply overwrite that since we + // restarted the stream. case stream_state::STOPPING: case stream_state::STOPPED: continue; |