Add to release memory for sound data
[platform/core/uifw/tts.git] / server / ttsd_player.c
1 /*
2 *  Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <audio_io.h>
15 #include <Ecore.h>
16 #include <sound_manager.h>
17 #include <sound_manager_internal.h>
18
19 #include "ttsd_main.h"
20 #include "ttsd_player.h"
21 #include "ttsd_data.h"
22 #include "ttsd_dbus.h"
23
24 /*
25 * Internal data structure
26 */
27
28 typedef enum {
29         AUDIO_STATE_NONE = 0,
30         AUDIO_STATE_READY,
31         AUDIO_STATE_PLAY
32 } audio_state_e;
33
34 typedef struct {
35         int                     uid;    /** client id */
36         app_state_e             state;  /** client state */
37
38         /* Current utterance information */
39         ttse_result_event_e     event;  /** event of last utterance */
40
41         bool                    is_paused_data;
42         int                     idx;
43         sound_data_s*           paused_data;
44 } player_s;
45
46 #define SOUND_BUFFER_LENGTH     2048
47 #define FOCUS_SERVER_READY "/tmp/.sound_server_ready"
48
49 /** player init info */
50 static bool g_player_init = false;
51
52 /** Client list */
53 static GList *g_player_list;
54
55 /** current player information */
56 static player_s* g_playing_info;
57
58 /* player state */
59 static audio_state_e g_audio_state;
60
61 static ttse_audio_type_e g_audio_type;
62
63 static int g_sampling_rate;
64
65 static audio_out_h g_audio_h;
66
67 static sound_stream_info_h g_stream_info_h;
68
69 /*
70 * Internal Interfaces
71 */
72
73 player_s* __player_get_item(int uid)
74 {
75         GList *iter = NULL;
76         player_s *data = NULL;
77
78         if (0 < g_list_length(g_player_list)) {
79                 /* Get a first item */
80                 iter = g_list_first(g_player_list);
81
82                 while (NULL != iter) {
83                         /* Get handle data from list */
84                         data = (player_s*)iter->data;
85
86                         /* compare uid */
87                         if (uid == data->uid)
88                                 return data;
89
90                         /* Get next item */
91                         iter = g_list_next(iter);
92                 }
93         }
94
95         return NULL;
96 }
97
98 void __player_focus_state_cb(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state,
99                                                         sound_stream_focus_change_reason_e reason_for_change, int sound_behavior, const char *extra_info, void *user_data)
100 {
101         SLOG(LOG_DEBUG, tts_tag(), "===== Focus state changed cb");
102
103         if (stream_info != g_stream_info_h) {
104                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Invalid stream info handle");
105                 return;
106         }
107         SLOG(LOG_WARN, tts_tag(), "[Player] focus state changed to (%d) with reason(%d)", (int)focus_state, (int)reason_for_change);
108
109         if (AUDIO_STATE_PLAY == g_audio_state && focus_mask == SOUND_STREAM_FOCUS_FOR_PLAYBACK && SOUND_STREAM_FOCUS_STATE_RELEASED == focus_state) {
110                 if (TTSD_MODE_DEFAULT == ttsd_get_mode()) {
111                         g_audio_state = AUDIO_STATE_READY;
112
113                         if (NULL == g_playing_info) {
114                                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player");
115                                 return;
116                         }
117
118                         if (APP_STATE_PLAYING == g_playing_info->state) {
119                                 int uid = g_playing_info->uid;
120
121                                 if (0 != ttsd_player_pause(uid)) {
122                                         SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to pause the player");
123                                         return;
124                                 }
125
126                                 g_playing_info->state = APP_STATE_PAUSED;
127                                 ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
128                                 int pid = ttsd_data_get_pid(uid);
129                                 /* send message to client about changing state */
130                                 ttsdc_send_set_state_message(pid, uid, APP_STATE_PAUSED);
131                         }
132                 } else {
133                         SLOG(LOG_DEBUG, tts_tag(), "[Player] Ignore focus state cb - mode(%d)", ttsd_get_mode());
134                 }
135         }
136
137         SLOG(LOG_DEBUG, tts_tag(), "=====");
138         SLOG(LOG_DEBUG, tts_tag(), "");
139
140         return;
141 }
142
143 static int __create_audio_out(ttse_audio_type_e type, int rate)
144 {
145         int ret = -1;
146         audio_sample_type_e sample_type;
147
148         if (TTSE_AUDIO_TYPE_RAW_S16 == type) {
149                 sample_type = AUDIO_SAMPLE_TYPE_S16_LE;
150         } else {
151                 sample_type = AUDIO_SAMPLE_TYPE_U8;
152         }
153
154         ret = audio_out_create_new(rate, AUDIO_CHANNEL_MONO, sample_type, &g_audio_h);
155         if (AUDIO_IO_ERROR_NONE != ret) {
156                 g_audio_state = AUDIO_STATE_NONE;
157                 g_audio_h = NULL;
158                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio");
159                 return -1;
160         } else {
161                 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create audio");
162         }
163
164         g_audio_type = type;
165         g_sampling_rate = rate;
166
167         g_audio_state = AUDIO_STATE_READY;
168
169         return 0;
170 }
171
172 static int __destroy_audio_out()
173 {
174         if (NULL == g_audio_h) {
175                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current handle is not valid");
176                 return -1;
177         }
178
179         int ret = -1;
180         ret = audio_out_destroy(g_audio_h);
181         if (AUDIO_IO_ERROR_NONE != ret) {
182                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to destroy audio");
183                 return -1;
184         } else {
185                 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy audio");
186         }
187
188         g_audio_type = 0;
189         g_sampling_rate = 0;
190
191         g_audio_state = AUDIO_STATE_NONE;
192         g_audio_h = NULL;
193
194         return 0;
195 }
196
197 static void __end_play_thread(void *data, Ecore_Thread *thread)
198 {
199         SLOG(LOG_ERROR, tts_tag(), "===== End thread");
200 }
201
202 static void __set_policy_for_playing(int volume)
203 {
204         /* Set stream info */
205         int ret;
206         if (TTSD_MODE_DEFAULT == ttsd_get_mode()) {
207                 ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
208                 if (SOUND_MANAGER_ERROR_NONE != ret) {
209                         SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to acquire focus");
210                 }
211         }
212         ret = audio_out_set_sound_stream_info(g_audio_h, g_stream_info_h);
213         if (AUDIO_IO_ERROR_NONE != ret) {
214                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to set stream info");
215         }
216
217         return;
218 }
219
220 static void __unset_policy_for_playing()
221 {
222         int ret;
223         /* Unset stream info */
224         if (TTSD_MODE_DEFAULT == ttsd_get_mode()) {
225                 sound_stream_focus_state_e state_for_playing = SOUND_STREAM_FOCUS_STATE_ACQUIRED;
226                 ret = sound_manager_get_focus_state(g_stream_info_h, &state_for_playing, NULL);
227                 if (SOUND_MANAGER_ERROR_NONE != ret) {
228                         SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to get focus state: %d", ret);
229                 }
230
231                 if (SOUND_STREAM_FOCUS_STATE_ACQUIRED == state_for_playing) {
232                         ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
233                         if (SOUND_MANAGER_ERROR_NONE != ret) {
234                                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to release focus");
235                         }
236                 }
237         }
238
239         return;
240 }
241
242 static void __play_thread(void *data, Ecore_Thread *thread)
243 {
244         SLOG(LOG_DEBUG, tts_tag(), "===== Start thread");
245
246         if (NULL == g_playing_info) {
247                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] No current player");
248                 return;
249         }
250
251         player_s* player = g_playing_info;
252         sound_data_s* sound_data = NULL;
253
254         int ret = -1;
255         int len = SOUND_BUFFER_LENGTH;
256         int idx = 0;
257
258         /* set volume policy as 40% */
259         __set_policy_for_playing(40);
260         while (1) {
261                 if (true == player->is_paused_data) {
262                         /* Resume player */
263                         sound_data = player->paused_data;
264                         player->paused_data = NULL;
265
266                         idx = player->idx;
267
268                         player->is_paused_data = false;
269                         player->idx = 0;
270
271                         if (NULL == sound_data) {
272                                 /* Request unprepare */
273                                 ret = audio_out_unprepare(g_audio_h);
274                                 if (AUDIO_IO_ERROR_NONE != ret) {
275                                         SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
276                                 } else {
277                                         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
278                                 }
279
280                                 g_audio_state = AUDIO_STATE_READY;
281
282                                 /* unset volume policy, volume will be 100% */
283                                 __unset_policy_for_playing();
284                                 return;
285                         }
286                         SLOG(LOG_INFO, tts_tag(), "[Player] Sound info : id(%d) data(%p) size(%d) audiotype(%d) rate(%d) event(%d)", 
287                                 sound_data->utt_id, sound_data->data, sound_data->data_size, sound_data->audio_type, sound_data->rate, sound_data->event);
288                 } else {
289                         sound_data = NULL;
290                         ret = ttsd_data_get_sound_data(player->uid, &sound_data);
291                         if (0 != ret || NULL == sound_data) {
292                                 /* empty queue */
293                                 SLOG(LOG_DEBUG, tts_tag(), "[Player] No sound data. Waiting mode");
294                                 /* release audio & recover session */
295                                 ret = audio_out_unprepare(g_audio_h);
296                                 if (AUDIO_IO_ERROR_NONE != ret) {
297                                         SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
298                                 } else {
299                                         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
300                                 }
301                                 g_audio_state = AUDIO_STATE_READY;
302
303                                 /* unset volume policy, volume will be 100% */
304                                 __unset_policy_for_playing();
305
306                                 /* wait for new audio data come */
307                                 while (1) {
308                                         usleep(10000);
309                                         if (NULL == g_playing_info) {
310                                                 /* current playing uid is replaced */
311                                                 SLOG(LOG_DEBUG, tts_tag(), "[Player] Finish thread");
312                                                 return;
313                                         } else if (0 < ttsd_data_get_sound_data_size(player->uid)) {
314                                                 /* new audio data come */
315                                                 SLOG(LOG_DEBUG, tts_tag(), "[Player] Resume thread");
316                                                 break;
317                                         }
318                                 }
319
320                                 /* set volume policy as 40%, when resume play thread*/
321                                 __set_policy_for_playing(40);
322
323                                 /* resume play thread */
324                                 player->state = APP_STATE_PLAYING;
325                                 continue;
326                         }
327
328                         /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
329                          * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
330                          * When previous wdata's event is 'finish' and current wdata's event is 'finish',
331                          * the player should send utt started event.
332                          */
333                         if (TTSE_RESULT_EVENT_START == sound_data->event ||
334                            (TTSE_RESULT_EVENT_FINISH == player->event && TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
335                                 int pid = ttsd_data_get_pid(player->uid);
336
337                                 if (pid <= 0) {
338                                         SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
339                                         /* unset volume policy, volume will be 100% */
340                                         __unset_policy_for_playing();
341
342                                         if (NULL != sound_data->data) {
343                                                 free(sound_data->data);
344                                                 sound_data->data = NULL;
345                                         }
346                                         free(sound_data);
347                                         sound_data = NULL;
348                                         return;
349                                 }
350
351                                 if (0 != ttsdc_send_utt_start_message(pid, player->uid, sound_data->utt_id)) {
352                                         SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%d), uttid(%d)", 
353                                                 pid, player->uid, sound_data->utt_id);
354                                 }
355                                 SLOG(LOG_DEBUG, tts_tag(), "[Player] Start utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
356                         }
357
358                         /* Save last event to check utterance start */
359                         player->event = sound_data->event;
360                         idx = 0;
361
362                         if (NULL == sound_data->data || 0 >= sound_data->data_size) {
363                                 if (TTSE_RESULT_EVENT_FINISH == sound_data->event) {
364                                         SLOG(LOG_DEBUG, tts_tag(), "No sound data");
365                                         /* send utterence finish signal */
366                                         int pid = ttsd_data_get_pid(player->uid);
367
368                                         if (pid <= 0) {
369                                                 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
370                                                 /* unset volume policy, volume will be 100% */
371                                                 __unset_policy_for_playing();
372                                                 if (NULL != sound_data->data) {
373                                                         free(sound_data->data);
374                                                         sound_data->data = NULL;
375                                                 }
376                                                 free(sound_data);
377                                                 sound_data = NULL;
378                                                 return;
379                                         }
380                                         if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
381                                                 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", 
382                                                         pid, player->uid, sound_data->utt_id);
383                                         }
384                                 }
385                                 SLOG(LOG_DEBUG, tts_tag(), "[Player] Finish utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
386                                 continue;
387                         }
388                 }
389
390                 if (g_sampling_rate != sound_data->rate || g_audio_type != sound_data->audio_type) {
391                         SLOG(LOG_DEBUG, tts_tag(), "[Player] Change audio handle : org type(%d) org rate(%d)", g_audio_type, g_sampling_rate);
392                         if (NULL != g_audio_h) {
393                                 __destroy_audio_out();
394                         }
395
396                         if (0 > __create_audio_out(sound_data->audio_type, sound_data->rate)) {
397                                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio out");
398                                 /* unset volume policy, volume will be 100% */
399                                 __unset_policy_for_playing();
400
401                                 if (NULL != sound_data->data) {
402                                         free(sound_data->data);
403                                         sound_data->data = NULL;
404                                 }
405                                 free(sound_data);
406                                 sound_data = NULL;
407
408                                 return;
409                         }
410                         __set_policy_for_playing(40);
411                 }
412
413                 while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) {
414                         if ((unsigned int)idx >= sound_data->data_size)
415                                 break;
416
417                         if ((unsigned int)idx + SOUND_BUFFER_LENGTH > sound_data->data_size) {
418                                 len = sound_data->data_size - idx;
419                         } else {
420                                 len = SOUND_BUFFER_LENGTH;
421                         }
422
423                         if (AUDIO_STATE_READY == g_audio_state) {
424                                 /* Request prepare */
425                                 ret = audio_out_prepare(g_audio_h);
426                                 if (AUDIO_IO_ERROR_NONE != ret) {
427                                         SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to prepare audio : %d", ret);
428                                         g_playing_info = NULL;
429                                         /* unset volume policy, volume will be 100% */
430                                         __unset_policy_for_playing();
431
432                                         if (NULL != sound_data->data) {
433                                                 free(sound_data->data);
434                                                 sound_data->data = NULL;
435                                         }
436
437                                         free(sound_data);
438                                         sound_data = NULL;
439
440                                         return;
441                                 }
442                                 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Prepare audio");
443                                 g_audio_state = AUDIO_STATE_PLAY;
444                         }
445
446                         char* temp_data = sound_data->data;
447                         ret = audio_out_write(g_audio_h, &temp_data[idx], len);
448                         if (0 > ret) {
449                                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to audio write - %d", ret);
450                         } else {
451                                 idx += len;
452                         }
453
454                         if (NULL == g_playing_info && APP_STATE_PAUSED != player->state) {
455                                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
456                                 g_audio_state = AUDIO_STATE_READY;
457                                 ret = audio_out_unprepare(g_audio_h);
458                                 if (AUDIO_IO_ERROR_NONE != ret) {
459                                         SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
460                                 }
461                                 /* unset volume policy, volume will be 100% */
462                                 __unset_policy_for_playing();
463
464                                 if (NULL != sound_data) {
465                                         if (NULL != sound_data->data) {
466                                                 free(sound_data->data);
467                                                 sound_data->data = NULL;
468                                         }
469
470                                         free(sound_data);
471                                         sound_data = NULL;
472                                 }
473
474                                 return;
475                         }
476
477                         if (APP_STATE_PAUSED == player->state) {
478                                 /* Save data */
479                                 player->paused_data = sound_data;
480
481                                 player->is_paused_data = true;
482                                 player->idx = idx;
483
484                                 g_audio_state = AUDIO_STATE_READY;
485                                 SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread by pause");
486
487                                 /* Request prepare */
488                                 ret = audio_out_unprepare(g_audio_h);
489                                 if (AUDIO_IO_ERROR_NONE != ret) {
490                                         SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
491                                 } else {
492                                         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
493                                 }
494                                 /* unset volume policy, volume will be 100% */
495                                 __unset_policy_for_playing();
496                                 return;
497                         }
498                 }
499
500                 if (NULL == g_playing_info && APP_STATE_READY == player->state) {
501                         /* player_stop */ 
502                         g_audio_state = AUDIO_STATE_READY;
503                         SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread");
504
505                         /* Request prepare */
506                         ret = audio_out_unprepare(g_audio_h);
507                         if (AUDIO_IO_ERROR_NONE != ret) {
508                                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
509                         } else {
510                                 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
511                         }
512
513                         if (NULL != sound_data) {
514                                 if (NULL != sound_data->data) {
515                                         free(sound_data->data);
516                                         sound_data->data = NULL;
517                                 }
518
519                                 free(sound_data);
520                                 sound_data = NULL;
521                         }
522                         /* unset volume policy, volume will be 100% */
523                         __unset_policy_for_playing();
524                         return;
525                 }
526
527                 if ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) &&
528                         (TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
529                         /* send utterence finish signal */
530                         int pid = ttsd_data_get_pid(player->uid);
531
532                         if (pid <= 0) {
533                                 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
534                                 /* unset volume policy, volume will be 100% */
535                                 __unset_policy_for_playing();
536                                 if (NULL != sound_data->data) {
537                                         free(sound_data->data);
538                                         sound_data->data = NULL;
539                                 }
540
541                                 free(sound_data);
542                                 sound_data = NULL;
543                                 return;
544                         }
545
546                         if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
547                                 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", 
548                                         pid, player->uid, sound_data->utt_id);
549                                 /* unset volume policy, volume will be 100% */
550                                 __unset_policy_for_playing();
551                                 if (NULL != sound_data->data) {
552                                         free(sound_data->data);
553                                         sound_data->data = NULL;
554                                 }
555
556                                 free(sound_data);
557                                 sound_data = NULL;
558                                 return;
559                         }
560
561                         SLOG(LOG_DEBUG, tts_tag(), "[Player] Finish utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
562                 }
563
564                 if (NULL != sound_data) {
565                         if (NULL != sound_data->data) {
566                                 free(sound_data->data);
567                                 sound_data->data = NULL;
568                         }
569
570                         free(sound_data);
571                         sound_data = NULL;
572                 }
573
574                 if (NULL == g_playing_info) {
575                         SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
576                         g_audio_state = AUDIO_STATE_READY;
577                         ret = audio_out_unprepare(g_audio_h);
578                         if (AUDIO_IO_ERROR_NONE != ret) {
579                                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
580                         }
581                         /* unset volume policy, volume will be 100% */
582                         __unset_policy_for_playing();
583
584                         return;
585                 }
586         }
587 }
588
589 /*
590 * Player Interfaces
591 */
592 int ttsd_player_init()
593 {
594         g_playing_info = NULL;
595         g_audio_state = AUDIO_STATE_NONE;
596         g_audio_h = NULL;
597
598         int ret;
599
600         ecore_thread_max_set(1);
601
602         int cnt = 0;
603         while (1) {
604                 if (0 == access(FOCUS_SERVER_READY, F_OK)) {
605                         SLOG(LOG_ERROR, tts_tag(), "[Player SUCCESS] focus server is available");
606                         break;
607                 } else {
608                         if (0 == cnt++ % 10)
609                                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] focus server is not available");
610                         usleep(50000);
611                 }
612         }
613
614         ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_INFORMATION, __player_focus_state_cb, NULL, &g_stream_info_h);
615         if (SOUND_MANAGER_ERROR_NONE != ret) {
616                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create stream info");
617                 return -1;
618         } else {
619                 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create stream info");
620         }
621
622         ecore_thread_max_set(1);
623
624         ret = __create_audio_out(TTSE_AUDIO_TYPE_RAW_S16, 16000);
625         if (0 != ret)
626                 return -1;
627
628         g_player_init = true;
629
630         return 0;
631 }
632
633 int ttsd_player_release(void)
634 {
635         if (false == g_player_init) {
636                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
637                 return TTSD_ERROR_OPERATION_FAILED;
638         }
639
640         int ret;
641
642         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] ==========================");
643         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
644         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] ==========================");
645
646         /* The thread should be released */
647         int thread_count = ecore_thread_active_get();
648         int count = 0;
649         while (0 < thread_count) {
650                 usleep(10000);
651
652                 count++;
653                 if (20 == count) {
654                         SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
655                         break;
656                 }
657
658                 thread_count = ecore_thread_active_get();
659         }
660
661         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Thread is released");
662
663         ret = __destroy_audio_out();
664         if (0 != ret)
665                 return -1;
666
667         ret = sound_manager_destroy_stream_information(g_stream_info_h);
668         if (SOUND_MANAGER_ERROR_NONE != ret) {
669                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy stream info");
670         } else {
671                 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy stream info");
672         }
673
674         /* clear g_player_list */
675         g_playing_info = NULL;
676         g_player_init = false;
677
678         return 0;
679 }
680
681 int ttsd_player_create_instance(int uid)
682 {
683         if (false == g_player_init) {
684                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
685                 return -1;
686         }
687
688         /* Check uid is duplicated */
689         if (NULL != __player_get_item(uid)) {
690                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is already registered", uid);
691                 return -1;
692         }
693
694         player_s* new_client = (player_s*)calloc(1, sizeof(player_s));
695         if (NULL == new_client) {
696                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to allocate memory");
697                 return TTSE_ERROR_OUT_OF_MEMORY;
698         }
699
700         new_client->uid = uid;
701         new_client->event = TTSE_RESULT_EVENT_FINISH;
702         new_client->state = APP_STATE_READY;
703         new_client->is_paused_data = false;
704         new_client->idx = 0;
705         new_client->paused_data = NULL;
706         
707         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Player] Create player : uid(%d)", uid);
708
709         g_player_list = g_list_append(g_player_list, new_client);
710
711         return 0;
712 }
713
714 int ttsd_player_destroy_instance(int uid)
715 {
716         if (false == g_player_init) {
717                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
718                 return -1;
719         }
720
721         player_s* current;
722         current = __player_get_item(uid);
723         if (NULL == current) {
724                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
725                 return -1;
726         }
727
728         if (NULL != g_playing_info) {
729                 if (uid == g_playing_info->uid) {
730                         g_playing_info = NULL;
731                 }
732         }
733
734         GList *iter = NULL;
735         player_s *data = NULL;
736
737         if (0 < g_list_length(g_player_list)) {
738                 /* Get a first item */
739                 iter = g_list_first(g_player_list);
740
741                 while (NULL != iter) {
742                         /* Get handle data from list */
743                         data = (player_s*)iter->data;
744
745                         if (NULL != data) {
746                                 /* compare uid */
747                                 if (uid == data->uid) {
748                                         g_player_list = g_list_remove_link(g_player_list, iter);
749                                         free(data);
750                                         g_list_free(iter);              
751                                         break;
752                                 }
753                         }
754
755                         /* Get next item */
756                         iter = g_list_next(iter);
757                 }
758         }
759
760         SLOG(LOG_DEBUG, tts_tag(), "[PLAYER Success] Destroy instance");
761
762         return 0;
763 }
764
765 int ttsd_player_play(int uid)
766 {
767         if (false == g_player_init) {
768                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
769                 return -1;
770         }
771
772         if (NULL != g_playing_info) {
773                 if (uid == g_playing_info->uid) {
774                         SLOG(LOG_DEBUG, tts_tag(), "[Player] uid(%d) has already played", g_playing_info->uid);
775                         return 0;
776                 } else {
777                         SLOG(LOG_WARN, tts_tag(), "[Player WARNING] stop old player (%d)", g_playing_info->uid);
778                         ttsd_player_stop(g_playing_info->uid);
779                 }
780         }
781
782         SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%d)", uid);
783
784         /* Check sound queue size */
785         if (0 == ttsd_data_get_sound_data_size(uid)) {
786                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
787                 return -1;
788         }
789
790         /* Check uid */
791         player_s* current;
792         current = __player_get_item(uid);
793         if (NULL == current) {
794                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
795                 return -1;
796         }
797
798         current->state = APP_STATE_PLAYING;
799
800         g_playing_info = current;
801
802         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
803
804         if (0 < ttsd_data_get_sound_data_size(current->uid)) {
805                 SLOG(LOG_DEBUG, tts_tag(), "[Player] Run thread");
806                 ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
807         }
808
809         return 0;
810 }
811
812 int ttsd_player_stop(int uid)
813 {
814         if (false == g_player_init) {
815                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
816                 return -1;
817         }
818
819         /* Check uid */
820         player_s* current;
821         current = __player_get_item(uid);
822         if (NULL == current) {
823                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
824                 return -1;
825         }
826
827         /* check whether uid is current playing or not */
828         if (NULL != g_playing_info) {
829                 if (uid == g_playing_info->uid) {
830                         /* release current playing info */
831                         g_playing_info = NULL;
832                 }
833         } else {
834                 SLOG(LOG_DEBUG, tts_tag(), "[Player] No current playing");
835         }
836
837         if (true == current->is_paused_data) {
838                 if (NULL != current->paused_data) {
839                         if (NULL != current->paused_data->data) {
840                                 free(current->paused_data->data);
841                                 current->paused_data->data = NULL;
842                         }
843
844                         free(current->paused_data);
845                         current->paused_data = NULL;
846                 }
847         }
848
849         current->event = TTSE_RESULT_EVENT_FINISH;
850         current->state = APP_STATE_READY;
851         current->is_paused_data = false;
852         current->idx = 0;
853
854         if (NULL == g_playing_info) {
855                 SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
856                 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
857                 SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
858
859                 /* The thread should be released */
860                 int thread_count = ecore_thread_active_get();
861                 int count = 0;
862                 while (0 < thread_count) {
863                         usleep(10000);
864
865                         count++;
866                         if (30 == count) {
867                                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
868                                 break;
869                         }
870
871                         thread_count = ecore_thread_active_get();
872                 }
873
874                 SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
875                 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
876                 SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
877         }
878
879         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Stop player : uid(%d)", uid);
880
881         return 0;
882 }
883
884 int ttsd_player_clear(int uid)
885 {
886         if (false == g_player_init) {
887                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
888                 return -1;
889         }
890
891         /* Check uid */
892         player_s* current;
893         current = __player_get_item(uid);
894         if (NULL == current) {
895                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid); 
896                 return -1;
897         }
898
899         if (true == current->is_paused_data) {
900                 if (NULL != current->paused_data) {
901                         if (NULL != current->paused_data->data) {
902                                 free(current->paused_data->data);
903                                 current->paused_data->data = NULL;
904                         }
905
906                         free(current->paused_data);
907                         current->paused_data = NULL;
908                 }
909         }
910
911         current->event = TTSE_RESULT_EVENT_FINISH;
912         current->state = APP_STATE_READY;
913         current->is_paused_data = false;
914         current->idx = 0;
915
916         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Clear player : uid(%d)", uid);
917
918         return 0;
919 }
920
921 int ttsd_player_pause(int uid)
922 {
923         SLOG(LOG_DEBUG, tts_tag(), "[Player] pause player : uid(%d)", uid);
924
925         if (false == g_player_init) {
926                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
927                 return -1;
928         }
929
930         /* Check uid */
931         player_s* current;
932         current = __player_get_item(uid);
933         if (NULL == current) {
934                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] ttsd_player_pause() : uid(%d) is not valid", uid);
935                 return -1;
936         }
937
938         /* check whether uid is current playing or not */
939         if (NULL != g_playing_info) {
940                 if (uid == g_playing_info->uid) {
941                         /* release current playing info */
942                         g_playing_info = NULL;
943                 } else {
944                         /* error case */
945                 }
946         }
947
948         current->state = APP_STATE_PAUSED;
949         
950         SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
951         SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
952         SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
953
954         /* The thread should be released */
955         int thread_count = ecore_thread_active_get();
956         int count = 0;
957         while (0 < thread_count) {
958                 usleep(10000);
959
960                 count++;
961                 if (30 == count) {
962                         SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
963                         break;
964                 }
965
966                 thread_count = ecore_thread_active_get();
967         }
968
969         SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
970         SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
971         SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
972
973         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Pause player : uid(%d)", uid);
974
975         return 0;
976 }
977
978 int ttsd_player_resume(int uid)
979 {
980         SLOG(LOG_DEBUG, tts_tag(), "[Player] Resume player : uid(%d)", uid);
981
982         if (false == g_player_init) {
983                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
984                 return -1;
985         }
986
987         /* Check id */
988         player_s* current;
989         current = __player_get_item(uid);
990         if (NULL == current) {
991                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
992                 return -1;
993         }
994
995         /* check current player */
996         if (NULL != g_playing_info)
997                 g_playing_info = NULL;
998
999         current->state = APP_STATE_PLAYING;
1000         g_playing_info = current;
1001
1002         SLOG(LOG_DEBUG, tts_tag(), "[Player] Run thread");
1003         ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
1004
1005         return 0;
1006 }
1007
1008 int ttsd_player_all_stop()
1009 {
1010         if (false == g_player_init) {
1011                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1012                 return -1;
1013         }
1014
1015         g_playing_info = NULL;
1016
1017         GList *iter = NULL;
1018         player_s *data = NULL;
1019
1020         if (0 < g_list_length(g_player_list)) {
1021                 /* Get a first item */
1022                 iter = g_list_first(g_player_list);
1023
1024                 while (NULL != iter) {
1025                         /* Get handle data from list */
1026                         data = (player_s*)iter->data;
1027
1028                         app_state_e state;
1029                         if (0 > ttsd_data_get_client_state(data->uid, &state)) {
1030                                 SLOG(LOG_ERROR, tts_tag(), "[player ERROR] uid(%d) is not valid", data->uid);
1031                                 ttsd_player_destroy_instance(data->uid);
1032                                 iter = g_list_next(iter);
1033                                 continue;
1034                         }
1035
1036                         if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
1037                                 data->event = TTSE_RESULT_EVENT_FINISH;
1038                                 data->state = APP_STATE_READY;
1039
1040                                 if (true == data->is_paused_data) {
1041                                         if (NULL != data->paused_data) {
1042                                                 if (NULL != data->paused_data->data) {
1043                                                         free(data->paused_data->data);
1044                                                         data->paused_data->data = NULL;
1045                                                 }
1046
1047                                                 free(data->paused_data);
1048                                                 data->paused_data = NULL;
1049                                         }
1050                                 }
1051
1052                                 data->is_paused_data = false;
1053                                 data->idx = 0;
1054                         }
1055
1056                         /* Get next item */
1057                         iter = g_list_next(iter);
1058                 }
1059         }
1060
1061         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] player all stop!!");
1062
1063         return 0;
1064 }