summaryrefslogtreecommitdiffstats
path: root/platform/linuxbsd/tts_linux.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd/tts_linux.cpp')
-rw-r--r--platform/linuxbsd/tts_linux.cpp71
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;
}