2 * Copyright (c) 2018 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>
36 namespace // unnamed namespace
40 * Helper function to convert Tizen-specific TTS state to external state.
41 * @param state The Tizen TTS state.
42 * @return The external TTS state.
44 Dali::TtsPlayer::State InternalToExternalState( tts_state_e state )
48 case TTS_STATE_CREATED:
50 return Dali::TtsPlayer::UNAVAILABLE;
54 return Dali::TtsPlayer::READY;
56 case TTS_STATE_PLAYING:
58 return Dali::TtsPlayer::PLAYING;
60 case TTS_STATE_PAUSED:
62 return Dali::TtsPlayer::PAUSED;
66 return Dali::TtsPlayer::UNAVAILABLE;
69 } // unnamed namespace
71 #if defined(DEBUG_ENABLED)
72 Debug::Filter* TtsPlayerTizen::gLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_TTS_PLAYER");
75 std::unique_ptr<TtsPlayerTizen> TtsPlayerTizen::New(Dali::TtsPlayer::Mode mode)
77 return std::unique_ptr<TtsPlayerTizen>(new TtsPlayerTizen(mode));
80 TtsPlayerTizen::TtsPlayerTizen(Dali::TtsPlayer::Mode mode)
81 : mInitialized(false),
90 TtsPlayerTizen::~TtsPlayerTizen()
92 // If it is playing, stop it
95 // Unset the callback funtion for TTS state change
96 int retVal = tts_unset_state_changed_cb(mTtsHandle);
97 if( retVal != TTS_ERROR_NONE )
99 LogErrorCode(static_cast<tts_error_e>(retVal));
102 // Destroy the TTS handle and disconnects the daemon
103 retVal = tts_destroy(mTtsHandle);
104 if( retVal != TTS_ERROR_NONE )
106 LogErrorCode(static_cast<tts_error_e>(retVal));
110 void TtsPlayerTizen::Initialize()
112 // Create the TTS handle
113 int retVal = tts_create(&mTtsHandle);
115 if( retVal != TTS_ERROR_NONE )
117 LogErrorCode(static_cast<tts_error_e>(retVal));
121 // Set the callback funtion for TTS state change
122 retVal = tts_set_state_changed_cb(mTtsHandle, &StateChangedCallback, this);
123 if( retVal != TTS_ERROR_NONE )
125 LogErrorCode(static_cast<tts_error_e>(retVal));
129 tts_mode_e ttsMode = TTS_MODE_DEFAULT;
132 case Dali::TtsPlayer::DEFAULT:
133 ttsMode = TTS_MODE_DEFAULT;
135 case Dali::TtsPlayer::NOTIFICATION:
136 ttsMode = TTS_MODE_NOTIFICATION;
138 case Dali::TtsPlayer::SCREEN_READER:
139 ttsMode = TTS_MODE_SCREEN_READER;
146 retVal = tts_set_mode(mTtsHandle, ttsMode);
147 if(retVal != TTS_ERROR_NONE)
149 LogErrorCode(static_cast<tts_error_e>(retVal));
152 // Connect the TTS daemon asynchronously
153 retVal = tts_prepare(mTtsHandle);
154 if(retVal != TTS_ERROR_NONE)
156 LogErrorCode(static_cast<tts_error_e>(retVal));
161 void TtsPlayerTizen::Play(const std::string& text)
167 // Add text to the queue, and use normal speed, default language and default voice set by the user
168 int retVal = tts_add_text(mTtsHandle, text.c_str(), NULL, TTS_VOICE_TYPE_AUTO, TTS_SPEED_AUTO, &mUtteranceId);
169 if(retVal != TTS_ERROR_NONE)
171 LogErrorCode(static_cast<tts_error_e>(retVal));
175 // Start synthesizing voice from text in the queue and play synthesized audio data
176 retVal = tts_play(mTtsHandle);
177 if(retVal != TTS_ERROR_NONE)
179 LogErrorCode(static_cast<tts_error_e>(retVal));
185 mUnplayedString = text;
189 void TtsPlayerTizen::Stop()
193 // Check the current TTS state
195 int retVal = tts_get_state(mTtsHandle, &state);
196 if(retVal != TTS_ERROR_NONE)
198 LogErrorCode(static_cast<tts_error_e>(retVal));
200 else if(state == TTS_STATE_PLAYING || state == TTS_STATE_PAUSED)
202 // If it is playing or paused, stop playing and clear the queue
203 retVal = tts_stop(mTtsHandle);
204 if( retVal != TTS_ERROR_NONE )
206 LogErrorCode(static_cast<tts_error_e>(retVal));
212 void TtsPlayerTizen::Pause()
216 // Check the current TTS state
218 int retVal = tts_get_state(mTtsHandle, &state);
219 if(retVal != TTS_ERROR_NONE)
221 LogErrorCode(static_cast<tts_error_e>(retVal));
223 else if(state == TTS_STATE_PLAYING)
225 // If the player is playing, pause it.
226 retVal = tts_pause(mTtsHandle);
227 if( retVal != TTS_ERROR_NONE )
229 LogErrorCode(static_cast<tts_error_e>(retVal));
235 void TtsPlayerTizen::Resume()
239 // Check the current TTS state
241 int retVal = tts_get_state(mTtsHandle, &state);
242 if(retVal != TTS_ERROR_NONE)
244 LogErrorCode(static_cast<tts_error_e>(retVal));
246 else if(state == TTS_STATE_PAUSED)
248 // If the player is paused, resume it.
249 retVal = tts_play(mTtsHandle);
250 if( retVal != TTS_ERROR_NONE )
252 LogErrorCode(static_cast<tts_error_e>(retVal));
258 Dali::TtsPlayer::State TtsPlayerTizen::GetState()
260 Dali::TtsPlayer::State ttsState = Dali::TtsPlayer::UNAVAILABLE;
264 // Check the current TTS state
266 int retVal = tts_get_state(mTtsHandle, &state);
267 if(retVal != TTS_ERROR_NONE)
269 LogErrorCode(static_cast<tts_error_e>(retVal));
273 ttsState = InternalToExternalState( state );
280 Dali::TtsPlayer::StateChangedSignalType& TtsPlayerTizen::StateChangedSignal()
282 return mStateChangedSignal;
285 void TtsPlayerTizen::EmitStateChangedSignal( tts_state_e previous, tts_state_e current )
287 // Convert the previous and current states to external states and emit them as a signal.
288 if( !mStateChangedSignal.Empty() )
290 mStateChangedSignal.Emit( InternalToExternalState( previous ), InternalToExternalState( current ) );
294 void TtsPlayerTizen::StateChangedCallback(tts_h tts, tts_state_e previous, tts_state_e current, void *userData)
296 // Get the implementation (this is a static function).
297 TtsPlayerTizen* obj = static_cast<TtsPlayerTizen*>(userData);
300 obj->EmitStateChangedSignal( previous, current );
302 if(!obj->mInitialized && current == TTS_STATE_READY)
304 obj->mInitialized = true;
306 // if there is queued text before initialization, play it
307 if(obj->mUnplayedString != "")
309 obj->Play(obj->mUnplayedString);
310 obj->mUnplayedString = "";
315 void TtsPlayerTizen::LogErrorCode(tts_error_e reason)
317 std::string error_string;
325 case TTS_ERROR_OUT_OF_MEMORY:
327 error_string = "TTS: Out of Memory\n";
330 case TTS_ERROR_IO_ERROR:
332 error_string = "TTS: I/O error\n";
335 case TTS_ERROR_INVALID_PARAMETER:
337 error_string = "TTS: Invalid parameter\n";
340 case TTS_ERROR_OUT_OF_NETWORK:
342 error_string = "TTS: Out of network\n";
345 case TTS_ERROR_INVALID_STATE:
347 error_string = "TTS: Invalid state\n";
350 case TTS_ERROR_INVALID_VOICE:
352 error_string = "TTS: Invalid voice\n";
355 case TTS_ERROR_ENGINE_NOT_FOUND:
357 error_string = "TTS: No available engine\n";
360 case TTS_ERROR_TIMED_OUT:
362 error_string = "TTS: No answer from the daemon\n";
365 case TTS_ERROR_OPERATION_FAILED:
367 error_string = "TTS: Operation failed\n";
372 error_string = "Invalid TTS error code\n";
377 if(reason != TTS_ERROR_NONE)
379 DALI_LOG_WARNING("[%s:%d] tts error : %s\n", __FUNCTION__, __LINE__, error_string.c_str());
383 } // namespace Adaptor
385 } // namespace Internal