aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/text-to-speech/linux/linux-text-to-speech.cpp11
-rw-r--r--backends/text-to-speech/linux/linux-text-to-speech.h2
-rw-r--r--backends/text-to-speech/windows/windows-text-to-speech.cpp4
-rw-r--r--backends/text-to-speech/windows/windows-text-to-speech.h2
-rw-r--r--common/text-to-speech.cpp56
-rw-r--r--common/text-to-speech.h22
6 files changed, 79 insertions, 18 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 633c107727..db036e053a 100644
--- a/backends/text-to-speech/linux/linux-text-to-speech.cpp
+++ b/backends/text-to-speech/linux/linux-text-to-speech.cpp
@@ -206,7 +206,8 @@ void LinuxTextToSpeechManager::setLanguage(Common::String language) {
void LinuxTextToSpeechManager::createVoice(int typeNumber, Common::TTSVoice::Gender gender, Common::TTSVoice::Age age, char *description) {
SPDVoiceType *type = (SPDVoiceType *) malloc(sizeof(SPDVoiceType));
*type = static_cast<SPDVoiceType>(typeNumber);
- _ttsState->_availaibleVoices.push_back(Common::TTSVoice(gender, age, (void *) type, description));
+ Common::TTSVoice voice(gender, age, (void *) type, description);
+ _ttsState->_availaibleVoices.push_back(voice);
}
void LinuxTextToSpeechManager::updateVoices() {
@@ -238,10 +239,6 @@ bool LinuxTextToSpeechManager::popState() {
if (_ttsState->_next == nullptr)
return true;
- for (Common::TTSVoice *i = _ttsState->_availaibleVoices.begin(); i < _ttsState->_availaibleVoices.end(); i++) {
- free(i->getData());
- }
-
Common::TTSState *oldState = _ttsState;
_ttsState = _ttsState->_next;
@@ -254,5 +251,9 @@ bool LinuxTextToSpeechManager::popState() {
return false;
}
+void LinuxTextToSpeechManager::freeVoiceData(void *data) {
+ free(data);
+}
+
#endif
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 64c2371b72..57b9aeea60 100644
--- a/backends/text-to-speech/linux/linux-text-to-speech.h
+++ b/backends/text-to-speech/linux/linux-text-to-speech.h
@@ -67,6 +67,8 @@ public:
void updateState(SpeechState state);
+ virtual void freeVoiceData(void *data);
+
private:
void init();
virtual void updateVoices();
diff --git a/backends/text-to-speech/windows/windows-text-to-speech.cpp b/backends/text-to-speech/windows/windows-text-to-speech.cpp
index f688ec1cd5..fec5a408d1 100644
--- a/backends/text-to-speech/windows/windows-text-to-speech.cpp
+++ b/backends/text-to-speech/windows/windows-text-to-speech.cpp
@@ -360,5 +360,9 @@ bool WindowsTextToSpeechManager::popState() {
setVoice(_ttsState->_activeVoice);
return false;
}
+void WindowsTextToSpeechManager::freeVoiceData(void *data) {
+ ISpObjectToken *voiceToken = (ISpObjectToken *) data;
+ voiceToken->Release();
+}
#endif
diff --git a/backends/text-to-speech/windows/windows-text-to-speech.h b/backends/text-to-speech/windows/windows-text-to-speech.h
index 03a1806849..2ae062ce92 100644
--- a/backends/text-to-speech/windows/windows-text-to-speech.h
+++ b/backends/text-to-speech/windows/windows-text-to-speech.h
@@ -66,6 +66,8 @@ public:
virtual bool popState();
+ virtual void freeVoiceData(void *data);
+
private:
void init();
virtual void updateVoices();
diff --git a/common/text-to-speech.cpp b/common/text-to-speech.cpp
index e8e0d9b870..ce9f4a9076 100644
--- a/common/text-to-speech.cpp
+++ b/common/text-to-speech.cpp
@@ -22,9 +22,62 @@
#include "common/text-to-speech.h"
+#include "common/system.h"
#if defined(USE_TTS)
namespace Common {
+
+TTSVoice::TTSVoice()
+ : _gender(UNKNOWN_GENDER)
+ , _age(UNKNOWN_AGE)
+ , _data(nullptr)
+ , _description("") {
+ _refCount = new int;
+ *_refCount = 1;
+}
+
+TTSVoice::TTSVoice(Gender gender, Age age, void *data, String description)
+ : _gender(gender)
+ , _age(age)
+ , _data(data)
+ , _description(description) {
+ _refCount = new int;
+ *_refCount = 1;
+}
+
+TTSVoice::TTSVoice(const TTSVoice& voice)
+ : _gender(voice._gender)
+ , _age(voice._age)
+ , _data(voice._data)
+ , _refCount(voice._refCount)
+ , _description(voice._description) {
+ if (_data)
+ (*_refCount)++;
+}
+
+TTSVoice::~TTSVoice() {
+ // _data is a platform specific field and so it the
+ // way it is freed differs from platform to platform
+ if (--(*_refCount) == 0) {
+ if (_data)
+ g_system->getTextToSpeechManager()->freeVoiceData(_data);
+ delete _refCount;
+ }
+}
+
+TTSVoice& TTSVoice::operator=(const TTSVoice& voice) {
+ if (&voice != this) {
+ _gender = voice._gender;
+ _data = voice._data;
+ _age = voice._age;
+ _refCount = voice._refCount;
+ if (_data)
+ (*_refCount)++;
+ _description = voice._description;
+ }
+ return *this;
+}
+
TextToSpeechManager::TextToSpeechManager() {
_ttsState = new TTSState;
_ttsState->_pitch = 0;
@@ -39,9 +92,6 @@ TextToSpeechManager::~TextToSpeechManager() {
TTSState *tmp = _ttsState;
while (tmp != nullptr) {
tmp = _ttsState->_next;
- for (TTSVoice *i = _ttsState->_availaibleVoices.begin(); i < _ttsState->_availaibleVoices.end(); i++) {
- free(i->_data);
- }
delete _ttsState;
_ttsState = tmp;
}
diff --git a/common/text-to-speech.h b/common/text-to-speech.h
index 63ea1a95c0..606f8d2d4b 100644
--- a/common/text-to-speech.h
+++ b/common/text-to-speech.h
@@ -52,16 +52,15 @@ class TTSVoice {
};
public:
- TTSVoice()
- : _gender(UNKNOWN_GENDER)
- , _age(UNKNOWN_AGE)
- , _data(nullptr)
- , _description("") {}
- TTSVoice(Gender gender, Age age, void *data, String description)
- : _gender(gender)
- , _age(age)
- , _data(data)
- , _description(description) {}
+ TTSVoice();
+
+ TTSVoice(Gender gender, Age age, void *data, String description) ;
+
+ TTSVoice(const TTSVoice& voice);
+
+ ~TTSVoice();
+
+ TTSVoice& operator=(const TTSVoice& voice);
/**
* Returns the gender of the used voice.
@@ -120,6 +119,7 @@ class TTSVoice {
Age _age;
void *_data;
String _description;
+ int *_refCount;
};
struct TTSState {
@@ -261,6 +261,8 @@ public:
*/
virtual bool popState() { return true; }
+ virtual void freeVoiceData(void *data) {}
+
protected:
TTSState *_ttsState;