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