Use AudioStream class on ttsd_player
[platform/core/uifw/tts.git] / server / ttsd_player.cpp
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 <Ecore.h>
15 #include <pthread.h>
16
17 #include "ttsd_main.h"
18 #include "ttsd_player.h"
19 #include "ttsd_data.h"
20 #include "ttsd_dbus.h"
21 #include "ttsd_ipc.h"
22
23 #include "BackgroundVolume.h"
24 #include "AudioStream.h"
25
26 #include "tts_internal.h"
27 #include "ttsd_server.h"
28
29 /*
30 * Internal data structure
31 */
32
33 typedef struct {
34         unsigned int            uid;    /** client id */
35         app_tts_state_e         state;  /** client state */
36
37         /* Current utterance information */
38         ttse_result_event_e     event;  /** event of last utterance */
39
40         bool                    is_paused_data;
41         int                     idx;
42         sound_data_s*           paused_data;
43 } player_s;
44
45 #define SOUND_BUFFER_LENGTH     2048
46
47 static const intptr_t CHECK_TIMER_DELETE = 1;
48 static const int EXTRA_INFO_LENGTH = 20;
49
50 /* Sound buf save for test */
51 /*
52 #define BUF_SAVE_MODE
53 */
54
55 #ifdef BUF_SAVE_MODE
56 static char g_temp_file_name[128] = {'\0',};
57 static FILE* g_pFile;
58 static int g_count = 0;
59 static pthread_mutex_t g_buf_save_mutex = PTHREAD_MUTEX_INITIALIZER;
60 #endif
61
62 /** player init info */
63 static bool g_player_init = false;
64
65 /** Client list */
66 static GList *g_player_list;
67
68 /** current player information */
69 static player_s* g_playing_info;
70
71 static bool g_is_set_policy;
72
73 /* CAUTION!
74 If you change this constant value. Please check the function '__set_timer_for_delay_recover()'.
75 If you choose too big value, it may cause integer overflow issue.
76 */
77 #define SND_MGR_DUCKING_DURATION 500
78
79 static pthread_mutex_t g_play_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
80 static pthread_mutex_t g_player_control_mutex = PTHREAD_MUTEX_INITIALIZER;
81
82 static pthread_cond_t g_play_thread_cond = PTHREAD_COND_INITIALIZER;
83
84 static BackgroundVolume* g_background_volume = nullptr;
85 static AudioStream* g_audio_stream = nullptr;
86
87 /*
88 * Internal Interfaces
89 */
90 static void __set_playing_status(bool is_playing)
91 {
92         int ret = vconf_set_bool(TTS_PLAYING_STATUS_KEY, is_playing ? 1 : 0);
93         SLOG(LOG_INFO, tts_tag(), "[Player] Set playing status (%s). ret(%d)", is_playing ? "True" : "False", ret);
94 }
95
96 #ifdef BUF_SAVE_MODE
97 static void __open_buffer_dump_file()
98 {
99         pthread_mutex_lock(&g_buf_save_mutex);
100         if (g_pFile) {
101                 SLOG(LOG_ERROR, tts_tag(), "[Buffer Dump] File is already opened(%s)", g_temp_file_name);
102                 pthread_mutex_unlock(&g_buf_save_mutex);
103                 return;
104         }
105
106         g_count++;
107         while (1) {
108                 snprintf(g_temp_file_name, sizeof(g_temp_file_name), "/tmp/tts_temp_%d_%d", getpid(), g_count);
109                 int ret = access(g_temp_file_name, 0);
110
111                 if (0 == ret) {
112                         SLOG(LOG_ERROR, tts_tag(), "[Recorder ERROR] File is already exist");
113                         if (0 == remove(g_temp_file_name)) {
114                                 SLOG(LOG_DEBUG, tts_tag(), "[Recorder] Remove file");
115                                 break;
116                         } else {
117                                 g_count++;
118                         }
119                 } else {
120                         break;
121                 }
122         }
123
124         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Recorder] Temp file name=[%s]", g_temp_file_name);
125
126         /* open test file */
127         g_pFile = fopen(g_temp_file_name, "wb+x");
128         if (NULL == g_pFile) {
129                 SLOG(LOG_ERROR, tts_tag(), "[Recorder ERROR] File not found!");
130         }
131
132         pthread_mutex_unlock(&g_buf_save_mutex);
133 }
134
135 static void __close_buffer_dump_file()
136 {
137         pthread_mutex_lock(&g_buf_save_mutex);
138
139         if (g_pFile) {
140                 fclose(g_pFile);
141                 g_pFile = NULL;
142         }
143
144         pthread_mutex_unlock(&g_buf_save_mutex);
145 }
146
147 static void __write_buffer_dump_file(const void* buffer, size_t length)
148 {
149         pthread_mutex_lock(&g_buf_save_mutex);
150
151         if (g_pFile) {
152                 size_t ret = fwrite(buffer, 1, length, g_pFile);
153                 SLOG(LOG_DEBUG, tts_tag(), "[Buffer Dump] Stored size(%zu / %zu)", ret, length);
154         } else {
155                 SLOG(LOG_ERROR, tts_tag(), "[Buffer Dump] File is not opened. Please check the file open");
156         }
157
158         pthread_mutex_unlock(&g_buf_save_mutex);
159 }
160 #endif
161
162 static bool __is_player_valid(player_s* player)
163 {
164         if (NULL == player || NULL == g_playing_info) {
165                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] player is NULL");
166                 return false;
167         }
168
169         if (g_playing_info != player || g_playing_info->uid != player->uid) {
170                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] player is not current player");
171                 return false;
172         }
173
174         return true;
175 }
176
177 player_s* __player_get_item(unsigned int uid)
178 {
179         GList *iter = NULL;
180         player_s *data = NULL;
181
182         if (0 < g_list_length(g_player_list)) {
183                 /* Get a first item */
184                 iter = g_list_first(g_player_list);
185
186                 while (NULL != iter) {
187                         /* Get handle data from list */
188                         data = (player_s*)iter->data;
189
190                         /* compare uid */
191                         if (uid == data->uid)
192                                 return data;
193
194                         /* Get next item */
195                         iter = g_list_next(iter);
196                 }
197         }
198
199         return NULL;
200 }
201
202 static void __focus_release_callback()
203 {
204         if (NULL == g_playing_info) {
205                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player");
206                 return;
207         }
208
209         if (APP_STATE_PLAYING != g_playing_info->state) {
210                 return;
211         }
212
213         unsigned int uid = g_playing_info->uid;
214         ttsd_mode_e mode = ttsd_data_get_mode(uid);
215
216         switch (mode) {
217         case TTSD_MODE_DEFAULT:
218                 {
219                         SLOG(LOG_DEBUG, tts_tag(), "[Player] Pause current player - mode(%d)", mode);
220                         if (0 != ttsd_player_pause(uid)) {
221                                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to pause the player");
222                                 break;
223                         }
224
225                         ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
226                         int pid = ttsd_data_get_pid(uid);
227                         if (pid <= 0) {
228                                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to get pid. uid(%u)", uid);
229                         } else {
230                                 /* send message to client about changing state */
231                                 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Player paused. pid(%d), uid(%u)", pid, uid);
232                                 ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_PAUSED);
233                         }
234                         break;
235                 }
236
237         case TTSD_MODE_NOTIFICATION:
238         case TTSD_MODE_SCREEN_READER:
239                 {
240                         SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop current player - mode(%d)", mode);
241                         ttsd_send_all_stop();
242                         break;
243                 }
244
245         case TTSD_MODE_INTERRUPT:
246                 SLOG(LOG_DEBUG, tts_tag(), "[Player] Ignore focus release - mode(%d)", mode);
247                 break;
248
249         default:
250                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Invalid mode - mode(%d)", mode);
251                 break;
252         }
253
254         SLOG(LOG_DEBUG, tts_tag(), "@@@");
255
256         return;
257 }
258
259 static void __end_play_thread(void *data, Ecore_Thread *thread)
260 {
261         SLOG(LOG_ERROR, tts_tag(), "@@@ End thread");
262 }
263
264 static void __set_policy_for_playing(void)
265 {
266         const char* extra_info = NULL;
267         if (TTSD_MODE_INTERRUPT == ttsd_get_mode()) {
268                 extra_info = "TTSD_MODE_INTERRUPT";
269         }
270
271         g_audio_stream->acquireSoundFocus(extra_info);
272         g_background_volume->applyVolumeRatio();
273         g_is_set_policy = true;
274         SLOG(LOG_ERROR, tts_tag(), "[BG] g_is_set_policy(%d)", g_is_set_policy);
275         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] set policy for playing");
276
277         return;
278 }
279
280 static void __unset_policy_for_playing()
281 {
282         g_audio_stream->releaseSoundFocus();
283         g_background_volume->recoverVolumeRatio();
284         g_is_set_policy = false;
285         SLOG(LOG_ERROR, tts_tag(), "[BG] g_is_set_policy(%d)", g_is_set_policy);
286         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] unset policy for playing");
287
288         return;
289 }
290
291 static bool __does_interrupt_have_focus(sound_stream_focus_change_reason_e reason, int sound_behavior, char *extra_info)
292 {
293         SLOG(LOG_DEBUG, tts_tag(), "[Player] current Playback focus: extra_info(%s), reason(%d), sound_behavior(%d)", extra_info, reason, sound_behavior);
294         if (SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION != reason) {
295                 return false;
296         }
297
298         if (NULL == extra_info || 0 >= strlen(extra_info) || 0 != strncmp(extra_info, "TTSD_MODE_INTERRUPT", EXTRA_INFO_LENGTH)) {
299                 return false;
300         }
301
302         return true;
303 }
304
305 bool ttsd_player_does_interrupt_have_playback_focus()
306 {
307         sound_stream_focus_change_reason_e reason;
308         int sound_behavior = 0;
309         char *extra_info = NULL;
310         if (SOUND_MANAGER_ERROR_NONE != sound_manager_get_current_playback_focus(&reason, &sound_behavior, &extra_info)) {
311                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to get focus information");
312                 return false;
313         }
314
315         bool result = __does_interrupt_have_focus(reason, sound_behavior, extra_info);
316         free(extra_info);
317         return result;
318 }
319
320 static void __play_thread_old(void *data, Ecore_Thread *thread)
321 {
322         SLOG(LOG_DEBUG, tts_tag(), "@@@ Start thread");
323
324         if (NULL == g_playing_info) {
325                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] No current player");
326                 return;
327         }
328
329         player_s* player = g_playing_info;
330         sound_data_s* sound_data = NULL;
331
332         int ret = -1;
333         int len = SOUND_BUFFER_LENGTH;
334         int idx = 0;
335
336         /* set volume policy as 40% */
337         __set_policy_for_playing();
338         while (1) { // 1st while(1)
339                 /* check g_playing_info one more time */
340                 if (false == __is_player_valid(player)) {
341                         SLOG(LOG_INFO, tts_tag(), "[Player INFO] Player is not valid");
342                         g_audio_stream->unprepareAudioOut();
343                         __unset_policy_for_playing();
344                         return;
345                 }
346
347                 if (true == player->is_paused_data && NULL != player->paused_data) {
348                         /* Resume player */
349                         sound_data_s* paused_data = player->paused_data;
350                         player->paused_data = NULL;
351
352                         ttsd_data_destroy_sound_data(sound_data);
353                         sound_data = ttsd_data_create_sound_data(paused_data->utt_id, paused_data->data, paused_data->data_size,
354                                         paused_data->event, paused_data->audio_type, paused_data->rate, paused_data->channels);
355                         if (NULL == sound_data || paused_data->data_size <= 0) {
356                                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Out of memory OR paused_data is empty");
357                                 ttsd_data_destroy_sound_data(sound_data);
358                                 sound_data = paused_data;
359                         } else { // NULL != sound_data && NULL != temp && player->paused_data->data_size > 0
360                                 ttsd_data_destroy_sound_data(paused_data);
361                         }
362
363                         idx = player->idx;
364
365                         player->is_paused_data = false;
366                         player->idx = 0;
367
368                         if (NULL == sound_data) {
369                                 /* Request unprepare */
370                                 g_audio_stream->unprepareAudioOut();
371
372                                 /* unset volume policy, volume will be 100% */
373                                 __unset_policy_for_playing();
374                                 return;
375                         }
376                         __set_playing_status(true);
377
378                         SLOG(LOG_INFO, tts_tag(), "[Player] Sound info : id(%d) data(%p) size(%d) audiotype(%d) rate(%d) event(%d)",
379                                 sound_data->utt_id, sound_data->data, sound_data->data_size, sound_data->audio_type, sound_data->rate, sound_data->event);
380                 } else { // NO player->is_paused_data
381                         sound_data = NULL;
382                         ret = ttsd_data_get_sound_data(player->uid, &sound_data);
383                         if (0 != ret || NULL == sound_data) {
384                                 /* empty queue */
385                                 SLOG(LOG_ERROR, tts_tag(), "[Player] No sound data. Waiting mode");
386
387                                 /* wait for new audio data come */
388                                 while (1) { // 2nd while(1)
389                                         usleep(10000);
390                                         if (false == __is_player_valid(player)) {
391                                                 /* current playing uid is replaced */
392                                                 SLOG(LOG_INFO, tts_tag(), "[Player] Finish thread");
393                                                 if (AudioStream::AUDIO_STATE_PLAY == g_audio_stream->getState()) {
394                                                         /* release audio & recover session */
395                                                         g_audio_stream->unprepareAudioOut();
396                                                 }
397                                                 /* unset volume policy, volume will be 100% */
398                                                 __unset_policy_for_playing();
399                                                 return;
400                                         } else if (0 < ttsd_data_get_sound_data_size(player->uid)) {
401                                                 /* new audio data come */
402                                                 SLOG(LOG_INFO, tts_tag(), "[Player] Resume thread");
403                                                 break; // exit from 2nd while(1)
404                                         }
405
406                                         /* If engine is not on processing */
407                                         ttsd_synthesis_control_e synth_control = ttsd_get_synth_control();
408                                         if (TTSD_SYNTHESIS_CONTROL_DOING != synth_control) {
409                                                 SLOG(LOG_INFO, tts_tag(), "[Server INFO] synth_control(%d)", synth_control);
410                                                 if (AudioStream::AUDIO_STATE_PLAY == g_audio_stream->getState()) {
411                                                         /* release audio & recover session */
412                                                         g_audio_stream->unprepareAudioOut();
413
414                                                         /* unset volume policy, volume will be 100% */
415                                                         __unset_policy_for_playing();
416                                                 }
417                                         }
418                                 } // end of 2nd while(1). waiting for new audio data come
419
420                                 SLOG(LOG_INFO, tts_tag(), "[Player] Finish to wait for new audio data come");
421
422                                 if (AudioStream::AUDIO_STATE_READY == g_audio_stream->getState() || AudioStream::AUDIO_STATE_WAIT_FOR_PLAYING == g_audio_stream->getState()) {
423                                         /* set volume policy as 40%, when resume play thread*/
424                                         __set_policy_for_playing();
425                                 }
426
427                                 /* resume play thread */
428                                 player->state = APP_STATE_PLAYING;
429                                 continue;
430                         } // NULL == sound_data
431
432                         /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
433                          * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
434                          * When previous wdata's event is 'finish' and current wdata's event is 'finish',
435                          * the player should send utt started event.
436                          */
437                         if (TTSE_RESULT_EVENT_START == sound_data->event ||
438                            (TTSE_RESULT_EVENT_FINISH == player->event && TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
439                                 int pid = ttsd_data_get_pid(player->uid);
440                                 if (pid <= 0) {
441                                         SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid);
442                                         /* unset volume policy, volume will be 100% */
443                                         __unset_policy_for_playing();
444                                         ttsd_data_destroy_sound_data(sound_data);
445                                         sound_data = NULL;
446                                         return;
447                                 }
448
449 #ifdef BUF_SAVE_MODE
450                                 __open_buffer_dump_file();
451 #endif
452
453                                 __set_playing_status(true);
454                                 if (0 != ttsdc_ipc_send_utt_start_message(pid, player->uid, sound_data->utt_id)) {
455                                         SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%u), uttid(%d)",
456                                                 pid, player->uid, sound_data->utt_id);
457                                 }
458                                 SLOG(LOG_INFO, tts_tag(), "[Player] Start utterance : uid(%u), uttid(%d)", player->uid, sound_data->utt_id);
459                         } // (TTSE_RESULT_EVENT_START == sound_data->event || (TTSE_RESULT_EVENT_FINISH == player->event && TTSE_RESULT_EVENT_FINISH == sound_data->event))
460
461                         /* Save last event to check utterance start */
462                         player->event = sound_data->event;
463                         idx = 0;
464
465                         if (NULL == sound_data->data || 0 >= sound_data->data_size) {
466                                 if (TTSE_RESULT_EVENT_FINISH == sound_data->event) {
467                                         SLOG(LOG_DEBUG, tts_tag(), "No sound data");
468                                         /* send utterence finish signal */
469                                         int pid = ttsd_data_get_pid(player->uid);
470
471                                         if (pid <= 0) {
472                                                 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid);
473                                                 /* unset volume policy, volume will be 100% */
474                                                 __unset_policy_for_playing();
475                                                 ttsd_data_destroy_sound_data(sound_data);
476                                                 sound_data = NULL;
477                                                 return;
478                                         }
479
480                                         __unset_policy_for_playing();
481
482 #ifdef BUF_SAVE_MODE
483                                         __close_buffer_dump_file();
484 #endif
485
486                                         __set_playing_status(false);
487                                         if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
488                                                 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%u), uttid(%d)",
489                                                         pid, player->uid, sound_data->utt_id);
490                                         } else {
491                                                 SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, sound_data->utt_id);
492                                         }
493                                 } // TTSE_RESULT_EVENT_FINISH == sound_data->event
494                                 SLOG(LOG_INFO, tts_tag(), "[Player] Event(%d) utterance : uid(%u), uttid(%d)", sound_data->event, player->uid, sound_data->utt_id);
495                                 ttsd_data_destroy_sound_data(sound_data);
496                                 sound_data = NULL;
497                                 continue;
498                         } // (NULL == sound_data->data || 0 >= sound_data->data_size)
499                 } // NO player->is_paused_data
500
501                 // If there is any change in audio format, recreate audio handle
502                 if (TTSD_ERROR_NONE != g_audio_stream->setAudioFormat(sound_data->audio_type, sound_data->rate)) {
503                         SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio out");
504                         /* unset volume policy, volume will be 100% */
505                         __unset_policy_for_playing();
506
507                         ttsd_data_destroy_sound_data(sound_data);
508                         sound_data = NULL;
509                         return;
510                 }
511
512                 while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) {
513                         if ((unsigned int)idx >= sound_data->data_size)
514                                 break;
515
516                         if ((unsigned int)idx + SOUND_BUFFER_LENGTH > sound_data->data_size) {
517                                 len = sound_data->data_size - idx;
518                         } else {
519                                 len = SOUND_BUFFER_LENGTH;
520                         }
521
522                         // Check whether set_policy is done or not
523                         if (false == g_is_set_policy) {
524                                 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Set policy");
525                                 __set_policy_for_playing();
526                         }
527
528                         if (AudioStream::AUDIO_STATE_READY == g_audio_stream->getState() || AudioStream::AUDIO_STATE_WAIT_FOR_PLAYING == g_audio_stream->getState()) {
529                                 /* Request prepare */
530                                 ret = g_audio_stream->prepareAudioOut();
531                                 if (TTSD_ERROR_NONE != ret) {
532                                         SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to prepare audio : %d", ret);
533
534                                         /* unset volume policy, volume will be 100% */
535                                         __unset_policy_for_playing();
536                                         ttsd_data_destroy_sound_data(sound_data);
537                                         sound_data = NULL;
538                                         return;
539                                 }
540
541                                 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Prepare audio");
542                         }
543
544                         char* temp_data = sound_data->data;
545                         SLOG(LOG_INFO, tts_tag(), "[Player INFO] Before audio_out_write. data(%p), data[%d](%p), uid(%u), utt_id(%d), len(%d)",
546                                         temp_data, idx, &temp_data[idx], player->uid, sound_data->utt_id, len);
547 #ifdef BUF_SAVE_MODE
548                         __write_buffer_dump_file(&temp_data[idx], len);
549 #endif
550                         ret = g_audio_stream->playAudioData(&temp_data[idx], len);
551                         if (TTSD_ERROR_NONE != ret) {
552                                 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to audio write - %d", ret);
553                         } else {
554                                 idx += len;
555                                 SLOG(LOG_INFO, tts_tag(), "[Player INFO] After audio_out_write");
556                         }
557
558                         if (NULL == g_playing_info && APP_STATE_PAUSED != player->state) {
559                                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
560                                 g_audio_stream->unprepareAudioOut();
561                                 /* unset volume policy, volume will be 100% */
562                                 __unset_policy_for_playing();
563
564                                 ttsd_data_destroy_sound_data(sound_data);
565                                 sound_data = NULL;
566                                 return;
567                         } // (NULL == g_playing_info && APP_STATE_PAUSED != player->state)
568
569                         if (APP_STATE_PAUSED == player->state) {
570                                 /* Save data */
571                                 SLOG(LOG_DEBUG, tts_tag(), "[Player] player(%p)", player);
572                                 ttsd_data_destroy_sound_data(player->paused_data);
573                                 player->paused_data = sound_data;
574
575                                 player->is_paused_data = true;
576                                 player->idx = idx;
577
578
579                                 SLOG(LOG_INFO, tts_tag(), "[Player] Stop player thread by pause");
580
581                                 /* Request prepare */
582                                 g_audio_stream->unprepareAudioOut();
583                                 /* unset volume policy, volume will be 100% */
584                                 __unset_policy_for_playing();
585                                 return;
586                         } // (APP_STATE_PAUSED == player->state)
587                 } // while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state)
588
589                 if (NULL == g_playing_info && APP_STATE_READY == player->state) {
590                         /* player_stop */
591                         SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread");
592
593                         /* Request prepare */
594                         g_audio_stream->unprepareAudioOut();
595                         /* unset volume policy, volume will be 100% */
596                         __unset_policy_for_playing();
597                         ttsd_data_destroy_sound_data(sound_data);
598                         sound_data = NULL;
599                         return;
600                 } // (NULL == g_playing_info && APP_STATE_READY == player->state)
601
602                 if ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) &&
603                         (TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
604                         /* send utterence finish signal */
605                         int pid = ttsd_data_get_pid(player->uid);
606
607                         if (pid <= 0) {
608                                 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid);
609                                 /* unset volume policy, volume will be 100% */
610                                 __unset_policy_for_playing();
611                                 ttsd_data_destroy_sound_data(sound_data);
612                                 sound_data = NULL;
613                                 return;
614                         }
615
616 #ifdef BUF_SAVE_MODE
617                         __close_buffer_dump_file();
618 #endif
619                         __set_playing_status(false);
620                         if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
621                                 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%u), uttid(%d)",
622                                         pid, player->uid, sound_data->utt_id);
623                                 /* unset volume policy, volume will be 100% */
624                                 __unset_policy_for_playing();
625                                 ttsd_data_destroy_sound_data(sound_data);
626                                 sound_data = NULL;
627                                 return;
628                         }
629
630                         SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, sound_data->utt_id);
631                 } // ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) && (TTSE_RESULT_EVENT_FINISH == sound_data->event))
632
633                 ttsd_data_destroy_sound_data(sound_data);
634                 sound_data = NULL;
635
636                 if (NULL == g_playing_info) {
637                         SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
638                         g_audio_stream->unprepareAudioOut();
639                         /* unset volume policy, volume will be 100% */
640                         __unset_policy_for_playing();
641                         ttsd_data_destroy_sound_data(sound_data);
642                         sound_data = NULL;
643                         return;
644                 }
645         } // end of 1st while(1)
646 }
647
648 static void __play_thread(void *data, Ecore_Thread *thread)
649 {
650         SLOG(LOG_INFO, tts_tag(), "[Player] play thread is on");
651
652         while (g_player_init) {
653                 SLOG(LOG_INFO, tts_tag(), "[Player] Wait play request...");
654                 pthread_mutex_lock(&g_play_thread_mutex);
655                 pthread_cond_wait(&g_play_thread_cond, &g_play_thread_mutex);
656                 if (false == g_player_init) {
657                         SLOG(LOG_INFO, tts_tag(), "[Player] Player is released");
658                         pthread_mutex_unlock(&g_play_thread_mutex);
659                         break;
660                 }
661
662                 __play_thread_old(data, thread);
663                 pthread_mutex_unlock(&g_play_thread_mutex);
664                 pthread_mutex_lock(&g_player_control_mutex);
665                 g_playing_info = NULL;
666                 pthread_mutex_unlock(&g_player_control_mutex);
667         }
668 }
669
670 /*
671 * Player Interfaces
672 */
673 int ttsd_player_init()
674 {
675         pthread_mutex_lock(&g_player_control_mutex);
676         g_playing_info = NULL;
677
678         ecore_thread_max_set(1);
679
680         g_background_volume = new BackgroundVolume(SND_MGR_DUCKING_DURATION);
681         g_audio_stream = new AudioStream(__focus_release_callback);
682
683         ecore_thread_max_set(1);
684         ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
685
686         g_is_set_policy = false;
687         g_player_init = true;
688
689         pthread_mutex_unlock(&g_player_control_mutex);
690
691         return 0;
692 }
693
694 int ttsd_player_release(void)
695 {
696 #ifdef BUF_SAVE_MODE
697         __close_buffer_dump_file();
698 #endif
699
700         __set_playing_status(false);
701         pthread_mutex_lock(&g_player_control_mutex);
702         if (false == g_player_init) {
703                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
704                 pthread_mutex_unlock(&g_player_control_mutex);
705                 return TTSD_ERROR_OPERATION_FAILED;
706         }
707
708         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] @@@@@");
709         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
710         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] @@@@@");
711
712         /* The thread should be released */
713         int thread_count = ecore_thread_active_get();
714         int count = 0;
715         while (0 < thread_count) {
716                 usleep(10000);
717
718                 count++;
719                 if (20 == count) {
720                         SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
721                         break;
722                 }
723
724                 thread_count = ecore_thread_active_get();
725         }
726
727         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Thread is released");
728
729         /* clear g_player_list */
730         g_playing_info = NULL;
731         g_player_init = false;
732         pthread_cond_broadcast(&g_play_thread_cond);
733
734         delete g_audio_stream;
735         g_audio_stream = nullptr;
736
737         delete g_background_volume;
738         g_background_volume = nullptr;
739
740         pthread_mutex_unlock(&g_player_control_mutex);
741
742         return 0;
743 }
744
745 int ttsd_player_create_instance(unsigned int uid)
746 {
747         if (false == g_player_init) {
748                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
749                 return TTSD_ERROR_OPERATION_FAILED;
750         }
751
752         /* Check uid is duplicated */
753         if (NULL != __player_get_item(uid)) {
754                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is already registered", uid);
755                 return -1;
756         }
757
758         player_s* new_client = (player_s*)calloc(1, sizeof(player_s));
759         if (NULL == new_client) {
760                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to allocate memory");
761                 return TTSE_ERROR_OUT_OF_MEMORY;
762         }
763
764         new_client->uid = uid;
765         new_client->event = TTSE_RESULT_EVENT_FINISH;
766         new_client->state = APP_STATE_READY;
767         new_client->is_paused_data = false;
768         new_client->idx = 0;
769         new_client->paused_data = NULL;
770
771         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Player] Create player : uid(%u)", uid);
772
773         g_player_list = g_list_append(g_player_list, new_client);
774
775         return 0;
776 }
777
778 int ttsd_player_destroy_instance(unsigned int uid)
779 {
780         pthread_mutex_lock(&g_player_control_mutex);
781         if (false == g_player_init) {
782                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
783                 pthread_mutex_unlock(&g_player_control_mutex);
784                 return TTSD_ERROR_OPERATION_FAILED;
785         }
786
787         player_s* current;
788         current = __player_get_item(uid);
789         if (NULL == current) {
790                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
791                 pthread_mutex_unlock(&g_player_control_mutex);
792                 return -1;
793         }
794
795         if (NULL != g_playing_info) {
796                 if (uid == g_playing_info->uid) {
797                         g_playing_info = NULL;
798                 }
799         }
800
801         GList *iter = NULL;
802         player_s *data = NULL;
803
804         if (0 < g_list_length(g_player_list)) {
805                 /* Get a first item */
806                 iter = g_list_first(g_player_list);
807
808                 while (NULL != iter) {
809                         /* Get handle data from list */
810                         data = (player_s*)iter->data;
811
812                         if (NULL != data) {
813                                 /* compare uid */
814                                 if (uid == data->uid) {
815                                         g_player_list = g_list_remove_link(g_player_list, iter);
816                                         free(data);
817                                         data = NULL;
818                                         g_list_free(iter);
819                                         break;
820                                 }
821                         }
822
823                         /* Get next item */
824                         iter = g_list_next(iter);
825                 }
826         }
827         pthread_mutex_unlock(&g_player_control_mutex);
828
829         SLOG(LOG_DEBUG, tts_tag(), "[PLAYER Success] Destroy instance");
830
831         return 0;
832 }
833
834 int ttsd_player_play(unsigned int uid)
835 {
836         pthread_mutex_lock(&g_player_control_mutex);
837         if (false == g_player_init) {
838                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
839                 pthread_mutex_unlock(&g_player_control_mutex);
840                 return TTSD_ERROR_OPERATION_FAILED;
841         }
842
843         if (NULL != g_playing_info) {
844                 if (uid == g_playing_info->uid) {
845                         SLOG(LOG_DEBUG, tts_tag(), "[Player] uid(%u) has already played", g_playing_info->uid);
846                         pthread_mutex_unlock(&g_player_control_mutex);
847                         return 0;
848                 } else {
849                         SLOG(LOG_WARN, tts_tag(), "[Player WARNING] stop old player (%u)", g_playing_info->uid);
850                         pthread_mutex_unlock(&g_player_control_mutex);
851                         ttsd_player_stop(g_playing_info->uid);
852                         pthread_mutex_lock(&g_player_control_mutex);
853                 }
854         }
855
856         SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%u)", uid);
857
858         /* Check uid */
859         player_s* current;
860         current = __player_get_item(uid);
861         if (NULL == current) {
862                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
863                 pthread_mutex_unlock(&g_player_control_mutex);
864                 return -1;
865         }
866
867         current->state = APP_STATE_PLAYING;
868         g_playing_info = current;
869
870         SLOG(LOG_INFO, tts_tag(), "[Player] Run thread");
871         pthread_cond_broadcast(&g_play_thread_cond);
872
873         pthread_mutex_unlock(&g_player_control_mutex);
874         return 0;
875 }
876
877 int ttsd_player_stop(unsigned int uid)
878 {
879         pthread_mutex_lock(&g_player_control_mutex);
880         if (false == g_player_init) {
881                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
882                 pthread_mutex_unlock(&g_player_control_mutex);
883                 return TTSD_ERROR_OPERATION_FAILED;
884         }
885
886         /* check whether uid is current playing or not */
887         if (NULL != g_playing_info) {
888                 if (uid == g_playing_info->uid) {
889                         /* release current playing info */
890                         g_playing_info = NULL;
891                 }
892         } else {
893                 SLOG(LOG_DEBUG, tts_tag(), "[Player] No current playing");
894         }
895
896         if (NULL == g_playing_info) {
897                 pthread_mutex_lock(&g_play_thread_mutex);
898                 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
899                 pthread_mutex_unlock(&g_play_thread_mutex);
900         }
901
902 #ifdef BUF_SAVE_MODE
903         __close_buffer_dump_file();
904 #endif
905
906         __set_playing_status(false);
907         int ret = ttsd_player_clear(uid);
908         if (0 != ret) {
909                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to stop player, ret(%d)", ret);
910                 pthread_mutex_unlock(&g_player_control_mutex);
911                 return ret;
912         }
913
914         SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Stop player : uid(%u)", uid);
915
916         pthread_mutex_unlock(&g_player_control_mutex);
917         return 0;
918 }
919
920 int ttsd_player_clear(unsigned int uid)
921 {
922         if (false == g_player_init) {
923                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
924                 return TTSD_ERROR_OPERATION_FAILED;
925         }
926
927         /* Check uid */
928         player_s* current;
929         current = __player_get_item(uid);
930         if (NULL == current) {
931                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
932                 return -1;
933         }
934
935         if (true == current->is_paused_data) {
936                 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Clear paused data");
937                 ttsd_data_destroy_sound_data(current->paused_data);
938                 current->paused_data = NULL;
939         }
940
941         current->event = TTSE_RESULT_EVENT_FINISH;
942         current->state = APP_STATE_READY;
943         current->is_paused_data = false;
944         current->idx = 0;
945
946         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Clear player : uid(%u)", uid);
947
948         return 0;
949 }
950
951 int ttsd_player_pause(unsigned int uid)
952 {
953         pthread_mutex_lock(&g_player_control_mutex);
954         SLOG(LOG_DEBUG, tts_tag(), "[Player] pause player : uid(%u)", uid);
955
956         if (false == g_player_init) {
957                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
958                 pthread_mutex_unlock(&g_player_control_mutex);
959                 return TTSD_ERROR_OPERATION_FAILED;
960         }
961
962         /* Check uid */
963         player_s* current;
964         current = __player_get_item(uid);
965         if (NULL == current) {
966                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] ttsd_player_pause() : uid(%u) is not valid", uid);
967                 pthread_mutex_unlock(&g_player_control_mutex);
968                 return -1;
969         }
970
971         /* check whether uid is current playing or not */
972         if (NULL != g_playing_info) {
973                 if (uid == g_playing_info->uid) {
974                         /* release current playing info */
975                         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] release current playing info (%u)", uid);
976                         g_playing_info = NULL;
977                 } else {
978                         /* error case */
979                 }
980         }
981
982         SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] current player (%p), g_playing_info(%p)", current, g_playing_info);
983
984         current->state = APP_STATE_PAUSED;
985
986         if (NULL == g_playing_info) {
987                 pthread_mutex_lock(&g_play_thread_mutex);
988                 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
989                 pthread_mutex_unlock(&g_play_thread_mutex);
990         }
991
992 #ifdef BUF_SAVE_MODE
993         __close_buffer_dump_file();
994 #endif
995
996         __set_playing_status(false);
997         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Pause player : uid(%u)", uid);
998
999         pthread_mutex_unlock(&g_player_control_mutex);
1000         return 0;
1001 }
1002
1003 int ttsd_player_resume(unsigned int uid)
1004 {
1005         pthread_mutex_lock(&g_player_control_mutex);
1006         SLOG(LOG_DEBUG, tts_tag(), "[Player] Resume player : uid(%u)", uid);
1007
1008         if (false == g_player_init) {
1009                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1010                 pthread_mutex_unlock(&g_player_control_mutex);
1011                 return TTSD_ERROR_OPERATION_FAILED;
1012         }
1013
1014         /* Check id */
1015         player_s* current;
1016         current = __player_get_item(uid);
1017         if (NULL == current) {
1018                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
1019                 pthread_mutex_unlock(&g_player_control_mutex);
1020                 return -1;
1021         }
1022
1023         /* check current player */
1024         if (NULL != g_playing_info)
1025                 g_playing_info = NULL;
1026
1027         current->state = APP_STATE_PLAYING;
1028         g_playing_info = current;
1029
1030         SLOG(LOG_INFO, tts_tag(), "[Player] Resume to run thread");
1031         pthread_cond_broadcast(&g_play_thread_cond);
1032
1033         pthread_mutex_unlock(&g_player_control_mutex);
1034         return 0;
1035 }
1036
1037 int ttsd_player_all_stop()
1038 {
1039         pthread_mutex_lock(&g_player_control_mutex);
1040         if (false == g_player_init) {
1041                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1042                 pthread_mutex_unlock(&g_player_control_mutex);
1043                 return TTSD_ERROR_OPERATION_FAILED;
1044         }
1045
1046         g_playing_info = NULL;
1047
1048         GList *iter = NULL;
1049         player_s *data = NULL;
1050
1051         if (0 < g_list_length(g_player_list)) {
1052                 /* Get a first item */
1053                 iter = g_list_first(g_player_list);
1054
1055                 while (NULL != iter) {
1056                         /* Get handle data from list */
1057                         data = (player_s*)iter->data;
1058
1059                         app_tts_state_e state;
1060                         if (0 > ttsd_data_get_client_state(data->uid, &state)) {
1061                                 SLOG(LOG_ERROR, tts_tag(), "[player ERROR] uid(%u) is not valid", data->uid);
1062                                 iter = g_list_next(iter);
1063
1064                                 pthread_mutex_unlock(&g_player_control_mutex);
1065                                 ttsd_player_destroy_instance(data->uid);
1066                                 pthread_mutex_lock(&g_player_control_mutex);
1067                                 continue;
1068                         }
1069
1070                         if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
1071                                 data->event = TTSE_RESULT_EVENT_FINISH;
1072                                 data->state = APP_STATE_READY;
1073
1074                                 if (true == data->is_paused_data) {
1075                                         SLOG(LOG_INFO, tts_tag(), "[Player INFO] Clear paused data");
1076                                         ttsd_data_destroy_sound_data(data->paused_data);
1077                                         data->paused_data = NULL;
1078                                 }
1079
1080                                 data->is_paused_data = false;
1081                                 data->idx = 0;
1082                         }
1083
1084                         /* Get next item */
1085                         iter = g_list_next(iter);
1086                 }
1087         }
1088
1089         SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] player all stop!!");
1090
1091         pthread_mutex_unlock(&g_player_control_mutex);
1092         return 0;
1093 }
1094
1095 int ttsd_player_get_background_volume_ratio(double* ratio)
1096 {
1097         if (false == g_player_init) {
1098                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1099                 return TTSD_ERROR_OPERATION_FAILED;
1100         }
1101
1102         if (NULL == ratio) {
1103                 return TTSD_ERROR_INVALID_PARAMETER;
1104         }
1105
1106         *ratio = g_background_volume->getVolumeRatio();
1107         return TTSD_ERROR_NONE;
1108 }
1109
1110 int ttsd_player_set_background_volume_ratio(double ratio)
1111 {
1112         if (false == g_player_init) {
1113                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1114                 return TTSD_ERROR_OPERATION_FAILED;
1115         }
1116
1117         SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] ttsd_player_set_background_volume_ratio : %lf", ratio);
1118         g_background_volume->setVolumeRatio(ratio);
1119
1120         return TTSD_ERROR_NONE;
1121 }
1122
1123 int ttsd_player_wait_to_play(unsigned int uid)
1124 {
1125         if (false == g_player_init) {
1126                 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1127                 return TTSD_ERROR_OPERATION_FAILED;
1128         }
1129
1130         SLOG(LOG_INFO, tts_tag(), "[Player INFO] wait to play (%u)", uid);
1131
1132         g_audio_stream->waitForPlay();
1133         return TTSD_ERROR_NONE;
1134 }