2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/accessibility/tizen-wayland/tts-player-impl-tizen.h>
24 #include <dali/public-api/object/type-registry.h>
32 namespace // unnamed namespace
35 * Helper function to convert Tizen-specific TTS state to external state.
36 * @param state The Tizen TTS state.
37 * @return The external TTS state.
39 Dali::TtsPlayer::State InternalToExternalState(tts_state_e state)
43 case TTS_STATE_CREATED:
45 return Dali::TtsPlayer::UNAVAILABLE;
49 return Dali::TtsPlayer::READY;
51 case TTS_STATE_PLAYING:
53 return Dali::TtsPlayer::PLAYING;
55 case TTS_STATE_PAUSED:
57 return Dali::TtsPlayer::PAUSED;
61 return Dali::TtsPlayer::UNAVAILABLE;
64 } // unnamed namespace
66 #if defined(DEBUG_ENABLED)
67 Debug::Filter* TtsPlayerTizen::gLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_TTS_PLAYER");
70 std::unique_ptr<TtsPlayerTizen> TtsPlayerTizen::New(Dali::TtsPlayer::Mode mode)
72 return std::unique_ptr<TtsPlayerTizen>(new TtsPlayerTizen(mode));
75 TtsPlayerTizen::TtsPlayerTizen(Dali::TtsPlayer::Mode mode)
76 : mInitialized(false),
85 TtsPlayerTizen::~TtsPlayerTizen()
87 // If it is playing, stop it
90 // Unset the callback funtion for TTS state change
91 int retVal = tts_unset_state_changed_cb(mTtsHandle);
92 if(retVal != TTS_ERROR_NONE)
94 LogErrorCode(static_cast<tts_error_e>(retVal));
97 // Destroy the TTS handle and disconnects the daemon
98 retVal = tts_destroy(mTtsHandle);
99 if(retVal != TTS_ERROR_NONE)
101 LogErrorCode(static_cast<tts_error_e>(retVal));
105 void TtsPlayerTizen::Initialize()
107 // Create the TTS handle
108 int retVal = tts_create(&mTtsHandle);
110 if(retVal != TTS_ERROR_NONE)
112 LogErrorCode(static_cast<tts_error_e>(retVal));
116 // Set the callback funtion for TTS state change
117 retVal = tts_set_state_changed_cb(mTtsHandle, &StateChangedCallback, this);
118 if(retVal != TTS_ERROR_NONE)
120 LogErrorCode(static_cast<tts_error_e>(retVal));
124 tts_mode_e ttsMode = TTS_MODE_DEFAULT;
127 case Dali::TtsPlayer::DEFAULT:
128 ttsMode = TTS_MODE_DEFAULT;
130 case Dali::TtsPlayer::NOTIFICATION:
131 ttsMode = TTS_MODE_NOTIFICATION;
133 case Dali::TtsPlayer::SCREEN_READER:
134 ttsMode = TTS_MODE_SCREEN_READER;
141 retVal = tts_set_mode(mTtsHandle, ttsMode);
142 if(retVal != TTS_ERROR_NONE)
144 LogErrorCode(static_cast<tts_error_e>(retVal));
147 // Connect the TTS daemon asynchronously
148 retVal = tts_prepare(mTtsHandle);
149 if(retVal != TTS_ERROR_NONE)
151 LogErrorCode(static_cast<tts_error_e>(retVal));
156 void TtsPlayerTizen::Play(const std::string& text)
162 // Add text to the queue, and use normal speed, default language and default voice set by the user
163 int retVal = tts_add_text(mTtsHandle, text.c_str(), NULL, TTS_VOICE_TYPE_AUTO, TTS_SPEED_AUTO, &mUtteranceId);
164 if(retVal != TTS_ERROR_NONE)
166 LogErrorCode(static_cast<tts_error_e>(retVal));
170 // Start synthesizing voice from text in the queue and play synthesized audio data
171 retVal = tts_play(mTtsHandle);
172 if(retVal != TTS_ERROR_NONE)
174 LogErrorCode(static_cast<tts_error_e>(retVal));
180 mUnplayedString = text;
184 void TtsPlayerTizen::Stop()
188 // Check the current TTS state
190 int retVal = tts_get_state(mTtsHandle, &state);
191 if(retVal != TTS_ERROR_NONE)
193 LogErrorCode(static_cast<tts_error_e>(retVal));
195 else if(state == TTS_STATE_PLAYING || state == TTS_STATE_PAUSED)
197 // If it is playing or paused, stop playing and clear the queue
198 retVal = tts_stop(mTtsHandle);
199 if(retVal != TTS_ERROR_NONE)
201 LogErrorCode(static_cast<tts_error_e>(retVal));
207 void TtsPlayerTizen::Pause()
211 // Check the current TTS state
213 int retVal = tts_get_state(mTtsHandle, &state);
214 if(retVal != TTS_ERROR_NONE)
216 LogErrorCode(static_cast<tts_error_e>(retVal));
218 else if(state == TTS_STATE_PLAYING)
220 // If the player is playing, pause it.
221 retVal = tts_pause(mTtsHandle);
222 if(retVal != TTS_ERROR_NONE)
224 LogErrorCode(static_cast<tts_error_e>(retVal));
230 void TtsPlayerTizen::Resume()
234 // Check the current TTS state
236 int retVal = tts_get_state(mTtsHandle, &state);
237 if(retVal != TTS_ERROR_NONE)
239 LogErrorCode(static_cast<tts_error_e>(retVal));
241 else if(state == TTS_STATE_PAUSED)
243 // If the player is paused, resume it.
244 retVal = tts_play(mTtsHandle);
245 if(retVal != TTS_ERROR_NONE)
247 LogErrorCode(static_cast<tts_error_e>(retVal));
253 Dali::TtsPlayer::State TtsPlayerTizen::GetState()
255 Dali::TtsPlayer::State ttsState = Dali::TtsPlayer::UNAVAILABLE;
259 // Check the current TTS state
261 int retVal = tts_get_state(mTtsHandle, &state);
262 if(retVal != TTS_ERROR_NONE)
264 LogErrorCode(static_cast<tts_error_e>(retVal));
268 ttsState = InternalToExternalState(state);
275 Dali::TtsPlayer::StateChangedSignalType& TtsPlayerTizen::StateChangedSignal()
277 return mStateChangedSignal;
280 void TtsPlayerTizen::EmitStateChangedSignal(tts_state_e previous, tts_state_e current)
282 // Convert the previous and current states to external states and emit them as a signal.
283 if(!mStateChangedSignal.Empty())
285 mStateChangedSignal.Emit(InternalToExternalState(previous), InternalToExternalState(current));
289 void TtsPlayerTizen::StateChangedCallback(tts_h tts, tts_state_e previous, tts_state_e current, void* userData)
291 // Get the implementation (this is a static function).
292 TtsPlayerTizen* obj = static_cast<TtsPlayerTizen*>(userData);
295 obj->EmitStateChangedSignal(previous, current);
297 if(!obj->mInitialized && current == TTS_STATE_READY)
299 obj->mInitialized = true;
301 // if there is queued text before initialization, play it
302 if(obj->mUnplayedString != "")
304 obj->Play(obj->mUnplayedString);
305 obj->mUnplayedString = "";
310 void TtsPlayerTizen::LogErrorCode(tts_error_e reason)
312 std::string error_string;
320 case TTS_ERROR_OUT_OF_MEMORY:
322 error_string = "TTS: Out of Memory\n";
325 case TTS_ERROR_IO_ERROR:
327 error_string = "TTS: I/O error\n";
330 case TTS_ERROR_INVALID_PARAMETER:
332 error_string = "TTS: Invalid parameter\n";
335 case TTS_ERROR_OUT_OF_NETWORK:
337 error_string = "TTS: Out of network\n";
340 case TTS_ERROR_INVALID_STATE:
342 error_string = "TTS: Invalid state\n";
345 case TTS_ERROR_INVALID_VOICE:
347 error_string = "TTS: Invalid voice\n";
350 case TTS_ERROR_ENGINE_NOT_FOUND:
352 error_string = "TTS: No available engine\n";
355 case TTS_ERROR_TIMED_OUT:
357 error_string = "TTS: No answer from the daemon\n";
360 case TTS_ERROR_OPERATION_FAILED:
362 error_string = "TTS: Operation failed\n";
367 error_string = "Invalid TTS error code\n";
372 if(reason != TTS_ERROR_NONE)
374 DALI_LOG_WARNING("[%s:%d] tts error : %s\n", __FUNCTION__, __LINE__, error_string.c_str());
378 } // namespace Adaptor
380 } // namespace Internal