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