1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef BACKENDS_TEXT_TO_SPEECH_ABSTRACT_H
24 #define BACKENDS_TEXT_TO_SPEECH_ABSTRACT_H
25 
26 #include "common/scummsys.h"
27 #include "common/str.h"
28 
29 #include "common/array.h"
30 namespace Common {
31 
32 
33 /**
34  * @defgroup common_text_speech Text-to-speech Manager
35  * @ingroup common
36  *
37  * @brief The TTS module allows for speech synthesis.
38  *
39  * @{
40  */
41 
42 /**
43  * Text to speech voice class.
44  */
45 class TTSVoice {
46 	friend class TextToSpeechManager;
47 
48 	public:
49 		enum Gender {
50 			MALE,
51 			FEMALE,
52 			UNKNOWN_GENDER
53 		};
54 
55 		enum Age {
56 			CHILD,
57 			ADULT,
58 			UNKNOWN_AGE
59 		};
60 
61 	public:
62 		TTSVoice();
63 
64 		TTSVoice(Gender gender, Age age, void *data, String description) ;
65 
66 		TTSVoice(const TTSVoice& voice);
67 
68 		~TTSVoice();
69 
70 		TTSVoice& operator=(const TTSVoice& voice);
71 
72 		/**
73 		 * Returns the gender of the used voice.
74 		 *
75 		 * @note The gender information is really platform specific, it may not be
76 		 * possible to find it out on some platforms. Sometimes it can be set by
77 		 * the user in the TTS engine configuration and so the information might be
78 		 * wrong
79 		 */
getGender()80 		Gender getGender() { return _gender; };
81 
82 		/**
83 		 * Sets the voice gender, should probably be used only by the backends
84 		 * that are directly communicating with the TTS engine.
85 		 */
setGender(Gender gender)86 		void setGender(Gender gender) { _gender = gender; };
87 
88 		/**
89 		 * Returns the age of the used voice.
90 		 *
91 		 * @note The age information is really platform specific, it may not be
92 		 * possible to find it out on some platforms. Sometimes it can be set by
93 		 * the user in the TTS engine configuration and so the information might be
94 		 * wrong
95 		 */
getAge()96 		Age getAge() { return _age; };
97 
98 		/**
99 		 * Sets the voice age, should probably be used only by the backends
100 		 * that are directly communicating with the TTS engine.
101 		 */
setAge(Age age)102 		void setAge(Age age) { _age = age; };
103 
104 		/**
105 		 * Returns the data about the voice, this is engine specific variable,
106 		 * it has close to no value for anything else then communicating
107 		 * directly with the TTS engine, which should probably be done only by
108 		 * the backends.
109 		 */
getData()110 		void *getData() { return _data; };
111 
112 		/**
113 		 * Sets the voice data, should probably be used only by the backends
114 		 * that are directly communicating with the TTS engine.
115 		 */
setData(void * data)116 		void setData(void *data) { _data = data; };
117 
118 		/**
119 		 * Returns the voice description. This description is really tts engine
120 		 * specific and might be not be available with some tts engines.
121 		 */
getDescription()122 		String getDescription() { return _description; };
123 
124 	protected:
125 		Gender _gender; ///< Gender of the voice
126 		Age _age; ///< Age of the voice
127 		void *_data; ///< Pointer to tts engine specific data about the voice
128 		String _description; ///< Description of the voice (gets displayed in GUI)
129 		int *_refCount; ///< Reference count (serves for proper feeing of _data)
130 };
131 
132 struct TTSState {
133 	int _rate;
134 	int _pitch;
135 	int _volume;
136 	String _language;
137 	int _activeVoice;
138 	Array<TTSVoice> _availableVoices;
139 	TTSState *_next;
140 };
141 
142 /**
143  * The TextToSpeechManager allows speech synthesis.
144  */
145 class TextToSpeechManager {
146 public:
147 	enum Action {
148 		INTERRUPT,
149 		INTERRUPT_NO_REPEAT,
150 		QUEUE,
151 		QUEUE_NO_REPEAT,
152 		DROP
153 	};
154 	/**
155 	 * The constructor sets the language to the translation manager language if
156 	 * USE_TRANSLATION is defined, or english when it isn't defined. It sets the rate,
157 	 * pitch and volume to their middle values.
158 	 */
159 	TextToSpeechManager();
~TextToSpeechManager()160 	virtual ~TextToSpeechManager() {}
161 
162 	/**
163 	 * Says the given string
164 	 *
165 	 * @param str The string to say
166 	 * @param action What to do if another string is just being said.
167 	 * Possible actions are:
168 	 *		INTERRUPT - interrupts the current speech
169 	 *		INTERRUPT_NO_REPEAT - interrupts the speech (deletes the whole queue),
170 	 *			if the str is the same as the string currently being said,
171 	 *			it lets the current string finish.
172 	 *		QUEUE - queues the speech
173 	 *		QUEUE_NO_REPEAT - queues the speech only if the str is different than
174 	 *			the last string in the queue (or the string, that is currently
175 	 *			being said if the queue is empty)
176 	 *		DROP - does nothing if there is anything being said at the moment
177 	 */
say(const U32String & str,Action action)178 	virtual bool say(const U32String &str, Action action) { return false; }
179 
180 	/**
181 	 * Says the given string, but strings can have a custom charset here.
182 	 * It will convert to UTF-32 before passing along to the intended method.
183 	 */
184 	bool say(const String &str, Action action, CodePage charset = kUtf8) {
185 		U32String textToSpeak(str, charset);
186 		return say(textToSpeak, action);
187 	}
188 
189 	/**
190 	 * Interrupts what's being said and says the given string
191 	 *
192 	 * @param str The string to say
193 	 */
say(const U32String & str)194 	bool say(const U32String &str) { return say(str, INTERRUPT_NO_REPEAT); }
195 
196 	/**
197 	 * Interrupts what's being said and says the given string
198 	 *
199 	 * @param str The string to say
200 	 * @param charset The encoding of the string. It will be converted to UTF-32.
201 	 *	              It will use UTF-8 by default.
202 	 */
203 	bool say(const String &str, CodePage charset = kUtf8) {
204 		return say(str, INTERRUPT_NO_REPEAT, charset);
205 	}
206 
207 	/**
208 	 * Stops the speech
209 	 */
stop()210 	virtual bool stop() { return false; }
211 
212 	/**
213 	 * Pauses the speech
214 	 */
pause()215 	virtual bool pause() { return false; }
216 
217 	/**
218 	 * Resumes the speech
219 	 *
220 	 * @note On linux, the speech resumes from the begining of the last speech being
221 	 * said, when pause() was called. On other platforms the speech resumes from
222 	 * exactly where it was paused();
223 	 */
resume()224 	virtual bool resume() { return false; }
225 
226 	/**
227 	 * Returns true, if the TTS engine is speaking
228 	 */
isSpeaking()229 	virtual bool isSpeaking() { return false; }
230 
231 	/**
232 	 * Returns true, if the TTS engine is paused
233 	 */
isPaused()234 	virtual bool isPaused() { return false; }
235 
236 	/**
237 	 * Returns true, if the TTS engine is ready to speak (isn't speaking and isn't paused)
238 	 */
isReady()239 	virtual bool isReady() { return false; }
240 
241 	/**
242 	 * Sets a voice to be used by the TTS.
243 	 *
244 	 * @param index The index of the voice inside the _ttsState->_availableVoices array
245 	 */
setVoice(unsigned index)246 	virtual void setVoice(unsigned index) {}
247 
248 	/**
249 	 * Returns the voice, that is used right now
250 	 */
251 	TTSVoice getVoice();
252 
253 	/**
254 	 * Sets the speech rate
255 	 *
256 	 * @param rate Integer between -100 (slowest) and 100 (fastest), 0 is the default
257 	 */
setRate(int rate)258 	virtual void setRate(int rate) { _ttsState->_rate = rate; }
259 
260 	/**
261 	 * Returns the current speech rate
262 	 */
getRate()263 	int getRate() { return _ttsState->_rate; }
264 
265 	/**
266 	 * Sets the pitch
267 	 *
268 	 * @param pitch Integer between -100 (lowest) and 100 (highest), 0 is the default
269 	 */
setPitch(int pitch)270 	virtual void setPitch(int pitch) { _ttsState->_pitch = pitch; }
271 
272 	/**
273 	 * Returns current speech pitch
274 	 */
getPitch()275 	int getPitch() { return _ttsState->_pitch; }
276 
277 	/**
278 	 * Sets the speech volume
279 	 *
280 	 * @param volume Volume as a percentage (0 means muted, 100 means as loud as possible)
281 	 */
setVolume(unsigned volume)282 	virtual void setVolume(unsigned volume) { _ttsState->_volume = volume; }
283 
284 	/**
285 	 * Returns the current voice volume
286 	 */
getVolume()287 	int getVolume() { return _ttsState->_volume; }
288 
289 	/**
290 	 * Sets the speech language
291 	 *
292 	 * @param language The language identifier as defined by ISO 639-1
293 	 *
294 	 * @note After using this method, it is probably a good idea to use setVoice,
295 	 * because voices are usually language specific and so it is set to some platform
296 	 * specific default after switching languages.
297 	 */
298 	virtual void setLanguage(String language);
299 
300 	/**
301 	 * Returns the current speech language
302 	 */
getLanguage()303 	String getLanguage() { return _ttsState->_language; }
304 
305 	/**
306 	 * Returns array of available voices for the current language
307 	 */
getVoicesArray()308 	Array<TTSVoice> getVoicesArray() { return _ttsState->_availableVoices; }
309 
310 	/**
311 	 * Returns array of indices of voices from the _availableVoices array, which
312 	 * have the needed gender.
313 	 *
314 	 * @param gender Gender, which indices should be returned
315 	 *
316 	 * @return Array of indices into _availableVoices
317 	 */
318 	Array<int> getVoiceIndicesByGender (TTSVoice::Gender gender);
319 
320 	/**
321 	 * returns the index for the default voice.
322 	 */
getDefaultVoice()323 	virtual int getDefaultVoice() { return 0; }
324 
325 	/**
326 	 * Pushes the current state of the TTS
327 	 */
328 	void pushState();
329 
330 	/**
331 	 * Pops the TTS state
332 	 */
333 	bool popState();
334 
335 	/**
336 	 * Frees the _data field from TTSVoice
337 	 */
freeVoiceData(void * data)338 	virtual void freeVoiceData(void *data) {}
339 
340 protected:
341 	TTSState *_ttsState;
342 
343 	void clearState();
updateVoices()344 	virtual void updateVoices() {};
345 };
346 
347 /** @} */
348 
349 } // End of namespace Common
350 
351 #endif // BACKENDS_TEXT_TO_SPEECH_ABSTRACT_H
352