1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-08 12:40:44 +00:00

[Linux/TTS] Cache TTS voice list.

This commit is contained in:
bruvzg
2023-06-02 14:00:52 +03:00
parent eab4075f1e
commit e15f37945b
2 changed files with 41 additions and 24 deletions

View File

@@ -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) { void TTS_Linux::_speech_event(size_t p_msg_id, size_t p_client_id, int p_type) {
_THREAD_SAFE_METHOD_ _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. // Inject index mark after each word.
String text; String text;
String language; String language;
SPDVoice **voices = spd_list_synthesis_voices(synth);
if (voices != nullptr) { _load_voices();
SPDVoice **voices_ptr = voices; const VoiceInfo *voice = voices.getptr(message.voice);
while (*voices_ptr != nullptr) { if (voice) {
if (String::utf8((*voices_ptr)->name) == message.voice) { language = voice->language;
language = String::utf8((*voices_ptr)->language);
break;
}
voices_ptr++;
}
free_spd_voices(voices);
} }
PackedInt32Array breaks = TS->string_get_word_breaks(message.text, language); PackedInt32Array breaks = TS->string_get_word_breaks(message.text, language);
for (int i = 0; i < breaks.size(); i += 2) { for (int i = 0; i < breaks.size(); i += 2) {
const int start = breaks[i]; const int start = breaks[i];
@@ -174,21 +187,17 @@ Array TTS_Linux::get_voices() const {
_THREAD_SAFE_METHOD_ _THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!synth, Array()); ERR_FAIL_COND_V(!synth, Array());
Array list; const_cast<TTS_Linux *>(this)->_load_voices();
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);
voices_ptr++; Array list;
} for (const KeyValue<String, VoiceInfo> &E : voices) {
free_spd_voices(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; return list;
} }

View File

@@ -55,6 +55,13 @@ class TTS_Linux : public Object {
int last_msg_id = -1; int last_msg_id = -1;
HashMap<int, int> ids; HashMap<int, int> ids;
struct VoiceInfo {
String language;
String variant;
};
bool voices_loaded = false;
HashMap<String, VoiceInfo> voices;
Thread init_thread; Thread init_thread;
static void speech_init_thread_func(void *p_userdata); static void speech_init_thread_func(void *p_userdata);
@@ -64,6 +71,7 @@ class TTS_Linux : public Object {
static TTS_Linux *singleton; static TTS_Linux *singleton;
protected: protected:
void _load_voices();
void _speech_event(size_t p_msg_id, size_t p_client_id, int p_type); 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); void _speech_index_mark(size_t p_msg_id, size_t p_client_id, int p_type, const String &p_index_mark);