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