Add memory releaser in ttsd_player.c
[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_INFO, 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_INFO, tts_tag(), "[Player] Resume thread");
316                                                 break;
317                                         }
318                                 }
319
320                                 SLOG(LOG_INFO, tts_tag(), "[Player] Finish to wait for new audio data come");
321
322                                 /* set volume policy as 40%, when resume play thread*/
323                                 __set_policy_for_playing(40);
324
325                                 /* resume play thread */
326                                 player->state = APP_STATE_PLAYING;
327                                 continue;
328                         }
329
330                         /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
331                          * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
332                          * When previous wdata's event is 'finish' and current wdata's event is 'finish',
333                          * the player should send utt started event.
334                          */
335                         if (TTSE_RESULT_EVENT_START == sound_data->event ||
336                            (TTSE_RESULT_EVENT_FINISH == player->event && TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
337                                 int pid = ttsd_data_get_pid(player->uid);
338
339                                 if (pid <= 0) {
340                                         SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
341                                         /* unset volume policy, volume will be 100% */
342                                         __unset_policy_for_playing();
343
344                                         if (NULL != sound_data->data) {
345                                                 free(sound_data->data);
346                                                 sound_data->data = NULL;
347                                         }
348                                         free(sound_data);
349                                         sound_data = NULL;
350                                         return;
351                                 }
352
353                                 if (0 != ttsdc_send_utt_start_message(pid, player->uid, sound_data->utt_id)) {
354                                         SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%d), uttid(%d)", 
355                                                 pid, player->uid, sound_data->utt_id);
356                                 }
357                                 SLOG(LOG_INFO, tts_tag(), "[Player] Start utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
358                         }
359
360                         /* Save last event to check utterance start */
361                         player->event = sound_data->event;
362                         idx = 0;
363
364                         if (NULL == sound_data->data || 0 >= sound_data->data_size) {
365                                 if (TTSE_RESULT_EVENT_FINISH == sound_data->event) {
366                                         SLOG(LOG_DEBUG, tts_tag(), "No sound data");
367                                         /* send utterence finish signal */
368                                         int pid = ttsd_data_get_pid(player->uid);
369
370                                         if (pid <= 0) {
371                                                 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
372                                                 /* unset volume policy, volume will be 100% */
373                                                 __unset_policy_for_playing();
374                                                 if (NULL != sound_data->data) {
375                                                         free(sound_data->data);
376                                                         sound_data->data = NULL;
377                                                 }
378                                                 free(sound_data);
379                                                 sound_data = NULL;
380                                                 return;
381                                         }
382                                         if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
383                                                 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", 
384                                                         pid, player->uid, sound_data->utt_id);
385                                         }
386                                 }
387                                 SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
388                                 if (NULL != sound_data->data) {
389                                         free(sound_data->data);
390                                         sound_data->data = NULL;
391                                 }
392                                 free(sound_data);
393                                 sound_data = NULL;
394                                 continue;
395                         }
396                 }
397
398                 if (g_sampling_rate != sound_data->rate || g_audio_type != sound_data->audio_type) {
399                         SLOG(LOG_DEBUG, tts_tag(), "[Player] Change audio handle : org type(%d) org rate(%d)", g_audio_type, g_sampling_rate);
400                         if (NULL != g_audio_h) {
401                                 __destroy_audio_out();
402                         }
403
404                         if (0 > __create_audio_out(sound_data->audio_type, sound_data->rate)) {
405                                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio out");
406                                 /* unset volume policy, volume will be 100% */
407                                 __unset_policy_for_playing();
408
409                                 if (NULL != sound_data->data) {
410                                         free(sound_data->data);
411                                         sound_data->data = NULL;
412                                 }
413                                 free(sound_data);
414                                 sound_data = NULL;
415
416                                 return;
417                         }
418                         __set_policy_for_playing(40);
419                 }
420
421                 while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) {
422                         if ((unsigned int)idx >= sound_data->data_size)
423                                 break;
424
425                         if ((unsigned int)idx + SOUND_BUFFER_LENGTH > sound_data->data_size) {
426                                 len = sound_data->data_size - idx;
427                         } else {
428                                 len = SOUND_BUFFER_LENGTH;
429                         }
430
431                         if (AUDIO_STATE_READY == g_audio_state) {
432                                 /* Request prepare */
433                                 ret = audio_out_prepare(g_audio_h);
434                                 if (AUDIO_IO_ERROR_NONE != ret) {
435                                         SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to prepare audio : %d", ret);
436                                         g_playing_info = NULL;
437                                         /* unset volume policy, volume will be 100% */
438                                         __unset_policy_for_playing();
439
440                                         if (NULL != sound_data->data) {
441                                                 free(sound_data->data);
442                                                 sound_data->data = NULL;
443                                         }
444
445                                         free(sound_data);
446                                         sound_data = NULL;
447
448                                         return;
449                                 }
450                                 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Prepare audio");
451                                 g_audio_state = AUDIO_STATE_PLAY;
452                         }
453
454                         char* temp_data = sound_data->data;
455                         ret = audio_out_write(g_audio_h, &temp_data[idx], len);
456                         if (0 > ret) {
457                                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to audio write - %d", ret);
458                         } else {
459                                 idx += len;
460                         }
461
462                         if (NULL == g_playing_info && APP_STATE_PAUSED != player->state) {
463                                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
464                                 g_audio_state = AUDIO_STATE_READY;
465                                 ret = audio_out_unprepare(g_audio_h);
466                                 if (AUDIO_IO_ERROR_NONE != ret) {
467                                         SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
468                                 }
469                                 /* unset volume policy, volume will be 100% */
470                                 __unset_policy_for_playing();
471
472                                 if (NULL != sound_data) {
473                                         if (NULL != sound_data->data) {
474                                                 free(sound_data->data);
475                                                 sound_data->data = NULL;
476                                         }
477
478                                         free(sound_data);
479                                         sound_data = NULL;
480                                 }
481
482                                 return;
483                         }
484
485                         if (APP_STATE_PAUSED == player->state) {
486                                 /* Save data */
487                                 player->paused_data = sound_data;
488
489                                 player->is_paused_data = true;
490                                 player->idx = idx;
491
492                                 g_audio_state = AUDIO_STATE_READY;
493                                 SLOG(LOG_INFO, tts_tag(), "[Player] Stop player thread by pause");
494
495                                 /* Request prepare */
496                                 ret = audio_out_unprepare(g_audio_h);
497                                 if (AUDIO_IO_ERROR_NONE != ret) {
498                                         SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
499                                 } else {
500                                         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
501                                 }
502                                 /* unset volume policy, volume will be 100% */
503                                 __unset_policy_for_playing();
504                                 return;
505                         }
506                 }
507
508                 if (NULL == g_playing_info && APP_STATE_READY == player->state) {
509                         /* player_stop */ 
510                         g_audio_state = AUDIO_STATE_READY;
511                         SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread");
512
513                         /* Request prepare */
514                         ret = audio_out_unprepare(g_audio_h);
515                         if (AUDIO_IO_ERROR_NONE != ret) {
516                                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
517                         } else {
518                                 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
519                         }
520
521                         if (NULL != sound_data) {
522                                 if (NULL != sound_data->data) {
523                                         free(sound_data->data);
524                                         sound_data->data = NULL;
525                                 }
526
527                                 free(sound_data);
528                                 sound_data = NULL;
529                         }
530                         /* unset volume policy, volume will be 100% */
531                         __unset_policy_for_playing();
532                         return;
533                 }
534
535                 if ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) &&
536                         (TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
537                         /* send utterence finish signal */
538                         int pid = ttsd_data_get_pid(player->uid);
539
540                         if (pid <= 0) {
541                                 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
542                                 /* unset volume policy, volume will be 100% */
543                                 __unset_policy_for_playing();
544                                 if (NULL != sound_data->data) {
545                                         free(sound_data->data);
546                                         sound_data->data = NULL;
547                                 }
548
549                                 free(sound_data);
550                                 sound_data = NULL;
551                                 return;
552                         }
553
554                         if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
555                                 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", 
556                                         pid, player->uid, sound_data->utt_id);
557                                 /* unset volume policy, volume will be 100% */
558                                 __unset_policy_for_playing();
559                                 if (NULL != sound_data->data) {
560                                         free(sound_data->data);
561                                         sound_data->data = NULL;
562                                 }
563
564                                 free(sound_data);
565                                 sound_data = NULL;
566                                 return;
567                         }
568
569                         SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
570                 }
571
572                 if (NULL != sound_data) {
573                         if (NULL != sound_data->data) {
574                                 free(sound_data->data);
575                                 sound_data->data = NULL;
576                         }
577
578                         free(sound_data);
579                         sound_data = NULL;
580                 }
581
582                 if (NULL == g_playing_info) {
583                         SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
584                         g_audio_state = AUDIO_STATE_READY;
585                         ret = audio_out_unprepare(g_audio_h);
586                         if (AUDIO_IO_ERROR_NONE != ret) {
587                                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
588                         }
589                         /* unset volume policy, volume will be 100% */
590                         __unset_policy_for_playing();
591
592                         return;
593                 }
594         }
595 }
596
597 /*
598 * Player Interfaces
599 */
600 int ttsd_player_init()
601 {
602         g_playing_info = NULL;
603         g_audio_state = AUDIO_STATE_NONE;
604         g_audio_h = NULL;
605
606         int ret;
607
608         ecore_thread_max_set(1);
609
610         int cnt = 0;
611         while (1) {
612                 if (0 == access(FOCUS_SERVER_READY, F_OK)) {
613                         SLOG(LOG_ERROR, tts_tag(), "[Player SUCCESS] focus server is available");
614                         break;
615                 } else {
616                         if (0 == cnt++ % 10)
617                                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] focus server is not available");
618                         usleep(50000);
619                 }
620         }
621
622         ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_INFORMATION, __player_focus_state_cb, NULL, &g_stream_info_h);
623         if (SOUND_MANAGER_ERROR_NONE != ret) {
624                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create stream info");
625                 return -1;
626         } else {
627                 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create stream info");
628         }
629
630         ecore_thread_max_set(1);
631
632         ret = __create_audio_out(TTSE_AUDIO_TYPE_RAW_S16, 16000);
633         if (0 != ret)
634                 return -1;
635
636         g_player_init = true;
637
638         return 0;
639 }
640
641 int ttsd_player_release(void)
642 {
643         if (false == g_player_init) {
644                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
645                 return TTSD_ERROR_OPERATION_FAILED;
646         }
647
648         int ret;
649
650         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] ==========================");
651         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
652         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] ==========================");
653
654         /* The thread should be released */
655         int thread_count = ecore_thread_active_get();
656         int count = 0;
657         while (0 < thread_count) {
658                 usleep(10000);
659
660                 count++;
661                 if (20 == count) {
662                         SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
663                         break;
664                 }
665
666                 thread_count = ecore_thread_active_get();
667         }
668
669         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Thread is released");
670
671         ret = __destroy_audio_out();
672         if (0 != ret)
673                 return -1;
674
675         ret = sound_manager_destroy_stream_information(g_stream_info_h);
676         if (SOUND_MANAGER_ERROR_NONE != ret) {
677                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy stream info");
678         } else {
679                 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy stream info");
680         }
681
682         /* clear g_player_list */
683         g_playing_info = NULL;
684         g_player_init = false;
685
686         return 0;
687 }
688
689 int ttsd_player_create_instance(int uid)
690 {
691         if (false == g_player_init) {
692                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
693                 return -1;
694         }
695
696         /* Check uid is duplicated */
697         if (NULL != __player_get_item(uid)) {
698                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is already registered", uid);
699                 return -1;
700         }
701
702         player_s* new_client = (player_s*)calloc(1, sizeof(player_s));
703         if (NULL == new_client) {
704                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to allocate memory");
705                 return TTSE_ERROR_OUT_OF_MEMORY;
706         }
707
708         new_client->uid = uid;
709         new_client->event = TTSE_RESULT_EVENT_FINISH;
710         new_client->state = APP_STATE_READY;
711         new_client->is_paused_data = false;
712         new_client->idx = 0;
713         new_client->paused_data = NULL;
714         
715         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Player] Create player : uid(%d)", uid);
716
717         g_player_list = g_list_append(g_player_list, new_client);
718
719         return 0;
720 }
721
722 int ttsd_player_destroy_instance(int uid)
723 {
724         if (false == g_player_init) {
725                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
726                 return -1;
727         }
728
729         player_s* current;
730         current = __player_get_item(uid);
731         if (NULL == current) {
732                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
733                 return -1;
734         }
735
736         if (NULL != g_playing_info) {
737                 if (uid == g_playing_info->uid) {
738                         g_playing_info = NULL;
739                 }
740         }
741
742         GList *iter = NULL;
743         player_s *data = NULL;
744
745         if (0 < g_list_length(g_player_list)) {
746                 /* Get a first item */
747                 iter = g_list_first(g_player_list);
748
749                 while (NULL != iter) {
750                         /* Get handle data from list */
751                         data = (player_s*)iter->data;
752
753                         if (NULL != data) {
754                                 /* compare uid */
755                                 if (uid == data->uid) {
756                                         g_player_list = g_list_remove_link(g_player_list, iter);
757                                         free(data);
758                                         g_list_free(iter);              
759                                         break;
760                                 }
761                         }
762
763                         /* Get next item */
764                         iter = g_list_next(iter);
765                 }
766         }
767
768         SLOG(LOG_DEBUG, tts_tag(), "[PLAYER Success] Destroy instance");
769
770         return 0;
771 }
772
773 int ttsd_player_play(int uid)
774 {
775         if (false == g_player_init) {
776                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
777                 return -1;
778         }
779
780         if (NULL != g_playing_info) {
781                 if (uid == g_playing_info->uid) {
782                         SLOG(LOG_DEBUG, tts_tag(), "[Player] uid(%d) has already played", g_playing_info->uid);
783                         return 0;
784                 } else {
785                         SLOG(LOG_WARN, tts_tag(), "[Player WARNING] stop old player (%d)", g_playing_info->uid);
786                         ttsd_player_stop(g_playing_info->uid);
787                 }
788         }
789
790         SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%d)", uid);
791
792         /* Check sound queue size */
793         if (0 == ttsd_data_get_sound_data_size(uid)) {
794                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
795                 return -1;
796         }
797
798         /* Check uid */
799         player_s* current;
800         current = __player_get_item(uid);
801         if (NULL == current) {
802                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
803                 return -1;
804         }
805
806         current->state = APP_STATE_PLAYING;
807
808         g_playing_info = current;
809
810         SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
811
812         if (0 < ttsd_data_get_sound_data_size(current->uid)) {
813                 SLOG(LOG_INFO, tts_tag(), "[Player] Run thread");
814                 ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
815         }
816
817         return 0;
818 }
819
820 int ttsd_player_stop(int uid)
821 {
822         if (false == g_player_init) {
823                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
824                 return -1;
825         }
826
827         /* Check uid */
828         player_s* current;
829         current = __player_get_item(uid);
830         if (NULL == current) {
831                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
832                 return -1;
833         }
834
835         /* check whether uid is current playing or not */
836         if (NULL != g_playing_info) {
837                 if (uid == g_playing_info->uid) {
838                         /* release current playing info */
839                         g_playing_info = NULL;
840                 }
841         } else {
842                 SLOG(LOG_DEBUG, tts_tag(), "[Player] No current playing");
843         }
844
845         if (true == current->is_paused_data) {
846                 if (NULL != current->paused_data) {
847                         if (NULL != current->paused_data->data) {
848                                 free(current->paused_data->data);
849                                 current->paused_data->data = NULL;
850                         }
851
852                         free(current->paused_data);
853                         current->paused_data = NULL;
854                 }
855         }
856
857         current->event = TTSE_RESULT_EVENT_FINISH;
858         current->state = APP_STATE_READY;
859         current->is_paused_data = false;
860         current->idx = 0;
861
862         if (NULL == g_playing_info) {
863                 SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
864                 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
865                 SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
866
867                 /* The thread should be released */
868                 int thread_count = ecore_thread_active_get();
869                 int count = 0;
870                 while (0 < thread_count) {
871                         usleep(10000);
872
873                         count++;
874                         if (30 == count) {
875                                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
876                                 break;
877                         }
878
879                         thread_count = ecore_thread_active_get();
880                 }
881
882                 SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
883                 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
884                 SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
885         }
886
887         SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Stop player : uid(%d)", uid);
888
889         return 0;
890 }
891
892 int ttsd_player_clear(int uid)
893 {
894         if (false == g_player_init) {
895                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
896                 return -1;
897         }
898
899         /* Check uid */
900         player_s* current;
901         current = __player_get_item(uid);
902         if (NULL == current) {
903                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid); 
904                 return -1;
905         }
906
907         if (true == current->is_paused_data) {
908                 if (NULL != current->paused_data) {
909                         if (NULL != current->paused_data->data) {
910                                 free(current->paused_data->data);
911                                 current->paused_data->data = NULL;
912                         }
913
914                         free(current->paused_data);
915                         current->paused_data = NULL;
916                 }
917         }
918
919         current->event = TTSE_RESULT_EVENT_FINISH;
920         current->state = APP_STATE_READY;
921         current->is_paused_data = false;
922         current->idx = 0;
923
924         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Clear player : uid(%d)", uid);
925
926         return 0;
927 }
928
929 int ttsd_player_pause(int uid)
930 {
931         SLOG(LOG_DEBUG, tts_tag(), "[Player] pause player : uid(%d)", uid);
932
933         if (false == g_player_init) {
934                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
935                 return -1;
936         }
937
938         /* Check uid */
939         player_s* current;
940         current = __player_get_item(uid);
941         if (NULL == current) {
942                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] ttsd_player_pause() : uid(%d) is not valid", uid);
943                 return -1;
944         }
945
946         /* check whether uid is current playing or not */
947         if (NULL != g_playing_info) {
948                 if (uid == g_playing_info->uid) {
949                         /* release current playing info */
950                         g_playing_info = NULL;
951                 } else {
952                         /* error case */
953                 }
954         }
955
956         current->state = APP_STATE_PAUSED;
957         
958         SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
959         SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
960         SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
961
962         /* The thread should be released */
963         int thread_count = ecore_thread_active_get();
964         int count = 0;
965         while (0 < thread_count) {
966                 usleep(10000);
967
968                 count++;
969                 if (30 == count) {
970                         SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
971                         break;
972                 }
973
974                 thread_count = ecore_thread_active_get();
975         }
976
977         SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
978         SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
979         SLOG(LOG_DEBUG, tts_tag(), "[Player] ==========================");
980
981         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Pause player : uid(%d)", uid);
982
983         return 0;
984 }
985
986 int ttsd_player_resume(int uid)
987 {
988         SLOG(LOG_DEBUG, tts_tag(), "[Player] Resume player : uid(%d)", uid);
989
990         if (false == g_player_init) {
991                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
992                 return -1;
993         }
994
995         /* Check id */
996         player_s* current;
997         current = __player_get_item(uid);
998         if (NULL == current) {
999                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
1000                 return -1;
1001         }
1002
1003         /* check current player */
1004         if (NULL != g_playing_info)
1005                 g_playing_info = NULL;
1006
1007         current->state = APP_STATE_PLAYING;
1008         g_playing_info = current;
1009
1010         SLOG(LOG_INFO, tts_tag(), "[Player] Resume to run thread");
1011         ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
1012
1013         return 0;
1014 }
1015
1016 int ttsd_player_all_stop()
1017 {
1018         if (false == g_player_init) {
1019                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1020                 return -1;
1021         }
1022
1023         g_playing_info = NULL;
1024
1025         GList *iter = NULL;
1026         player_s *data = NULL;
1027
1028         if (0 < g_list_length(g_player_list)) {
1029                 /* Get a first item */
1030                 iter = g_list_first(g_player_list);
1031
1032                 while (NULL != iter) {
1033                         /* Get handle data from list */
1034                         data = (player_s*)iter->data;
1035
1036                         app_state_e state;
1037                         if (0 > ttsd_data_get_client_state(data->uid, &state)) {
1038                                 SLOG(LOG_ERROR, tts_tag(), "[player ERROR] uid(%d) is not valid", data->uid);
1039                                 ttsd_player_destroy_instance(data->uid);
1040                                 iter = g_list_next(iter);
1041                                 continue;
1042                         }
1043
1044                         if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
1045                                 data->event = TTSE_RESULT_EVENT_FINISH;
1046                                 data->state = APP_STATE_READY;
1047
1048                                 if (true == data->is_paused_data) {
1049                                         if (NULL != data->paused_data) {
1050                                                 if (NULL != data->paused_data->data) {
1051                                                         free(data->paused_data->data);
1052                                                         data->paused_data->data = NULL;
1053                                                 }
1054
1055                                                 free(data->paused_data);
1056                                                 data->paused_data = NULL;
1057                                         }
1058                                 }
1059
1060                                 data->is_paused_data = false;
1061                                 data->idx = 0;
1062                         }
1063
1064                         /* Get next item */
1065                         iter = g_list_next(iter);
1066                 }
1067         }
1068
1069         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] player all stop!!");
1070
1071         return 0;
1072 }