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