diff options
-rw-r--r-- | backends/text-to-speech/linux/linux-text-to-speech.cpp | 79 | ||||
-rw-r--r-- | backends/text-to-speech/linux/linux-text-to-speech.h | 16 |
2 files changed, 68 insertions, 27 deletions
diff --git a/backends/text-to-speech/linux/linux-text-to-speech.cpp b/backends/text-to-speech/linux/linux-text-to-speech.cpp index 97d05a67c1..20ba07d74d 100644 --- a/backends/text-to-speech/linux/linux-text-to-speech.cpp +++ b/backends/text-to-speech/linux/linux-text-to-speech.cpp @@ -28,45 +28,42 @@ #if defined(USE_LINUX_TTS) #include <speech-dispatcher/libspeechd.h> #include "backends/platform/sdl/sdl-sys.h" -//#include <iconv.h> #include "common/translation.h" #include "common/system.h" #include "common/ustr.h" #include "common/config-manager.h" + SPDConnection *_connection; void speech_begin_callback(size_t msg_id, size_t client_id, SPDNotificationType state){ LinuxTextToSpeechManager *manager = static_cast<LinuxTextToSpeechManager *> (g_system->getTextToSpeechManager()); - manager->updateState(LinuxTextToSpeechManager::SPEAKING); + manager->updateState(LinuxTextToSpeechManager::SPEECH_BEGUN); } void speech_end_callback(size_t msg_id, size_t client_id, SPDNotificationType state){ LinuxTextToSpeechManager *manager = static_cast<LinuxTextToSpeechManager *> (g_system->getTextToSpeechManager()); - manager->updateState(LinuxTextToSpeechManager::READY); + manager->updateState(LinuxTextToSpeechManager::SPEECH_ENDED); } void speech_cancel_callback(size_t msg_id, size_t client_id, SPDNotificationType state){ LinuxTextToSpeechManager *manager = static_cast<LinuxTextToSpeechManager *> (g_system->getTextToSpeechManager()); - if (manager->isSpeaking()) - manager->updateState(LinuxTextToSpeechManager::READY); - if (manager->isPaused()) - manager->updateState(LinuxTextToSpeechManager::PAUSED); + manager->updateState(LinuxTextToSpeechManager::SPEECH_CANCELED); } void speech_resume_callback(size_t msg_id, size_t client_id, SPDNotificationType state){ LinuxTextToSpeechManager *manager = static_cast<LinuxTextToSpeechManager *> (g_system->getTextToSpeechManager()); - manager->updateState(LinuxTextToSpeechManager::SPEAKING); + manager->updateState(LinuxTextToSpeechManager::SPEECH_RESUMED); } void speech_pause_callback(size_t msg_id, size_t client_id, SPDNotificationType state){ LinuxTextToSpeechManager *manager = static_cast<LinuxTextToSpeechManager *> (g_system->getTextToSpeechManager()); - manager->updateState(LinuxTextToSpeechManager::PAUSED); + manager->updateState(LinuxTextToSpeechManager::SPEECH_PAUSED); } LinuxTextToSpeechManager::LinuxTextToSpeechManager() @@ -101,6 +98,7 @@ void LinuxTextToSpeechManager::init() { #else setLanguage("en"); #endif + _speechQueue.clear(); } LinuxTextToSpeechManager::~LinuxTextToSpeechManager() { @@ -108,8 +106,29 @@ LinuxTextToSpeechManager::~LinuxTextToSpeechManager() { spd_close(_connection); } -void LinuxTextToSpeechManager::updateState(LinuxTextToSpeechManager::SpeechState state) { - _speechState = state; +void LinuxTextToSpeechManager::updateState(LinuxTextToSpeechManager::SpeechEvent event) { + if (_speechState == BROKEN) + return; + switch(event) { + case SPEECH_ENDED: + _speechQueue.pop_front(); + if (_speechQueue.size() == 0) + _speechState = READY; + break; + case SPEECH_PAUSED: + _speechState = PAUSED; + break; + case SPEECH_CANCELED: + if (_speechState != PAUSED) { + _speechState = READY; + } + break; + case SPEECH_RESUMED: + break; + case SPEECH_BEGUN: + _speechState = SPEAKING; + break; + } } Common::String LinuxTextToSpeechManager::strToUtf8(Common::String str, Common::String charset) { @@ -155,17 +174,19 @@ bool LinuxTextToSpeechManager::say(Common::String str, Action action, Common::St str = strToUtf8(str, charset); - if (isSpeaking() && action == INTERRUPT || action == INTERRUPT_NO_REPEAT) + if (isSpeaking() && (action == INTERRUPT || action == INTERRUPT_NO_REPEAT)) stop(); - if (str.size() != 0) + if (!str.empty()) { _speechState = SPEAKING; - _lastSaid = str; - if(spd_say(_connection, SPD_MESSAGE, str.c_str()) == -1) { - //restart the connection - if (_connection != 0) - spd_close(_connection); - init(); - return true; + _speechQueue.push_back(str); + _lastSaid = str; + if(spd_say(_connection, SPD_MESSAGE, str.c_str()) == -1) { + //restart the connection + if (_connection != 0) + spd_close(_connection); + init(); + return true; + } } return false; @@ -175,27 +196,35 @@ bool LinuxTextToSpeechManager::stop() { if (_speechState == READY || _speechState == BROKEN) return true; _speechState = READY; + _speechQueue.clear(); return spd_cancel(_connection) == -1; } bool LinuxTextToSpeechManager::pause() { if (_speechState == READY || _speechState == PAUSED || _speechState == BROKEN) return true; - bool result = spd_pause_all(_connection) == -1; + _speechState = PAUSED; + bool result = spd_cancel_all(_connection) == -1; if (result) return true; - result = spd_stop(_connection) == -1; if (result) return true; - _speechState = PAUSED; return false; } bool LinuxTextToSpeechManager::resume() { if (_speechState == READY || _speechState == SPEAKING || _speechState == BROKEN) return true; - _speechState = SPEAKING; - return spd_resume(_connection) == -1; + if (_speechQueue.size()) { + _speechState = SPEAKING; + for (Common::List<Common::String>::iterator i = _speechQueue.begin(); i != _speechQueue.end(); i++) { + if (spd_say(_connection, SPD_MESSAGE, i->c_str()) == -1) + return true; + } + } + else + _speechState = READY; + return false; } bool LinuxTextToSpeechManager::isSpeaking() { diff --git a/backends/text-to-speech/linux/linux-text-to-speech.h b/backends/text-to-speech/linux/linux-text-to-speech.h index 30fa9b878c..23c35c33f6 100644 --- a/backends/text-to-speech/linux/linux-text-to-speech.h +++ b/backends/text-to-speech/linux/linux-text-to-speech.h @@ -29,6 +29,7 @@ #include "common/text-to-speech.h" #include "common/str.h" +#include "common/list.h" class LinuxTextToSpeechManager : public Common::TextToSpeechManager { public: @@ -39,6 +40,14 @@ public: BROKEN }; + enum SpeechEvent { + SPEECH_ENDED, + SPEECH_PAUSED, + SPEECH_CANCELED, + SPEECH_RESUMED, + SPEECH_BEGUN + }; + LinuxTextToSpeechManager(); virtual ~LinuxTextToSpeechManager(); @@ -62,7 +71,7 @@ public: virtual void setLanguage(Common::String language); - void updateState(SpeechState state); + void updateState(SpeechEvent event); virtual void freeVoiceData(void *data); @@ -70,9 +79,12 @@ private: void init(); virtual void updateVoices(); void createVoice(int typeNumber, Common::TTSVoice::Gender, Common::TTSVoice::Age, char *description); - SpeechState _speechState; Common::String strToUtf8(Common::String str, Common::String charset); + bool spdSay(const char *str); + + SpeechState _speechState; Common::String _lastSaid; + Common::List<Common::String> _speechQueue; }; #endif |