Merge "Add API to notify adaptor that scene has been created" into devel/master
[platform/core/uifw/dali-adaptor.git] / adaptors / tizen / tts-player-impl-tizen.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include "tts-player-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <tts.h>
23 #include <stdio.h>
24
25 #include <dali/public-api/object/type-registry.h>
26
27
28 namespace Dali
29 {
30
31 namespace Internal
32 {
33
34 namespace Adaptor
35 {
36
37 namespace // unnamed namespace
38 {
39 // Type Registration
40 Dali::BaseHandle Create()
41 {
42   return Dali::TtsPlayer::Get() ;
43 }
44
45 Dali::TypeRegistration mType( typeid(Dali::TtsPlayer), typeid(Dali::BaseHandle), Create ) ;
46 } // unnamed namespace
47
48 #if defined(DEBUG_ENABLED)
49 Debug::Filter* TtsPlayer::gLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_TTS_PLAYER");
50 #endif
51
52 Dali::TtsPlayer TtsPlayer::New(Dali::TtsPlayer::Mode mode)
53 {
54   Dali::TtsPlayer player = Dali::TtsPlayer(new TtsPlayer(mode));
55
56   return player;
57 }
58
59 TtsPlayer::TtsPlayer(Dali::TtsPlayer::Mode mode)
60 : mInitialized(false),
61   mUnplayedString(""),
62   mUtteranceId(0),
63   mTtsMode(mode)
64 {
65   Initialize();
66 }
67
68 TtsPlayer::~TtsPlayer()
69 {
70   // If it is playing, stop it
71   Stop();
72
73   // Unset the callback funtion for TTS state change
74   int retVal = tts_unset_state_changed_cb(mTtsHandle);
75   if( retVal != TTS_ERROR_NONE )
76   {
77     LogErrorCode(static_cast<tts_error_e>(retVal));
78   }
79
80   // Destroy the TTS handle and disconnects the daemon
81   retVal = tts_destroy(mTtsHandle);
82   if( retVal != TTS_ERROR_NONE )
83   {
84     LogErrorCode(static_cast<tts_error_e>(retVal));
85   }
86 }
87
88 void TtsPlayer::Initialize()
89 {
90   // Create the TTS handle
91   int retVal = tts_create(&mTtsHandle);
92
93   if( retVal != TTS_ERROR_NONE )
94   {
95     LogErrorCode(static_cast<tts_error_e>(retVal));
96   }
97   else
98   {
99     // Set the callback funtion for TTS state change
100     retVal = tts_set_state_changed_cb(mTtsHandle, &StateChangedCallback, this);
101     if( retVal != TTS_ERROR_NONE )
102     {
103       LogErrorCode(static_cast<tts_error_e>(retVal));
104     }
105
106     // Check tts mode
107     tts_mode_e ttsMode = TTS_MODE_DEFAULT;
108     switch (mTtsMode)
109     {
110       case Dali::TtsPlayer::DEFAULT:
111         ttsMode = TTS_MODE_DEFAULT;
112       break;
113       case Dali::TtsPlayer::NOTIFICATION:
114         ttsMode = TTS_MODE_NOTIFICATION;
115       break;
116       case Dali::TtsPlayer::SCREEN_READER:
117         ttsMode = TTS_MODE_SCREEN_READER;
118       break;
119       default:
120       break;
121     }
122
123     // Set mode
124     retVal = tts_set_mode(mTtsHandle, ttsMode);
125     if(retVal != TTS_ERROR_NONE)
126     {
127       LogErrorCode(static_cast<tts_error_e>(retVal));
128     }
129
130     // Connect the TTS daemon asynchronously
131     retVal = tts_prepare(mTtsHandle);
132     if(retVal != TTS_ERROR_NONE)
133     {
134       LogErrorCode(static_cast<tts_error_e>(retVal));
135     }
136   }
137 }
138
139 void TtsPlayer::Play(const std::string& text)
140 {
141   if(mInitialized)
142   {
143     Stop();
144
145     // Add text to the queue, and use normal speed, default language and default voice set by the user
146     int retVal = tts_add_text(mTtsHandle, text.c_str(), NULL, TTS_VOICE_TYPE_AUTO, TTS_SPEED_AUTO, &mUtteranceId);
147     if(retVal != TTS_ERROR_NONE)
148     {
149       LogErrorCode(static_cast<tts_error_e>(retVal));
150     }
151     else
152     {
153       // Start synthesizing voice from text in the queue and play synthesized audio data
154       retVal = tts_play(mTtsHandle);
155       if(retVal != TTS_ERROR_NONE)
156       {
157         LogErrorCode(static_cast<tts_error_e>(retVal));
158       }
159     }
160   }
161   else
162   {
163     mUnplayedString = text;
164   }
165 }
166
167 void TtsPlayer::Stop()
168 {
169   if(mInitialized)
170   {
171     // Check the current TTS state
172     tts_state_e state;
173     int retVal = tts_get_state(mTtsHandle, &state);
174     if(retVal != TTS_ERROR_NONE)
175     {
176       LogErrorCode(static_cast<tts_error_e>(retVal));
177     }
178     else if(state == TTS_STATE_PLAYING || state == TTS_STATE_PAUSED)
179     {
180       // If it is playing or paused, stop playing and clear the queue
181       retVal = tts_stop(mTtsHandle);
182       if( retVal != TTS_ERROR_NONE )
183       {
184         LogErrorCode(static_cast<tts_error_e>(retVal));
185       }
186     }
187   }
188 }
189
190 void TtsPlayer::Pause()
191 {
192   if(mInitialized)
193   {
194     // Check the current TTS state
195     tts_state_e state;
196     int retVal = tts_get_state(mTtsHandle, &state);
197     if(retVal != TTS_ERROR_NONE)
198     {
199       LogErrorCode(static_cast<tts_error_e>(retVal));
200     }
201     else if(state == TTS_STATE_PLAYING)
202     {
203       // If the player is playing, pause it.
204       retVal = tts_pause(mTtsHandle);
205       if( retVal != TTS_ERROR_NONE )
206       {
207         LogErrorCode(static_cast<tts_error_e>(retVal));
208       }
209     }
210   }
211 }
212
213 void TtsPlayer::Resume()
214 {
215   if(mInitialized)
216   {
217     // Check the current TTS state
218     tts_state_e state;
219     int retVal = tts_get_state(mTtsHandle, &state);
220     if(retVal != TTS_ERROR_NONE)
221     {
222       LogErrorCode(static_cast<tts_error_e>(retVal));
223     }
224     else if(state == TTS_STATE_PAUSED)
225     {
226       // If the player is paused, resume it.
227       retVal = tts_play(mTtsHandle);
228       if( retVal != TTS_ERROR_NONE )
229       {
230         LogErrorCode(static_cast<tts_error_e>(retVal));
231       }
232     }
233   }
234 }
235
236 Dali::TtsPlayer::State TtsPlayer::GetState()
237 {
238   Dali::TtsPlayer::State ttsState = Dali::TtsPlayer::UNAVAILABLE;
239
240   if(mInitialized)
241   {
242     // Check the current TTS state
243     tts_state_e state;
244     int retVal = tts_get_state(mTtsHandle, &state);
245     if(retVal != TTS_ERROR_NONE)
246     {
247       LogErrorCode(static_cast<tts_error_e>(retVal));
248     }
249     else
250     {
251       ttsState = static_cast<Dali::TtsPlayer::State>(state);
252     }
253   }
254
255   return ttsState;
256 }
257
258 void TtsPlayer::StateChangedCallback(tts_h tts, tts_state_e previous, tts_state_e current, void *userData)
259 {
260   TtsPlayer* obj = static_cast<TtsPlayer*>(userData);
261   if(!obj->mInitialized && current == TTS_STATE_READY)
262   {
263     obj->mInitialized = true;
264
265     // if there is queued text before initialization, play it
266     if(obj->mUnplayedString != "")
267     {
268       obj->Play(obj->mUnplayedString);
269       obj->mUnplayedString = "";
270     }
271   }
272 }
273
274 void TtsPlayer::LogErrorCode(tts_error_e reason)
275 {
276   std::string error_string;
277
278   switch (reason)
279   {
280     case TTS_ERROR_NONE:
281     {
282       break;
283     }
284     case TTS_ERROR_OUT_OF_MEMORY:
285     {
286       error_string = "TTS: Out of Memory\n";
287       break;
288     }
289     case TTS_ERROR_IO_ERROR:
290     {
291       error_string = "TTS: I/O error\n";
292       break;
293     }
294     case TTS_ERROR_INVALID_PARAMETER:
295     {
296       error_string = "TTS: Invalid parameter\n";
297       break;
298     }
299     case TTS_ERROR_OUT_OF_NETWORK:
300     {
301       error_string = "TTS: Out of network\n";
302       break;
303     }
304     case TTS_ERROR_INVALID_STATE:
305     {
306       error_string = "TTS: Invalid state\n";
307       break;
308     }
309     case TTS_ERROR_INVALID_VOICE:
310     {
311       error_string = "TTS: Invalid voice\n";
312       break;
313     }
314     case TTS_ERROR_ENGINE_NOT_FOUND:
315     {
316       error_string = "TTS: No available engine\n";
317       break;
318     }
319     case TTS_ERROR_TIMED_OUT:
320     {
321       error_string = "TTS: No answer from the daemon\n";
322       break;
323     }
324     case TTS_ERROR_OPERATION_FAILED:
325     {
326       error_string = "TTS: Operation failed\n";
327       break;
328     }
329     default:
330     {
331       error_string = "Invalid TTS error code\n";
332       break;
333     }
334   }
335
336   if(reason != TTS_ERROR_NONE)
337   {
338     DALI_LOG_WARNING("[%s:%d] tts error : %s\n", __FUNCTION__, __LINE__, error_string.c_str());
339   }
340 }
341
342 } // namespace Adaptor
343
344 } // namespace Internal
345
346 } // namespace Dali