From fe7c26d27d47f6087b67af9fe740f674078b5da1 Mon Sep 17 00:00:00 2001 From: Tursiae Date: Sun, 9 Feb 2025 18:25:16 +1100 Subject: [PATCH] TTS: Avoid exhausting the WorkerPool with concurrent TTS playback. Reported in issue #258. As of v1.2.0, if /.tangara-tts/ samples are present on the SD card, and >= 4 menu items with matching TTS samples are highlighted in the UI, and no audio output (headphones or BT sink) is connected, the `tts::Player`'s invocation of lambdas on the WorkerPool will result in worker task exhaustion. This is because we get stuck in state where the `drivers::PcmBuffer` is not accepting any new samples, and the inner loop in `Player::decodeToSink` that pushes to the output isn't checking to see whether playback was cancelled. So the loop never terminates, and we consume that worker slot. Repeat with another 3 menu items, and, hey, all four worker threads are consumed with TTS that will not terminate until headphones/BT are connected. --- src/tangara/tts/player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tangara/tts/player.cpp b/src/tangara/tts/player.cpp index 46e8c48a..9cc7a1f7 100644 --- a/src/tangara/tts/player.cpp +++ b/src/tangara/tts/player.cpp @@ -174,7 +174,7 @@ auto Player::decodeToSink(const codecs::ICodec::OutputFormat& format, // The mixin PcmBuffer should almost always be draining, so we can force // samples into it more aggressively than with the main music PcmBuffer. - while (!stereo_buf.isEmpty()) { + while (!stereo_buf.isEmpty() && !stream_cancelled_) { size_t sent = output_.send(stereo_buf.readAcquire()); stereo_buf.readCommit(sent); }