2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0/
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.
18 #include <FBaseColArrayList.h>
19 #include <FBaseString.h>
20 #include <FBaseSysLog.h>
21 #include <FBaseUtilStringTokenizer.h>
22 #include <FLclLocale.h>
23 #include <FBase_StringConverter.h>
24 #include "FUi_AccessibilityTtsPlayer.h"
25 #include "FUi_AccessibilityManager.h"
27 using namespace Tizen::Base;
28 using namespace Tizen::Base::Collection;
29 using namespace Tizen::Locales;
31 namespace Tizen { namespace Ui {
33 _AccessibilityTtsPlayer::_AccessibilityTtsPlayer(_AccessibilityManager& manager)
34 : __initialized(false)
38 , __speed(TTS_SPEED_AUTO)
39 , __status(ACCESSIBILITY_SCREEN_READER_STATUS_ERROR)
41 , __pCurrentLocale(null)
42 , __pSupportedLocaleList(null)
43 , __pManager(&manager)
47 _AccessibilityTtsPlayer::~_AccessibilityTtsPlayer(void)
50 delete __pCurrentLocale;
52 if (__pSupportedLocaleList != null)
54 __pSupportedLocaleList->RemoveAll(true);
55 delete __pSupportedLocaleList;
60 _AccessibilityTtsPlayer::Construct(void)
62 Locale *pLocale = new (std::nothrow) Locale(LANGUAGE_INVALID, COUNTRY_INVALID);
63 SysTryReturnResult(NID_UI, pLocale != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
65 ArrayList* pLocaleList = new (std::nothrow) ArrayList();
66 SysTryReturnResult(NID_UI, pLocaleList != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
68 result r = pLocaleList->Construct();
69 SysTryReturnResult(NID_UI, r == E_SUCCESS, E_OUT_OF_MEMORY, "The memory is insufficient.");
71 __pCurrentLocale = pLocale;
72 __pSupportedLocaleList = pLocaleList;
78 _AccessibilityTtsPlayer::Activate(void)
82 SysLog(NID_UI, "TTS player was already activated.");
86 int ttsError = tts_create(&__ttsHandle);
87 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to create.");
89 ttsError = tts_set_error_cb(__ttsHandle, TtsErrorReceiver, (void*)(this));
90 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
92 ttsError = tts_set_state_changed_cb(__ttsHandle, TtsStateChangedReceiver, (void*)(this));
93 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
95 ttsError = tts_set_utterance_started_cb(__ttsHandle, TtsStartedReceiver, (void*)(this));
96 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
98 ttsError = tts_set_utterance_completed_cb(__ttsHandle, TtsCompletedReceiver, (void*)(this));
99 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
101 ttsError = tts_prepare(__ttsHandle);
102 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
109 _AccessibilityTtsPlayer::GetEngineStateMessage(const tts_state_e state)
113 case TTS_STATE_CREATED:
116 case TTS_STATE_READY:
119 case TTS_STATE_PLAYING:
122 case TTS_STATE_PAUSED:
131 _AccessibilityTtsPlayer::GetEngineErrorMessage(const int errorType)
136 return "TTS_ERROR_NONE";
138 case TTS_ERROR_OUT_OF_MEMORY:
139 return "TTS_ERROR_OUT_OF_MEMORY";
141 case TTS_ERROR_IO_ERROR:
142 return "TTS_ERROR_IO_ERROR";
144 case TTS_ERROR_INVALID_PARAMETER:
145 return "TTS_ERROR_INVALID_PARAMETER";
147 case TTS_ERROR_INVALID_STATE:
148 return "TTS_ERROR_INVALID_STATE";
150 case TTS_ERROR_INVALID_VOICE:
151 return "TTS_ERROR_INVALID_VOICE";
153 case TTS_ERROR_ENGINE_NOT_FOUND:
154 return "TTS_ERROR_ENGINE_NOT_FOUND";
156 case TTS_ERROR_TIMED_OUT:
157 return "TTS_ERROR_TIMED_OUT";
159 case TTS_ERROR_OPERATION_FAILED:
160 return "TTS_ERROR_OPERATION_FAILED";
163 return "TTS_ERROR_UNKNOWN_ERROR";
168 _AccessibilityTtsPlayer::TtsStateChangedReceiver(tts_h ttsHandle, tts_state_e previousState, tts_state_e currentState, void* pTtsInstance)
170 SysLog(NID_UI, "[Accessibility TTS] [%s] ---> [%s]", GetEngineStateMessage(previousState), GetEngineStateMessage(currentState));
172 if ((previousState == TTS_STATE_CREATED) && (currentState == TTS_STATE_READY))
174 char *pDefaultLang = null;
175 tts_voice_type_e defaultVoiceType;
177 int ttsError = tts_get_default_voice(ttsHandle, &pDefaultLang, &defaultVoiceType);
178 if (ttsError == TTS_ERROR_NONE)
180 SysLog(NID_UI, "Default language[%s] and voice[%d]", pDefaultLang, defaultVoiceType);
181 const Locale* pDefaultLocale = ConvertEngineLocaleToNativeN(pDefaultLang);
184 delete static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->__pCurrentLocale;
185 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->__pCurrentLocale = const_cast<Locale*>(pDefaultLocale);
190 ttsError = tts_foreach_supported_voices(ttsHandle, TtsSupportedLocaleListGetter, (void*)(static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->__pSupportedLocaleList));
191 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to get supported voices", GetEngineErrorMessage(ttsError));
193 tts_set_mode(ttsHandle, TTS_MODE_SCREEN_READER);
194 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->__initialized = true;
195 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->OnStatusChanged(ACCESSIBILITY_SCREEN_READER_STATUS_READY);
197 else if ((previousState == TTS_STATE_READY || previousState == TTS_STATE_PAUSED) && (currentState == TTS_STATE_PLAYING))
199 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->OnStatusChanged(ACCESSIBILITY_SCREEN_READER_STATUS_PLAYING);
201 else if ((previousState == TTS_STATE_PLAYING) && (currentState == TTS_STATE_PAUSED))
203 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->OnStatusChanged(ACCESSIBILITY_SCREEN_READER_STATUS_PAUSE);
205 else if ((previousState == TTS_STATE_PLAYING || previousState == TTS_STATE_PAUSED) && (currentState == TTS_STATE_READY))
207 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->OnStatusChanged(ACCESSIBILITY_SCREEN_READER_STATUS_READY);
211 SysLog(NID_UI, "[CB] Unknown state. / [%s] ---> [%s]",
212 GetEngineStateMessage(previousState), GetEngineStateMessage(currentState));
216 _AccessibilityTtsPlayer::TtsStartedReceiver(tts_h ttsHandle, int utteranceId, void* pListener)
218 SysLog(NID_UI, "Accessibility TTS reader is started", utteranceId);
221 _AccessibilityTtsPlayer::TtsCompletedReceiver(tts_h ttsHandle, int utteranceId, void* pTtsInstance)
223 int ttsError = tts_stop(ttsHandle);
224 SysTryReturnVoidResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM,
225 "[CB] Failed to stop, error[%s]", GetEngineErrorMessage(ttsError));
226 _AccessibilityTtsPlayer* pPlayer = static_cast<_AccessibilityTtsPlayer*>(pTtsInstance);
227 pPlayer->SetStatus(ACCESSIBILITY_SCREEN_READER_STATUS_READY);
228 pPlayer->__pManager->OnFinishReading(pPlayer->__grammar);
231 _AccessibilityTtsPlayer::TtsErrorReceiver(tts_h ttsHandle, int ttsUtteranceId, tts_error_e error, void* pTtsInstance)
233 Tizen::Base::String errorMessage =L"";
236 case TTS_ERROR_OUT_OF_MEMORY:
237 errorMessage = L"TEXT_TO_SPEECH_ERROR_OUT_OF_MEMORY";
239 case TTS_ERROR_IO_ERROR:
240 errorMessage = L"TEXT_TO_SPEECH_ERROR_IO_ERROR";
242 case TTS_ERROR_OUT_OF_NETWORK:
243 errorMessage = L"TEXT_TO_SPEECH_ERROR_NETWORK_ERROR";
245 case TTS_ERROR_ENGINE_NOT_FOUND:
246 errorMessage = L"TEXT_TO_SPEECH_ERROR_UNSUPPORTED_SERVICE";
248 case TTS_ERROR_TIMED_OUT:
249 errorMessage = L"TEXT_TO_SPEECH_ERROR_TIME_OUT";
252 errorMessage = L"TEXT_TO_SPEECH_ERROR_SYSTEM_ERROR";
255 static_cast<_AccessibilityTtsPlayer*>(pTtsInstance)->OnErrorOccurred(errorMessage);
258 _AccessibilityTtsPlayer::TtsSupportedLocaleListGetter(tts_h ttsHandle, const char* pLanguage, tts_voice_type_e voiceType, void* pLocaleList)
260 const Locale* pLocale = ConvertEngineLocaleToNativeN(String(pLanguage));
263 static_cast <ArrayList*>(pLocaleList)->RemoveAll(true);
267 if (pLocale->GetLanguageCode() == LANGUAGE_INVALID)
269 SysLog(NID_UI, "[CB] Not support language[%s]", pLanguage);
274 result r = static_cast<ArrayList*>(pLocaleList)->Add(*pLocale);
277 static_cast<ArrayList*>(pLocaleList)->RemoveAll(true);
284 _AccessibilityTtsPlayer::ConvertTizenLocaleToEngineN(const Tizen::Locales::Locale& locale)
286 String strLanguageCode = Locale::LanguageCodeToTwoLetterLanguageCodeString(locale.GetLanguageCode());
287 String strCountryCode = Locale::CountryCodeToString(locale.GetCountryCode());
288 String strLanguage = strLanguageCode + L"_" + strCountryCode;
290 return _StringConverter::CopyToCharArrayN(strLanguage);
292 const Tizen::Locales::Locale*
293 _AccessibilityTtsPlayer::ConvertEngineLocaleToNativeN(const Tizen::Base::String& strSource)
295 String strDelim(L"_");
296 String strLanguageCode;
297 String strCountryCode;
299 LanguageCode languageCode = LANGUAGE_INVALID;
300 CountryCode countryCode = COUNTRY_INVALID;
302 Utility::StringTokenizer toknizer(strSource, strDelim);
303 if (toknizer.GetTokenCount() == 2)
305 toknizer.GetNextToken(strLanguageCode);
306 toknizer.GetNextToken(strCountryCode);
308 languageCode = Locale::TwoLetterLanguageCodeStringToLanguageCode(strLanguageCode);
309 countryCode = Locale::StringToCountryCode(strCountryCode);
312 return new (std::nothrow) Locale(languageCode, countryCode);
316 _AccessibilityTtsPlayer::Speak(const String& text)
318 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
319 "Not yet initialized! This method should be called after initialized.");
321 result r = E_SUCCESS;
322 tts_state_e ttsState = TTS_STATE_READY;
324 int ttsError = tts_get_state(__ttsHandle, &ttsState);
325 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to get the current state.");
327 const char* pLanguage = ConvertTizenLocaleToEngineN(*__pCurrentLocale);
328 SysTryReturnResult(NID_UI, pLanguage != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
330 // if (ttsState != TTS_STATE_READY)
335 const char* pTextN = _StringConverter::CopyToCharArrayN(text);
336 int ttsUtteranceId = 0;
338 SysTryCatchLabel(NID_UI, pTextN != null, r = E_OUT_OF_MEMORY, CATCH_LANG, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
340 ttsError = tts_add_text(__ttsHandle, pTextN, pLanguage, TTS_VOICE_TYPE_AUTO, __speed, &ttsUtteranceId);
341 SysTryCatch(NID_UI, ttsError == TTS_ERROR_NONE, r = E_OUT_OF_MEMORY, E_SYSTEM, "[E_SYSTEM] Failed to add a text.");
342 ttsError = tts_play(__ttsHandle);
343 SysTryCatch(NID_UI, ttsError == TTS_ERROR_NONE, r = E_SYSTEM, E_SYSTEM, "[%s] Failed to play.", GetEngineErrorMessage(ttsError));
345 OnStatusChanged(ACCESSIBILITY_SCREEN_READER_STATUS_PLAYING);
357 _AccessibilityTtsPlayer::Stop(void)
359 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
360 "Not yet initialized! This method should be called after initialized.");
362 tts_state_e ttsState = TTS_STATE_READY;
364 int ttsError = tts_get_state(__ttsHandle, &ttsState);
365 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to get the current state.");
366 ttsError = tts_stop(__ttsHandle);
367 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to stop.");
373 _AccessibilityTtsPlayer::Pause(void)
375 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
376 "Not yet initialized! This method should be called after initialized.");
378 tts_state_e ttsState = TTS_STATE_READY;
380 int ttsError = tts_get_state(__ttsHandle, &ttsState);
381 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to get the current state.");
382 SysTryReturnResult(NID_UI, ttsState == TTS_STATE_PLAYING, E_INVALID_OPERATION, "The TTS state should be TTS_STATUS_PLAYING.");
384 ttsError = tts_pause(__ttsHandle);
385 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to pause.");
391 _AccessibilityTtsPlayer::Resume(void)
393 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
394 "Not yet initialized! This method should be called after initialized.");
396 tts_state_e ttsState = TTS_STATE_READY;
398 int ttsError = tts_get_state(__ttsHandle, &ttsState);
399 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to get the current state.");
400 SysTryReturnResult(NID_UI, ttsState == TTS_STATE_PAUSED, E_INVALID_OPERATION, "The TTS state should be TTS_STATUS_PAUSED.");
402 ttsError = tts_play(__ttsHandle);
403 SysTryReturnResult(NID_UI, ttsError == TTS_ERROR_NONE, E_SYSTEM, "Failed to resume.");
409 _AccessibilityTtsPlayer::SetLocale(const Locale& locale)
411 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
412 "Not yet initialized! This method should be called after initialized.");
413 SysTryReturnResult(NID_UI, __pSupportedLocaleList->Contains(locale), E_UNSUPPORTED_LOCALE, "This locale is not supported.");
415 *__pCurrentLocale = locale;
419 Tizen::Locales::Locale
420 _AccessibilityTtsPlayer::GetLocale(void) const
422 SysTryReturn(NID_UI, __initialized, Locale(LANGUAGE_INVALID, COUNTRY_INVALID), E_INVALID_STATE,
423 "[E_INVALID_STATE] Not yet initialized! This method should be called after initialized.");
425 SetLastResult(E_SUCCESS);
426 return *__pCurrentLocale;
429 const Tizen::Base::Collection::IList*
430 _AccessibilityTtsPlayer::GetSupportedLocales(void) const
432 SysTryReturnResult(NID_UI, __initialized , null,
433 "Not yet initialized! This method should be called after initialized.");
435 SetLastResult(E_SUCCESS);
436 return __pSupportedLocaleList->GetCount() > 0 ? __pSupportedLocaleList : null;
440 _AccessibilityTtsPlayer::IsLocaleSupported(const Tizen::Locales::Locale& locale) const
442 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
443 "Not yet initialized! This method should be called after initialized.");
445 SetLastResult(E_SUCCESS);
446 return __pSupportedLocaleList->Contains(locale);
450 _AccessibilityTtsPlayer::SetSpeechRate(tts_speed_e speechRate)
452 SysTryReturnResult(NID_UI, __initialized , E_INVALID_STATE,
453 "Not yet initialized! This method should be called after initialized.");
455 __speed = speechRate;
461 _AccessibilityTtsPlayer::ReadGrammar(const Tizen::Base::String& grammar, bool init)
463 if(grammar.GetLength() == 0)
467 if(init && GetStatus() == ACCESSIBILITY_SCREEN_READER_STATUS_PLAYING)
471 SetStatus(ACCESSIBILITY_SCREEN_READER_STATUS_PLAYING);
477 _AccessibilityTtsPlayer::StopReading(void)
482 AccessibilityScreenReaderStatus
483 _AccessibilityTtsPlayer::GetStatus(void)
488 _AccessibilityTtsPlayer::GetCurrentGrammar(void)
494 _AccessibilityTtsPlayer::Deactivate(void)
496 __initialized = false;
497 tts_state_e ttsState = TTS_STATE_READY;
499 int ttsError = tts_get_state(__ttsHandle, &ttsState);
500 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to get the current state.", GetEngineErrorMessage(ttsError));
502 if (ttsState == TTS_STATE_PLAYING || ttsState == TTS_STATE_PAUSED)
504 ttsError = tts_stop(__ttsHandle);
505 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to stop.", GetEngineErrorMessage(ttsError));
509 ttsError = tts_unprepare(__ttsHandle);
510 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to unprepare.", GetEngineErrorMessage(ttsError));
512 ttsError = tts_unset_utterance_completed_cb(__ttsHandle);
513 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to unset the utterance completed callback.", GetEngineErrorMessage(ttsError));
515 ttsError = tts_unset_utterance_started_cb(__ttsHandle);
516 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to unset the utterance started callback.", GetEngineErrorMessage(ttsError));
518 ttsError = tts_unset_state_changed_cb(__ttsHandle);
519 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to unset the state changed callback.", GetEngineErrorMessage(ttsError));
521 ttsError = tts_unset_error_cb(__ttsHandle);
522 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to unset the error callback.", GetEngineErrorMessage(ttsError));
524 ttsError = tts_destroy(__ttsHandle);
525 SysTryLog(NID_UI, ttsError == TTS_ERROR_NONE, "[%s] Failed to destroy.", GetEngineErrorMessage(ttsError));
533 _AccessibilityTtsPlayer::OnErrorOccurred(Tizen::Base::String& errorString)
537 _AccessibilityTtsPlayer::OnStatusChanged(AccessibilityScreenReaderStatus status)
541 case ACCESSIBILITY_SCREEN_READER_STATUS_PLAYING:
542 __pManager->OnStartReading(__grammar);
551 _AccessibilityTtsPlayer::SetStatus(AccessibilityScreenReaderStatus status)