From a4b5c1ebf1e784485c483818767a0e43d0385d93 Mon Sep 17 00:00:00 2001 From: Ruwen Hahn Date: Thu, 8 Aug 2024 13:59:57 +0200 Subject: [PATCH] Use condition variable to signal input thread if available --- src/tests/localvocal-offline-test.cpp | 48 +++++++++--------------- src/transcription-filter-data.h | 1 + src/whisper-utils/whisper-processing.cpp | 3 ++ 3 files changed, 21 insertions(+), 31 deletions(-) diff --git a/src/tests/localvocal-offline-test.cpp b/src/tests/localvocal-offline-test.cpp index ad14ef5..f5f9bc4 100644 --- a/src/tests/localvocal-offline-test.cpp +++ b/src/tests/localvocal-offline-test.cpp @@ -101,6 +101,7 @@ create_context(int sample_rate, int channels, const std::string &whisper_model_p gf->process_while_muted = false; gf->buffered_output = false; gf->fix_utf8 = true; + gf->input_cv.emplace(); for (size_t i = 0; i < gf->channels; i++) { circlebuf_init(&gf->input_buffers[i]); @@ -453,38 +454,23 @@ int wmain(int argc, wchar_t *argv[]) frames_size_bytes = frames * frame_size_bytes; } { - bool wait = false; - auto max_wait = - start_time_time + (window_number * window_size_in_ms); - for (;;) { - { - std::lock_guard lock( - gf->whisper_buf_mutex); - wait = gf->input_buffers->size != 0; - } - if (!wait) - break; - - // sleep up to window size in case whisper is processing, so the buffer builds up similar to OBS - auto now = std::chrono::system_clock::now(); - if (false && now > max_wait) - break; - - auto wait_start = now + std::chrono::milliseconds(1); - auto wait_until = max_wait > wait_start ? wait_start - : max_wait; -#if 0 - obs_log(LOG_INFO, "sleeping %lld ms", - std::chrono::duration_cast( - (wait_until - - std::chrono::system_clock::now())) - .count()); -#endif - std::this_thread::sleep_until(wait_until); - } - { - std::lock_guard lock(gf->whisper_buf_mutex); + auto max_wait = start_time_time + + (window_number * window_size_in_ms); + std::unique_lock lock(gf->whisper_buf_mutex); + for (;;) { + // sleep up to window size in case whisper is processing, so the buffer builds up similar to OBS + auto now = std::chrono::system_clock::now(); + if (false && now > max_wait) + break; + + gf->input_cv->wait_for( + lock, std::chrono::milliseconds(10), [&] { + return gf->input_buffers->size == 0; + }); + if (gf->input_buffers->size == 0) + break; + } // push back current audio data to input circlebuf for (size_t c = 0; c < gf->channels; c++) { circlebuf_push_back( diff --git a/src/transcription-filter-data.h b/src/transcription-filter-data.h index 8a640f3..4b16d13 100644 --- a/src/transcription-filter-data.h +++ b/src/transcription-filter-data.h @@ -104,6 +104,7 @@ struct transcription_filter_data { std::mutex whisper_buf_mutex; std::mutex whisper_ctx_mutex; std::condition_variable wshiper_thread_cv; + std::optional input_cv; // translation context struct translation_context translation_ctx; diff --git a/src/whisper-utils/whisper-processing.cpp b/src/whisper-utils/whisper-processing.cpp index 347d821..e0f190c 100644 --- a/src/whisper-utils/whisper-processing.cpp +++ b/src/whisper-utils/whisper-processing.cpp @@ -599,6 +599,9 @@ void whisper_loop(void *data) } } + if (gf->input_cv.has_value()) + gf->input_cv->notify_one(); + // Sleep using the condition variable wshiper_thread_cv // This will wake up the thread if there is new data in the input buffer // or if the whisper context is null