Tizen 2.1 base
[platform/framework/native/speech.git] / src / tts / FUixSpeech_TextToSpeechImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file    FUixSpeech_TextToSpeechImpl.h
20  * @brief   This is the implementation file for the _TextToSpeechImpl class.
21  *
22  * This files contains implementation of the _TextToSpeechImpl class.
23  */
24
25 #include <new>
26 #include <FBaseColIList.h>
27 #include <FBaseColArrayList.h>
28 #include <FBaseString.h>
29 #include <FBaseUtilStringTokenizer.h>
30 #include <FLclLocale.h>
31 #include <FUixSpeechTextToSpeech.h>
32 #include <FBaseSysLog.h>
33 #include <FBase_StringConverter.h>
34 #include <FUixSpeech_TextToSpeechImpl.h>
35
36 using namespace Tizen::Base;
37 using namespace Tizen::Base::Collection;
38 using namespace Tizen::Locales;
39
40 #ifdef __cplusplus
41 extern "C"
42 {
43 #endif
44
45 _OSP_EXPORT_ Tizen::Uix::Speech::_ITextToSpeech*
46 _GetInstance_FUixTextToSpeechImpl(void)
47 {
48     return new (std::nothrow) Tizen::Uix::Speech::_TextToSpeechImpl();
49 }
50
51 _OSP_EXPORT_ void
52 _ReleaseInstance_FUixTextToSpeechImpl(Tizen::Uix::Speech::_ITextToSpeech* pInstacne)
53 {
54     delete pInstacne;
55 }
56
57 #ifdef __cplusplus
58 }
59 #endif
60
61 namespace Tizen { namespace Uix { namespace Speech
62 {
63 void
64 _TextToSpeechImpl::TtsStateChangedReceiver(tts_h ttsHandle, tts_state_e previousState, tts_state_e currentState, void* pTtsInstance)
65 {
66     SysLog(NID_UIX_SPEECH, "The current state is changed to '%s' from '%s'.",
67                 GetEngineStateMessage(currentState), GetEngineStateMessage(previousState));
68
69         _TextToSpeechImpl* pInstance = static_cast<_TextToSpeechImpl*>(pTtsInstance);
70     ITextToSpeechEventListener* pListener = pInstance->__pTextToSpeechListener;
71
72     if ((previousState == TTS_STATE_CREATED) && (currentState == TTS_STATE_READY))
73     {
74         char *pDefaultLang = null;
75         tts_voice_type_e defaultVoiceType;
76
77         int ttsError = tts_get_default_voice(ttsHandle, &pDefaultLang, &defaultVoiceType);
78         if (ttsError == TTS_ERROR_NONE)
79         {
80             SysLog(NID_UIX_SPEECH, "The default language is '%s', and voice type is '%d'." , pDefaultLang, defaultVoiceType);
81             const Locale* pDefaultLocale = ConvertEngineLocaleToOspN(pDefaultLang);
82             *pInstance->__pCurrentLocale = *pDefaultLocale;
83
84             delete pDefaultLocale;
85             free(pDefaultLang);
86         }
87
88         ttsError = tts_foreach_supported_voices(ttsHandle, TtsSupportedLocaleListGetter, (void*)(pInstance->__pSupportedLocaleList));
89         SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to get supported voices", GetEngineErrorMessage(ttsError));
90
91         pInstance->__isInitialized = true;
92         pInstance->__currentStatus = TEXT_TO_SPEECH_STATUS_READY;
93
94         pListener->OnTextToSpeechInitialized();
95         pListener->OnTextToSpeechStatusChanged(TEXT_TO_SPEECH_STATUS_READY);
96     }
97     else if ((previousState == TTS_STATE_READY || previousState == TTS_STATE_PAUSED) && (currentState == TTS_STATE_PLAYING))
98     {
99         pInstance->__currentStatus = TEXT_TO_SPEECH_STATUS_PLAYING;
100         pListener->OnTextToSpeechStatusChanged(TEXT_TO_SPEECH_STATUS_PLAYING);
101     }
102     else if ((previousState == TTS_STATE_PLAYING) && (currentState == TTS_STATE_PAUSED))
103     {
104         pInstance->__currentStatus = TEXT_TO_SPEECH_STATUS_PAUSED;
105         pListener->OnTextToSpeechStatusChanged(TEXT_TO_SPEECH_STATUS_PAUSED);
106     }
107     else if ((previousState == TTS_STATE_PLAYING || previousState == TTS_STATE_PAUSED) && (currentState == TTS_STATE_READY))
108     {
109         pInstance->__currentStatus = TEXT_TO_SPEECH_STATUS_READY;
110         pListener->OnTextToSpeechStatusChanged(TEXT_TO_SPEECH_STATUS_READY);
111     }
112     else
113     {
114         SysLog(NID_UIX_SPEECH, "The unknown state is changed to '%s' from '%s'.",
115                         GetEngineStateMessage(currentState), GetEngineStateMessage(previousState));
116     }
117 }
118
119 void
120 _TextToSpeechImpl::TtsStartedReceiver(tts_h ttsHandle, int utteranceId, void* pListener)
121 {
122         SysLog(NID_UIX_SPEECH, "The utterance(%d) has started.", utteranceId);
123 }
124
125 void
126 _TextToSpeechImpl::TtsCompletedReceiver(tts_h ttsHandle, int utteranceId, void* pTtsInstance)
127 {
128     _TextToSpeechImpl* pInstance = static_cast<_TextToSpeechImpl*>(pTtsInstance);
129     ITextToSpeechEventListener* pListener = pInstance->__pTextToSpeechListener;
130
131     SysLog(NID_UIX_SPEECH, "The utterance id is '%d' and the request count is '%d'.",
132                 utteranceId, pInstance->__appendRequsetCount);
133
134     if ((--(pInstance->__appendRequsetCount) == 0) || (pInstance->__currentRequestMode == TEXT_TO_SPEECH_REQUEST_MODE_REPLACE))
135     {
136         SysLog(NID_UIX_SPEECH, "Automatically, Stop() method was called.");
137         int ttsError = tts_stop(ttsHandle);
138         SysTryReturnVoidResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_SYSTEM,
139                         "[%s] Failed to stop.", GetEngineErrorMessage(ttsError));
140     }
141
142         static_cast <ITextToSpeechEventListener*>(pListener)->OnTextToSpeechCompleted();
143 }
144
145 void
146 _TextToSpeechImpl::TtsErrorReceiver(tts_h ttsHandle, int ttsUtteranceId, tts_error_e error, void* pListener)
147 {
148         SysLog(NID_UIX_SPEECH, "[%s] Error occurred.", GetEngineErrorMessage(error));
149
150         TextToSpeechError ttsError;
151
152         switch (error)
153         {
154         case TTS_ERROR_OUT_OF_MEMORY:
155         ttsError = TEXT_TO_SPEECH_ERROR_OUT_OF_MEMORY;
156         break;
157         case TTS_ERROR_IO_ERROR:
158             ttsError = TEXT_TO_SPEECH_ERROR_IO_ERROR;
159         break;
160         case TTS_ERROR_OUT_OF_NETWORK:
161             ttsError = TEXT_TO_SPEECH_ERROR_NETWORK_ERROR;
162             break;
163         case TTS_ERROR_ENGINE_NOT_FOUND:
164             ttsError = TEXT_TO_SPEECH_ERROR_UNSUPPORTED_SERVICE;
165         break;
166         case TTS_ERROR_TIMED_OUT:
167             ttsError = TEXT_TO_SPEECH_ERROR_TIME_OUT;
168         break;
169         default:
170             ttsError = TEXT_TO_SPEECH_ERROR_SYSTEM_ERROR;
171         break;
172
173         }
174         static_cast <ITextToSpeechEventListener*>(pListener)->OnTextToSpeechErrorOccurred(ttsError);
175 }
176
177 bool
178 _TextToSpeechImpl::TtsSupportedLocaleListGetter(tts_h ttsHandle, const char* pLanguage, tts_voice_type_e voiceType, void* pLocaleList)
179 {
180         SysLog(NID_UIX_SPEECH, "The language is '%s' and the voice type is '%s'.",
181                         pLanguage, GetEngineVoiceTypeMessage(voiceType));
182
183         const Locale* pLocale = ConvertEngineLocaleToOspN(String(pLanguage));
184         if (pLocale == null)
185         {
186                 static_cast <ArrayList*>(pLocaleList)->RemoveAll(true);
187                 return false; // escape call back loop
188         }
189
190         if (pLocale->GetLanguageCode() == LANGUAGE_INVALID)
191         {
192             SysLog(NID_UIX_SPEECH, "The '%s' language is not supported.", pLanguage);
193             delete pLocale;
194         }
195         else
196         {
197         result r = static_cast<ArrayList*>(pLocaleList)->Add(*pLocale);
198         if (IsFailed(r))
199         {
200             static_cast<ArrayList*>(pLocaleList)->RemoveAll(true);
201             return false;   // escape call back loop
202         }
203         }
204
205         return true; // continue call back loop
206 }
207
208 _TextToSpeechImpl::_TextToSpeechImpl(void)
209         : __ttsHandle(null)
210         , __isInitialized(false)
211     , __currentRequestMode(TEXT_TO_SPEECH_REQUEST_MODE_APPEND)
212     , __appendRequsetCount(0)
213     , __pCurrentLocale(null)
214     , __pSupportedLocaleList(null)
215     , __pTextToSpeechListener(null)
216     , __currentStatus(TEXT_TO_SPEECH_STATUS_NONE)
217     , __speechRate(TEXT_TO_SPEECH_SPEECH_RATE_SYSTEM_SETTING)
218 {
219 }
220
221 _TextToSpeechImpl::~_TextToSpeechImpl(void)
222 {
223     tts_state_e ttsState = TTS_STATE_READY;
224
225     int ttsError = tts_get_state(__ttsHandle, &ttsState);
226     SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to get the current state.", GetEngineErrorMessage(ttsError));
227
228     if (ttsState == TTS_STATE_PLAYING || ttsState == TTS_STATE_PAUSED)
229     {
230         ttsError = tts_stop(__ttsHandle);
231         SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to stop.", GetEngineErrorMessage(ttsError));
232     }
233
234     if (__isInitialized)
235     {
236         ttsError = tts_unprepare(__ttsHandle);
237         SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to unprepare.", GetEngineErrorMessage(ttsError));
238
239         ttsError = tts_unset_utterance_completed_cb(__ttsHandle);
240         SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to unset the utterance completed callback.", GetEngineErrorMessage(ttsError));
241
242         ttsError = tts_unset_utterance_started_cb(__ttsHandle);
243         SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to unset the utterance started callback.", GetEngineErrorMessage(ttsError));
244
245         ttsError = tts_unset_state_changed_cb(__ttsHandle);
246         SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to unset the state changed callback.", GetEngineErrorMessage(ttsError));
247
248         ttsError = tts_unset_error_cb(__ttsHandle);
249         SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to unset the error callback.", GetEngineErrorMessage(ttsError));
250     }
251
252     ttsError = tts_destroy(__ttsHandle);
253     SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to destroy.", GetEngineErrorMessage(ttsError));
254
255     delete __pCurrentLocale;
256
257     if (__pSupportedLocaleList != null)
258     {
259         __pSupportedLocaleList->RemoveAll(true);
260         delete __pSupportedLocaleList;
261     }
262 }
263
264 result
265 _TextToSpeechImpl::Construct(ITextToSpeechEventListener& listener)
266 {
267         int ttsError = tts_create(&__ttsHandle);
268         SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to create", GetEngineErrorMessage(ttsError));
269         SysTryReturnResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to create.");
270
271     Locale *pLocale = new (std::nothrow) Locale(LANGUAGE_INVALID, COUNTRY_INVALID);
272     SysTryReturnResult(NID_UIX_SPEECH, pLocale != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
273
274     ArrayList* pLocaleList = new (std::nothrow) ArrayList();
275     SysTryReturnResult(NID_UIX_SPEECH, pLocaleList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
276
277     result r = pLocaleList->Construct();
278     SysTryReturnResult(NID_UIX_SPEECH, r == E_SUCCESS, E_OUT_OF_MEMORY, "The memory is insufficient.");
279
280     __pCurrentLocale = pLocale;
281     __pSupportedLocaleList = pLocaleList;
282         __pTextToSpeechListener = &listener;
283
284         return E_SUCCESS;
285 }
286
287 result
288 _TextToSpeechImpl::Initialize(void)
289 {
290     SysAssertf(__isInitialized != true,
291                 "Already calling Initialize() twice or more on a same instance is not allowed for this class.");
292
293     int ttsError = tts_set_error_cb(__ttsHandle, TtsErrorReceiver, (void*)(__pTextToSpeechListener));
294     SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to set the error callback.", GetEngineErrorMessage(ttsError));
295     SysTryReturnResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "The memory is insufficient.");
296
297     ttsError = tts_set_state_changed_cb(__ttsHandle, TtsStateChangedReceiver, (void*)(this));
298     SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to set the state changed callback.", GetEngineErrorMessage(ttsError));
299     SysTryReturnResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "The memory is insufficient.");
300
301     ttsError = tts_set_utterance_started_cb(__ttsHandle, TtsStartedReceiver, (void*)(__pTextToSpeechListener));
302     SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to set the utterance started callback.", GetEngineErrorMessage(ttsError));
303     SysTryReturnResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "The memory is insufficient.");
304
305     ttsError = tts_set_utterance_completed_cb(__ttsHandle, TtsCompletedReceiver, (void*)(this));
306     SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to set the utterance completed callback.", GetEngineErrorMessage(ttsError));
307     SysTryReturnResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "The memory is insufficient.");
308
309     ttsError = tts_prepare(__ttsHandle);
310     SysTryLog(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, "[%s] Failed to prepare", GetEngineErrorMessage(ttsError));
311     SysTryReturnResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "The memory is insufficient.");
312
313     return E_SUCCESS;
314 }
315
316 result
317 _TextToSpeechImpl::Speak(const String& text, TextToSpeechRequestMode requestMode)
318 {
319     SysTryReturnResult(NID_UIX_SPEECH, __isInitialized, E_INVALID_STATE,
320             "Not yet initialized! This method should be called after receiving OnTextToSpeechInitialized() event.");
321
322     result r = E_SUCCESS;
323     tts_state_e ttsState = TTS_STATE_READY;
324
325     int ttsError = tts_get_state(__ttsHandle, &ttsState);
326     SysTryReturnResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to get the current state.");
327
328     const char* pLanguage = ConvertOspLocaleToEngineN(*__pCurrentLocale);
329     SysTryReturnResult(NID_UIX_SPEECH, pLanguage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
330
331     if (requestMode == TEXT_TO_SPEECH_REQUEST_MODE_REPLACE && ttsState != TTS_STATE_READY)
332     {
333         Stop();
334     }
335
336     const char* pTextN = _StringConverter::CopyToCharArrayN(text);
337     tts_speed_e ttsSpeed = ConvertOspSpeedToEngine(__speechRate);
338     int ttsUtteranceId = 0;
339
340     SysTryCatchLabel(NID_UIX_SPEECH, pTextN != null, r = E_OUT_OF_MEMORY, CATCH_LANG, E_OUT_OF_MEMORY,
341                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
342
343     ttsError = tts_add_text(__ttsHandle, pTextN, pLanguage, TTS_VOICE_TYPE_AUTO, ttsSpeed, &ttsUtteranceId);
344     SysTryCatch(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, r = E_OUT_OF_MEMORY, E_SYSTEM, "[E_SYSTEM] Failed to add a text.");
345
346     if (requestMode == TEXT_TO_SPEECH_REQUEST_MODE_REPLACE || __appendRequsetCount == 0)
347     {
348         __appendRequsetCount = 0;
349
350         ttsError = tts_play(__ttsHandle);
351         SysTryCatch(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, r = E_SYSTEM, E_SYSTEM, "[%s] Failed to play.", GetEngineErrorMessage(ttsError));
352     }
353
354     __appendRequsetCount++;
355     __currentRequestMode = requestMode;
356
357     if (__appendRequsetCount == 1)
358     {
359         __pTextToSpeechListener->OnTextToSpeechStatusChanged(TEXT_TO_SPEECH_STATUS_SYNTHESIZING);
360     }
361
362     SysLog(NID_UIX_SPEECH, "The utterance id is '%d', the request count is '%d' and the request mode is '%s'.",
363                 ttsUtteranceId, __appendRequsetCount, (requestMode == TEXT_TO_SPEECH_REQUEST_MODE_REPLACE ? "Replace" : "Append"));
364
365 CATCH:
366     delete[] pTextN;
367
368 CATCH_LANG:
369     delete[] pLanguage;
370
371     return r;
372 }
373
374 result
375 _TextToSpeechImpl::Stop(void)
376 {
377     SysTryReturnResult(NID_UIX_SPEECH, __isInitialized, E_INVALID_STATE,
378                 "Not yet initialized! This method should be called after receiving OnTextToSpeechInitialized() event.");
379
380     tts_state_e ttsState = TTS_STATE_READY;
381
382     int ttsError = tts_get_state(__ttsHandle, &ttsState);
383     SysTryReturnResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to get the current state.");
384     SysTryReturnResult(NID_UIX_SPEECH, ttsState != TTS_STATE_READY, E_INVALID_OPERATION,
385             "The TTS state should be TTS_STATUS_PLAYING or TTS_STATUS_PAUSED.");
386
387     ttsError = tts_stop(__ttsHandle);
388     SysTryReturnResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to stop.");
389     __appendRequsetCount = 0;
390
391     return E_SUCCESS;
392 }
393
394 result
395 _TextToSpeechImpl::Pause(void)
396 {
397     SysTryReturnResult(NID_UIX_SPEECH, __isInitialized, E_INVALID_STATE,
398                 "Not yet initialized! This method should be called after receiving OnTextToSpeechInitialized() event.")
399
400     tts_state_e ttsState = TTS_STATE_READY;
401
402     int ttsError = tts_get_state(__ttsHandle, &ttsState);
403     SysTryReturnResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to get the current state.");
404     SysTryReturnResult(NID_UIX_SPEECH, ttsState == TTS_STATE_PLAYING, E_INVALID_OPERATION, "The TTS state should be TTS_STATUS_PLAYING.");
405
406     ttsError = tts_pause(__ttsHandle);
407     SysTryReturnResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to pause.");
408
409     return E_SUCCESS;
410 }
411
412 result
413 _TextToSpeechImpl::Resume(void)
414 {
415     SysTryReturnResult(NID_UIX_SPEECH, __isInitialized, E_INVALID_STATE,
416                 "Not yet initialized! This method should be called after receiving OnTextToSpeechInitialized() event.");
417
418     tts_state_e ttsState = TTS_STATE_READY;
419
420     int ttsError = tts_get_state(__ttsHandle, &ttsState);
421     SysTryReturnResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to get the current state.");
422     SysTryReturnResult(NID_UIX_SPEECH, ttsState == TTS_STATE_PAUSED, E_INVALID_OPERATION, "The TTS state should be TTS_STATUS_PAUSED.");
423
424     ttsError = tts_play(__ttsHandle);
425     SysTryReturnResult(NID_UIX_SPEECH, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to resume.");
426
427     return E_SUCCESS;
428 }
429
430 result
431 _TextToSpeechImpl::SetLocale(const Locale& locale)
432 {
433     SysTryReturnResult(NID_UIX_SPEECH, __isInitialized, E_INVALID_STATE,
434             "Not yet initialized! This method should be called after receiving OnTextToSpeechInitialized() event.")
435     SysTryReturnResult(NID_UIX_SPEECH, __pSupportedLocaleList->Contains(locale), E_UNSUPPORTED_LOCALE, "This locale is not supported.");
436
437         *__pCurrentLocale = locale;
438         return E_SUCCESS;
439 }
440
441 Tizen::Locales::Locale
442 _TextToSpeechImpl::GetLocale(void) const
443 {
444         SysTryReturn(NID_UIX_SPEECH, __isInitialized, Locale(LANGUAGE_INVALID, COUNTRY_INVALID), E_INVALID_STATE,
445             "[E_INVALID_STATE] Not yet initialized! This method should be called after receiving OnTextToSpeechInitialized() event.");
446
447     SetLastResult(E_SUCCESS);
448     return *__pCurrentLocale;
449 }
450
451 const Tizen::Base::Collection::IList*
452 _TextToSpeechImpl::GetSupportedLocales(void) const
453 {
454         SysTryReturn(NID_UIX_SPEECH, __isInitialized, null, E_INVALID_STATE,
455             "[E_INVALID_STATE] Not yet initialized! This method should be called after receiving OnTextToSpeechInitialized() event.");
456
457     SetLastResult(E_SUCCESS);
458     return __pSupportedLocaleList->GetCount() > 0 ? __pSupportedLocaleList : null;
459 }
460
461 bool
462 _TextToSpeechImpl::IsLocaleSupported(const Tizen::Locales::Locale& locale) const
463 {
464         SysTryReturn(NID_UIX_SPEECH, __isInitialized, false, E_INVALID_STATE,
465             "[E_INVALID_STATE] Not yet initialized! This method should be called after receiving OnTextToSpeechInitialized() event.");
466
467     SetLastResult(E_SUCCESS);
468     return __pSupportedLocaleList->Contains(locale);
469 }
470
471 result
472 _TextToSpeechImpl::SetSpeechRate(TextToSpeechSpeechRate speechRate)
473 {
474         SysTryReturnResult(NID_UIX_SPEECH, __isInitialized, E_INVALID_STATE,
475             "Not yet initialized! This method should be called after receiving OnTextToSpeechInitialized() event.");
476
477         __speechRate = speechRate;
478
479         return E_SUCCESS;
480 }
481
482 TextToSpeechStatus
483 _TextToSpeechImpl::GetCurrentStatus(void) const
484 {
485         SysTryReturn(NID_UIX_SPEECH, __isInitialized, TEXT_TO_SPEECH_STATUS_NONE, E_INVALID_STATE,
486             "[E_INVALID_STATE] Not yet initialized! This method should be called after receiving OnTextToSpeechInitialized() event.");
487
488     SetLastResult(E_SUCCESS);
489     return __currentStatus;
490 }
491
492 _TextToSpeechImpl*
493 _TextToSpeechImpl::GetInstance(TextToSpeech& textToSpeech)
494 {
495     return textToSpeech.__pTextToSpeechImpl;
496 }
497
498 const _TextToSpeechImpl*
499 _TextToSpeechImpl::GetInstance(const TextToSpeech& textToSpeech)
500 {
501     return textToSpeech.__pTextToSpeechImpl;
502 }
503
504 const char*
505 _TextToSpeechImpl::GetEngineErrorMessage(const int errorType)
506 {
507     switch (errorType)
508     {
509     case TTS_ERROR_NONE:
510         return "TTS_ERROR_NONE";
511
512     case TTS_ERROR_OUT_OF_MEMORY:
513         return "TTS_ERROR_OUT_OF_MEMORY";
514
515     case TTS_ERROR_IO_ERROR:
516         return "TTS_ERROR_IO_ERROR";
517
518     case TTS_ERROR_INVALID_PARAMETER:
519         return "TTS_ERROR_INVALID_PARAMETER";
520
521     case TTS_ERROR_INVALID_STATE:
522         return "TTS_ERROR_INVALID_STATE";
523
524     case TTS_ERROR_INVALID_VOICE:
525         return "TTS_ERROR_INVALID_VOICE";
526
527     case TTS_ERROR_ENGINE_NOT_FOUND:
528         return "TTS_ERROR_ENGINE_NOT_FOUND";
529
530     case TTS_ERROR_TIMED_OUT:
531         return "TTS_ERROR_TIMED_OUT";
532
533     case TTS_ERROR_OPERATION_FAILED:
534         return "TTS_ERROR_OPERATION_FAILED";
535
536     default:
537         return "TTS_ERROR_UNKNOWN_ERROR";
538     }
539 }
540
541 const char*
542 _TextToSpeechImpl::GetEngineStateMessage(const tts_state_e state)
543 {
544     switch (state)
545     {
546         case TTS_STATE_CREATED:
547                 return "CREATED";
548
549     case TTS_STATE_READY:
550         return "READY";
551
552     case TTS_STATE_PLAYING:
553         return "PLAYING";
554
555     case TTS_STATE_PAUSED:
556         return "PAUSED";
557
558     default:
559         return "UNKNOWN";
560     }
561 }
562
563 const char*
564 _TextToSpeechImpl::GetEngineVoiceTypeMessage(const tts_voice_type_e voiceType)
565 {
566     switch (voiceType)
567     {
568     case TTS_VOICE_TYPE_AUTO:
569         return "TTS_VOICE_TYPE_AUTO";
570
571     case TTS_VOICE_TYPE_MALE:
572         return "TTS_VOICE_TYPE_MALE";
573
574     case TTS_VOICE_TYPE_FEMALE:
575         return "TTS_VOICE_TYPE_FEMALE";
576
577     case TTS_VOICE_TYPE_CHILD:
578         return "TTS_VOICE_TYPE_CHILD";
579
580     case TTS_VOICE_TYPE_USER1:
581         return "TTS_VOICE_TYPE_USER1";
582
583     case TTS_VOICE_TYPE_USER2:
584         return "TTS_VOICE_TYPE_USER2";
585
586     case TTS_VOICE_TYPE_USER3:
587         return "TTS_VOICE_TYPE_USER3";
588
589     default:
590         return "TTS_VOICE_TYPE_UNKNOWN";
591     }
592 }
593
594 tts_speed_e
595 _TextToSpeechImpl::ConvertOspSpeedToEngine(const TextToSpeechSpeechRate& speechRate) const
596 {
597     switch (speechRate)
598     {
599     case TEXT_TO_SPEECH_SPEECH_RATE_SYSTEM_SETTING:
600         return TTS_SPEED_AUTO;
601
602     case TEXT_TO_SPEECH_SPEECH_RATE_VERY_SLOW:
603         return TTS_SPEED_VERY_SLOW;
604
605     case TEXT_TO_SPEECH_SPEECH_RATE_SLOW:
606         return TTS_SPEED_SLOW;
607
608     case TEXT_TO_SPEECH_SPEECH_RATE_NORMAL:
609         return TTS_SPEED_NORMAL;
610
611     case TEXT_TO_SPEECH_SPEECH_RATE_FAST:
612         return TTS_SPEED_FAST;
613
614     case TEXT_TO_SPEECH_SPEECH_RATE_VERY_FAST:
615         return TTS_SPEED_VERY_FAST;
616
617     default:
618         return TTS_SPEED_AUTO;
619     }
620 }
621
622 const char*
623 _TextToSpeechImpl::ConvertOspLocaleToEngineN(const Tizen::Locales::Locale& locale)
624 {
625     String strLanguageCode = Locale::LanguageCodeToTwoLetterLanguageCodeString(locale.GetLanguageCode());
626     String strCountryCode = Locale::CountryCodeToString(locale.GetCountryCode());
627
628     String strLanguage = strLanguageCode + L"_" + strCountryCode;
629
630     return _StringConverter::CopyToCharArrayN(strLanguage);
631 }
632
633 const Tizen::Locales::Locale*
634 _TextToSpeechImpl::ConvertEngineLocaleToOspN(const Tizen::Base::String& strSource)
635 {
636     String strDelim(L"_");
637     String strLanguageCode;
638     String strCountryCode;
639
640     LanguageCode languageCode = LANGUAGE_INVALID;
641     CountryCode countryCode = COUNTRY_INVALID;
642
643     Utility::StringTokenizer toknizer(strSource, strDelim);
644     if (toknizer.GetTokenCount() == 2)
645     {
646         toknizer.GetNextToken(strLanguageCode);
647         toknizer.GetNextToken(strCountryCode);
648
649         languageCode = Locale::TwoLetterLanguageCodeStringToLanguageCode(strLanguageCode);
650         countryCode = Locale::StringToCountryCode(strCountryCode);
651     }
652
653     return new (std::nothrow) Locale(languageCode, countryCode);
654 }
655
656 } } } // Tizen::Uix::Speech