diff options
Diffstat (limited to 'platform/linuxbsd/tts_linux.cpp')
-rw-r--r-- | platform/linuxbsd/tts_linux.cpp | 71 |
1 files changed, 40 insertions, 31 deletions
diff --git a/platform/linuxbsd/tts_linux.cpp b/platform/linuxbsd/tts_linux.cpp index 6b8584ef6c..8bc83f5b9c 100644 --- a/platform/linuxbsd/tts_linux.cpp +++ b/platform/linuxbsd/tts_linux.cpp @@ -35,11 +35,6 @@ TTS_Linux *TTS_Linux::singleton = nullptr; -void TTS_Linux::_bind_methods() { - ClassDB::bind_method(D_METHOD("_speech_event", "msg_id", "client_id", "type"), &TTS_Linux::_speech_event); - ClassDB::bind_method(D_METHOD("_speech_index_mark", "msg_id", "client_id", "type", "index_mark"), &TTS_Linux::_speech_index_mark); -} - void TTS_Linux::speech_init_thread_func(void *p_userdata) { TTS_Linux *tts = (TTS_Linux *)p_userdata; if (tts) { @@ -53,6 +48,11 @@ void TTS_Linux::speech_init_thread_func(void *p_userdata) { if (initialize_speechd(dylibloader_verbose) != 0) { print_verbose("Text-to-Speech: Cannot load Speech Dispatcher library!"); } else { + if (!spd_open || !spd_set_notification_on || !spd_list_synthesis_voices || !free_spd_voices || !spd_set_synthesis_voice || !spd_set_volume || !spd_set_voice_pitch || !spd_set_voice_rate || !spd_set_data_mode || !spd_say || !spd_pause || !spd_resume || !spd_cancel) { + // There's no API to check version, check if functions are available instead. + print_verbose("Text-to-Speech: Unsupported Speech Dispatcher library version!"); + return; + } #else { #endif @@ -82,7 +82,7 @@ void TTS_Linux::speech_init_thread_func(void *p_userdata) { void TTS_Linux::speech_event_index_mark(size_t p_msg_id, size_t p_client_id, SPDNotificationType p_type, char *p_index_mark) { TTS_Linux *tts = TTS_Linux::get_singleton(); if (tts) { - tts->call_deferred(SNAME("_speech_index_mark"), p_msg_id, p_client_id, (int)p_type, String::utf8(p_index_mark)); + callable_mp(tts, &TTS_Linux::_speech_index_mark).call_deferred(p_msg_id, p_client_id, (int)p_type, String::utf8(p_index_mark)); } } @@ -97,7 +97,25 @@ void TTS_Linux::_speech_index_mark(size_t p_msg_id, size_t p_client_id, int p_ty void TTS_Linux::speech_event_callback(size_t p_msg_id, size_t p_client_id, SPDNotificationType p_type) { TTS_Linux *tts = TTS_Linux::get_singleton(); if (tts) { - tts->call_deferred(SNAME("_speech_event"), p_msg_id, p_client_id, (int)p_type); + callable_mp(tts, &TTS_Linux::_speech_event).call_deferred(p_msg_id, p_client_id, (int)p_type); + } +} + +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; } } @@ -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()); + const_cast<TTS_Linux *>(this)->_load_voices(); + 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); - - voices_ptr++; - } - free_spd_voices(voices); + for (const KeyValue<String, VoiceInfo> &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; } |