From e15f37945b9e1ef4995322957346fdca624c1733 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Fri, 2 Jun 2023 14:00:52 +0300 Subject: [PATCH] [Linux/TTS] Cache TTS voice list. --- platform/linuxbsd/tts_linux.cpp | 57 +++++++++++++++++++-------------- platform/linuxbsd/tts_linux.h | 8 +++++ 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/platform/linuxbsd/tts_linux.cpp b/platform/linuxbsd/tts_linux.cpp index a0cb4f5c6c2..8bc83f5b9ce 100644 --- a/platform/linuxbsd/tts_linux.cpp +++ b/platform/linuxbsd/tts_linux.cpp @@ -101,6 +101,24 @@ void TTS_Linux::speech_event_callback(size_t p_msg_id, size_t p_client_id, SPDNo } } +void TTS_Linux::_load_voices() { + if (!voices_loaded) { + SPDVoice **spd_voices = spd_list_synthesis_voices(synth); + if (spd_voices != nullptr) { + SPDVoice **voices_ptr = spd_voices; + while (*voices_ptr != nullptr) { + VoiceInfo vi; + vi.language = String::utf8((*voices_ptr)->language); + vi.variant = String::utf8((*voices_ptr)->variant); + voices[String::utf8((*voices_ptr)->name)] = vi; + voices_ptr++; + } + free_spd_voices(spd_voices); + } + voices_loaded = true; + } +} + void TTS_Linux::_speech_event(size_t p_msg_id, size_t p_client_id, int p_type) { _THREAD_SAFE_METHOD_ @@ -123,18 +141,13 @@ void TTS_Linux::_speech_event(size_t p_msg_id, size_t p_client_id, int p_type) { // Inject index mark after each word. String text; String language; - SPDVoice **voices = spd_list_synthesis_voices(synth); - if (voices != nullptr) { - SPDVoice **voices_ptr = voices; - while (*voices_ptr != nullptr) { - if (String::utf8((*voices_ptr)->name) == message.voice) { - language = String::utf8((*voices_ptr)->language); - break; - } - voices_ptr++; - } - free_spd_voices(voices); + + _load_voices(); + const VoiceInfo *voice = voices.getptr(message.voice); + if (voice) { + language = voice->language; } + PackedInt32Array breaks = TS->string_get_word_breaks(message.text, language); for (int i = 0; i < breaks.size(); i += 2) { const int start = breaks[i]; @@ -174,21 +187,17 @@ Array TTS_Linux::get_voices() const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!synth, Array()); - Array list; - SPDVoice **voices = spd_list_synthesis_voices(synth); - if (voices != nullptr) { - SPDVoice **voices_ptr = voices; - while (*voices_ptr != nullptr) { - Dictionary voice_d; - voice_d["name"] = String::utf8((*voices_ptr)->name); - voice_d["id"] = String::utf8((*voices_ptr)->name); - voice_d["language"] = String::utf8((*voices_ptr)->language) + "_" + String::utf8((*voices_ptr)->variant); - list.push_back(voice_d); + const_cast(this)->_load_voices(); - voices_ptr++; - } - free_spd_voices(voices); + Array list; + for (const KeyValue &E : voices) { + Dictionary voice_d; + voice_d["name"] = E.key; + voice_d["id"] = E.key; + voice_d["language"] = E.value.language + "_" + E.value.variant; + list.push_back(voice_d); } + return list; } diff --git a/platform/linuxbsd/tts_linux.h b/platform/linuxbsd/tts_linux.h index 651a64d9d62..ec68219689b 100644 --- a/platform/linuxbsd/tts_linux.h +++ b/platform/linuxbsd/tts_linux.h @@ -55,6 +55,13 @@ class TTS_Linux : public Object { int last_msg_id = -1; HashMap ids; + struct VoiceInfo { + String language; + String variant; + }; + bool voices_loaded = false; + HashMap voices; + Thread init_thread; static void speech_init_thread_func(void *p_userdata); @@ -64,6 +71,7 @@ class TTS_Linux : public Object { static TTS_Linux *singleton; protected: + void _load_voices(); void _speech_event(size_t p_msg_id, size_t p_client_id, int p_type); void _speech_index_mark(size_t p_msg_id, size_t p_client_id, int p_type, const String &p_index_mark);