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.
16 #include <sound_manager.h>
17 #include <sound_manager_internal.h>
21 #include "ttsd_main.h"
22 #include "ttsd_player.h"
23 #include "ttsd_data.h"
24 #include "ttsd_dbus.h"
27 #include "tts_internal.h"
28 #include "ttsd_server.h"
31 * Internal data structure
37 AUDIO_STATE_WAIT_FOR_PLAYING,
42 unsigned int uid; /** client id */
43 app_tts_state_e state; /** client state */
45 /* Current utterance information */
46 ttse_result_event_e event; /** event of last utterance */
50 sound_data_s* paused_data;
53 #define SOUND_BUFFER_LENGTH 2048
54 #define FOCUS_SERVER_READY "/tmp/.sound_server_ready"
56 static const intptr_t CHECK_TIMER_DELETE = 1;
57 static const int EXTRA_INFO_LENGTH = 20;
59 /* Sound buf save for test */
65 static char g_temp_file_name[128] = {'\0',};
67 static int g_count = 0;
68 static pthread_mutex_t g_buf_save_mutex = PTHREAD_MUTEX_INITIALIZER;
71 /** player init info */
72 static bool g_player_init = false;
75 static GList *g_player_list;
77 /** current player information */
78 static player_s* g_playing_info;
81 static audio_state_e g_audio_state;
83 static ttse_audio_type_e g_audio_type;
85 static int g_sampling_rate;
87 static audio_out_h g_audio_h;
89 static sound_stream_info_h g_stream_info_h;
91 static sound_stream_ducking_h g_media_stream_ducking;
92 //static sound_stream_ducking_h g_system_stream_ducking;
93 static sound_stream_ducking_h g_notification_stream_ducking;
94 static sound_stream_ducking_h g_alarm_stream_ducking;
96 static bool g_is_set_policy;
98 // static bool ducking_flag;
101 If you change this constant value. Please check the function '__set_timer_for_delay_recover()'.
102 If you choose too big value, it may cause integer overflow issue.
104 #define SND_MGR_DUCKING_DURATION 500
106 static struct timespec g_policy_set_time;
107 static Ecore_Timer* g_delayed_unset_policy_timer = NULL;
108 static Ecore_Timer* g_modify_background_volume = NULL;
110 static double g_bg_volume_ratio;
112 static pthread_mutex_t g_play_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
113 static pthread_mutex_t g_player_control_mutex = PTHREAD_MUTEX_INITIALIZER;
115 static pthread_cond_t g_play_thread_cond = PTHREAD_COND_INITIALIZER;
117 * Internal Interfaces
119 static void __set_playing_status(bool is_playing)
121 int ret = vconf_set_bool(TTS_PLAYING_STATUS_KEY, is_playing ? 1 : 0);
122 SLOG(LOG_INFO, tts_tag(), "[Player] Set playing status (%s). ret(%d)", is_playing ? "True" : "False", ret);
126 static void __open_buffer_dump_file()
128 pthread_mutex_lock(&g_buf_save_mutex);
130 SLOG(LOG_ERROR, tts_tag(), "[Buffer Dump] File is already opened(%s)", g_temp_file_name);
131 pthread_mutex_unlock(&g_buf_save_mutex);
137 snprintf(g_temp_file_name, sizeof(g_temp_file_name), "/tmp/tts_temp_%d_%d", getpid(), g_count);
138 int ret = access(g_temp_file_name, 0);
141 SLOG(LOG_ERROR, tts_tag(), "[Recorder ERROR] File is already exist");
142 if (0 == remove(g_temp_file_name)) {
143 SLOG(LOG_DEBUG, tts_tag(), "[Recorder] Remove file");
153 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Recorder] Temp file name=[%s]", g_temp_file_name);
156 g_pFile = fopen(g_temp_file_name, "wb+x");
157 if (NULL == g_pFile) {
158 SLOG(LOG_ERROR, tts_tag(), "[Recorder ERROR] File not found!");
161 pthread_mutex_unlock(&g_buf_save_mutex);
164 static void __close_buffer_dump_file()
166 pthread_mutex_lock(&g_buf_save_mutex);
173 pthread_mutex_unlock(&g_buf_save_mutex);
176 static void __write_buffer_dump_file(const void* buffer, size_t length)
178 pthread_mutex_lock(&g_buf_save_mutex);
181 size_t ret = fwrite(buffer, 1, length, g_pFile);
182 SLOG(LOG_DEBUG, tts_tag(), "[Buffer Dump] Stored size(%zu / %zu)", ret, length);
184 SLOG(LOG_ERROR, tts_tag(), "[Buffer Dump] File is not opened. Please check the file open");
187 pthread_mutex_unlock(&g_buf_save_mutex);
191 static bool __is_player_valid(player_s* player)
193 if (NULL == player || NULL == g_playing_info) {
194 SLOG(LOG_ERROR, tts_tag(), "[ERROR] player is NULL");
198 if (g_playing_info != player || g_playing_info->uid != player->uid) {
199 SLOG(LOG_ERROR, tts_tag(), "[ERROR] player is not current player");
206 player_s* __player_get_item(unsigned int uid)
209 player_s *data = NULL;
211 if (0 < g_list_length(g_player_list)) {
212 /* Get a first item */
213 iter = g_list_first(g_player_list);
215 while (NULL != iter) {
216 /* Get handle data from list */
217 data = (player_s*)iter->data;
220 if (uid == data->uid)
224 iter = g_list_next(iter);
231 static bool __is_focus_released_on_playing(sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state)
233 if (NULL == g_playing_info) {
234 SLOG(LOG_INFO, tts_tag(), "[Player] No current player");
238 if (APP_STATE_PLAYING != g_playing_info->state || AUDIO_STATE_NONE == g_audio_state || AUDIO_STATE_READY == g_audio_state) {
239 SLOG(LOG_INFO, tts_tag(), "[Player] Audio is not played");
243 if (SOUND_STREAM_FOCUS_FOR_PLAYBACK != focus_mask || SOUND_STREAM_FOCUS_STATE_RELEASED != focus_state) {
244 SLOG(LOG_INFO, tts_tag(), "[Player] Playback focus is not released");
251 static void __player_focus_state_cb(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state,
252 sound_stream_focus_change_reason_e reason_for_change, int sound_behavior, const char *extra_info, void *user_data)
254 SLOG(LOG_DEBUG, tts_tag(), "@@@ Focus state changed cb");
255 SLOG(LOG_WARN, tts_tag(), "[Player] focus state changed to (%d) with reason(%d) and extra info(%s)", (int)focus_state, (int)reason_for_change, extra_info);
257 if (stream_info != g_stream_info_h) {
258 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Invalid stream info handle");
262 if (false == __is_focus_released_on_playing(focus_mask, focus_state)) {
263 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Playback focus is not released on playing");
267 unsigned int uid = g_playing_info->uid;
268 ttsd_mode_e mode = ttsd_data_get_mode(uid);
271 case TTSD_MODE_DEFAULT:
273 SLOG(LOG_DEBUG, tts_tag(), "[Player] Pause current player - mode(%d)", mode);
274 g_audio_state = AUDIO_STATE_READY;
276 if (0 != ttsd_player_pause(uid)) {
277 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to pause the player");
281 ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
282 int pid = ttsd_data_get_pid(uid);
284 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to get pid. uid(%u)", uid);
286 /* send message to client about changing state */
287 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Player paused. pid(%d), uid(%u)", pid, uid);
288 ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_PAUSED);
293 case TTSD_MODE_NOTIFICATION:
294 case TTSD_MODE_SCREEN_READER:
296 SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop current player - mode(%d)", mode);
297 g_audio_state = AUDIO_STATE_READY;
298 ttsd_send_all_stop();
302 case TTSD_MODE_INTERRUPT:
303 SLOG(LOG_DEBUG, tts_tag(), "[Player] Ignore focus release - mode(%d)", mode);
307 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Invalid mode - mode(%d)", mode);
311 SLOG(LOG_DEBUG, tts_tag(), "@@@");
316 void __sound_stream_ducking_state_changed_cb(sound_stream_ducking_h stream_ducking, bool is_ducked, void *user_data)
318 SLOG(LOG_DEBUG, tts_tag(), "@@@ ducking state changed cb");
319 SLOG(LOG_ERROR, tts_tag(), "[Player] ducking_h(%p) is ducked : %d", stream_ducking, is_ducked);
320 // ducking_flag = true;
324 static const char* __get_ducking_stream(sound_stream_type_e stream_type)
326 const char* type = nullptr;
327 if (SOUND_STREAM_TYPE_MEDIA == stream_type)
328 type = "Media stream";
329 else if (SOUND_STREAM_TYPE_SYSTEM == stream_type)
330 type = "System stream";
331 else if (SOUND_STREAM_TYPE_NOTIFICATION == stream_type)
332 type = "Notification stream";
333 else if (SOUND_STREAM_TYPE_ALARM == stream_type)
334 type = "Alarm stream";
336 type = "Non matched stream";
341 static int __activate_ducking_sound_stream(sound_stream_type_e stream_type, sound_stream_ducking_h stream_ducking_h, unsigned int duration)
343 bool is_ducked = false;
344 int ret = sound_manager_is_ducked(stream_ducking_h, &is_ducked);
346 SLOG(LOG_DEBUG, tts_tag(), "[Player] The %s is already ducked", __get_ducking_stream(stream_type));
348 ret = sound_manager_activate_ducking(stream_ducking_h, duration, g_bg_volume_ratio);
349 if (SOUND_MANAGER_ERROR_NONE != ret) {
350 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to activate ducking for %s", __get_ducking_stream(stream_type));
352 SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Activate ducking for %s", __get_ducking_stream(stream_type));
358 static void __change_background_volume(unsigned int duration)
360 SLOG(LOG_INFO, tts_tag(), "[BG] Change background volume");
361 SLOG(LOG_INFO, tts_tag(), "[Player] volume ratio(%lf)", g_bg_volume_ratio);
362 if (1.0 > g_bg_volume_ratio) {
363 __activate_ducking_sound_stream(SOUND_STREAM_TYPE_MEDIA, g_media_stream_ducking, duration);
364 // __activate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_ducking, duration);
365 __activate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_ducking, duration);
366 __activate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_ducking, duration);
370 static void __change_background_volume_async(void* data)
372 __change_background_volume(SND_MGR_DUCKING_DURATION);
375 static int __deactivate_ducking_sound_stream(sound_stream_type_e stream_type, sound_stream_ducking_h stream_ducking_h)
377 bool is_ducked = false;
378 int ret = sound_manager_is_ducked(stream_ducking_h, &is_ducked);
380 SLOG(LOG_DEBUG, tts_tag(), "[Player] The %s is already recovered from ducking", __get_ducking_stream(stream_type));
382 ret = sound_manager_deactivate_ducking(stream_ducking_h);
383 if (SOUND_MANAGER_ERROR_NONE != ret) {
384 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to deactivate ducking for %s", __get_ducking_stream(stream_type));
386 SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Deactivate ducking for %s", __get_ducking_stream(stream_type));
392 static void __recover_background_volume()
394 __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_MEDIA, g_media_stream_ducking);
395 // __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_ducking);
396 __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_ducking);
397 __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_ducking);
400 static int __create_audio_out(ttse_audio_type_e type, int rate)
403 audio_sample_type_e sample_type;
405 if (TTSE_AUDIO_TYPE_RAW_S16 == type) {
406 sample_type = AUDIO_SAMPLE_TYPE_S16_LE;
408 sample_type = AUDIO_SAMPLE_TYPE_U8;
411 ret = audio_out_create_new(rate, AUDIO_CHANNEL_MONO, sample_type, &g_audio_h);
412 if (AUDIO_IO_ERROR_NONE != ret) {
413 g_audio_state = AUDIO_STATE_NONE;
415 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio");
418 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create audio");
422 g_sampling_rate = rate;
424 g_audio_state = AUDIO_STATE_READY;
429 static int __destroy_audio_out()
431 if (NULL == g_audio_h) {
432 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current handle is not valid");
437 ret = audio_out_destroy(g_audio_h);
438 if (AUDIO_IO_ERROR_NONE != ret) {
439 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to destroy audio");
442 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy audio");
445 g_audio_type = TTSE_AUDIO_TYPE_RAW_S16;
448 g_audio_state = AUDIO_STATE_NONE;
454 static void __end_play_thread(void *data, Ecore_Thread *thread)
456 SLOG(LOG_ERROR, tts_tag(), "@@@ End thread");
459 static void __del_timer_for_delayed_recover(void* data)
461 if (NULL != g_delayed_unset_policy_timer) {
462 int result = (intptr_t)ecore_timer_del(g_delayed_unset_policy_timer);
463 g_delayed_unset_policy_timer = NULL;
464 SLOG(LOG_ERROR, tts_tag(), "[BG] Remove timer (%d)", result);
468 static void __set_policy_for_playing(void)
470 ecore_main_loop_thread_safe_call_async(__del_timer_for_delayed_recover, NULL);
472 /* Set stream info */
473 const char* extra_info = NULL;
474 if (TTSD_MODE_INTERRUPT == ttsd_get_mode()) {
475 extra_info = "TTSD_MODE_INTERRUPT";
478 int ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, extra_info);
479 if (SOUND_MANAGER_ERROR_NONE != ret) {
480 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to acquire focus");
482 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Success to acquire focus");
485 ret = audio_out_set_sound_stream_info(g_audio_h, g_stream_info_h);
486 if (AUDIO_IO_ERROR_NONE != ret) {
487 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to set stream info");
490 ecore_main_loop_thread_safe_call_async(__change_background_volume_async, NULL);
492 g_is_set_policy = true;
493 SLOG(LOG_ERROR, tts_tag(), "[BG] g_is_set_policy(%d)", g_is_set_policy);
495 clock_gettime(CLOCK_MONOTONIC, &g_policy_set_time);
497 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] set policy for playing");
502 static Eina_Bool __delay_recover_background_volume(void* data)
504 __recover_background_volume();
505 SLOG(LOG_INFO, tts_tag(), "[BG] Delayed unset policy success");
507 g_delayed_unset_policy_timer = NULL;
511 static long long int __get_duration_from_last_volume_change()
513 struct timespec current_time;
514 clock_gettime(CLOCK_MONOTONIC, ¤t_time);
516 long long int diff = ((long long int)current_time.tv_sec - (long long int)g_policy_set_time.tv_sec) * 1000
517 + ((long long int)current_time.tv_nsec - (long long int)g_policy_set_time.tv_nsec) / 1000000;
518 SLOG(LOG_INFO, tts_tag(), "[BG] Time Diff(%lld)", diff);
523 static void __set_timer_for_delay_recover(void* data)
525 if (NULL != g_delayed_unset_policy_timer) {
529 long long int diff = __get_duration_from_last_volume_change();
530 if (diff > SND_MGR_DUCKING_DURATION) {
531 SLOG(LOG_INFO, tts_tag(), "[BG] Direct unset policy");
532 __recover_background_volume();
534 double delay = (double)(SND_MGR_DUCKING_DURATION - diff) / 1000.0;
535 g_delayed_unset_policy_timer = ecore_timer_add(delay, __delay_recover_background_volume, (void*)CHECK_TIMER_DELETE);
536 SLOG(LOG_INFO, tts_tag(), "[BG] Delayed unset policy (%p), delay(%f)", g_delayed_unset_policy_timer, delay);
540 static void __unset_policy_for_playing()
542 /* Unset stream info */
543 sound_stream_focus_state_e state_for_playing = SOUND_STREAM_FOCUS_STATE_ACQUIRED;
544 int ret = sound_manager_get_focus_state(g_stream_info_h, &state_for_playing, NULL);
545 if (SOUND_MANAGER_ERROR_NONE != ret) {
546 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to get focus state: %d", ret);
549 if (SOUND_STREAM_FOCUS_STATE_ACQUIRED == state_for_playing) {
550 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] release focus (mode: %d)", ttsd_get_mode());
551 ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
552 if (SOUND_MANAGER_ERROR_NONE != ret) {
553 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to release focus: %d", ret);
557 ecore_main_loop_thread_safe_call_async(__set_timer_for_delay_recover, NULL);
559 g_is_set_policy = false;
560 SLOG(LOG_ERROR, tts_tag(), "[BG] g_is_set_policy(%d)", g_is_set_policy);
561 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] unset policy for playing");
566 static bool __does_interrupt_have_focus(sound_stream_focus_change_reason_e reason, int sound_behavior, char *extra_info)
568 SLOG(LOG_DEBUG, tts_tag(), "[Player] current Playback focus: extra_info(%s), reason(%d), sound_behavior(%d)", extra_info, reason, sound_behavior);
569 if (SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION != reason) {
573 if (NULL == extra_info || 0 >= strlen(extra_info) || 0 != strncmp(extra_info, "TTSD_MODE_INTERRUPT", EXTRA_INFO_LENGTH)) {
580 bool ttsd_player_does_interrupt_have_playback_focus()
582 sound_stream_focus_change_reason_e reason;
583 int sound_behavior = 0;
584 char *extra_info = NULL;
585 if (SOUND_MANAGER_ERROR_NONE != sound_manager_get_current_playback_focus(&reason, &sound_behavior, &extra_info)) {
586 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to get focus information");
590 bool result = __does_interrupt_have_focus(reason, sound_behavior, extra_info);
595 static void __play_thread_old(void *data, Ecore_Thread *thread)
597 SLOG(LOG_DEBUG, tts_tag(), "@@@ Start thread");
599 if (NULL == g_playing_info) {
600 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] No current player");
604 player_s* player = g_playing_info;
605 sound_data_s* sound_data = NULL;
608 int len = SOUND_BUFFER_LENGTH;
611 /* set volume policy as 40% */
612 __set_policy_for_playing();
613 while (1) { // 1st while(1)
614 /* check g_playing_info one more time */
615 if (false == __is_player_valid(player)) {
616 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Player is not valid");
617 g_audio_state = AUDIO_STATE_READY;
618 ret = audio_out_unprepare(g_audio_h);
619 if (AUDIO_IO_ERROR_NONE != ret) {
620 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
622 __unset_policy_for_playing();
626 if (true == player->is_paused_data && NULL != player->paused_data) {
628 sound_data_s* paused_data = player->paused_data;
629 player->paused_data = NULL;
631 ttsd_data_destroy_sound_data(sound_data);
632 sound_data = ttsd_data_create_sound_data(paused_data->utt_id, paused_data->data, paused_data->data_size,
633 paused_data->event, paused_data->audio_type, paused_data->rate, paused_data->channels);
634 if (NULL == sound_data || player->paused_data->data_size <= 0) {
635 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Out of memory OR paused_data is empty");
636 ttsd_data_destroy_sound_data(sound_data);
637 sound_data = paused_data;
638 } else { // NULL != sound_data && NULL != temp && player->paused_data->data_size > 0
639 ttsd_data_destroy_sound_data(paused_data);
644 player->is_paused_data = false;
647 if (NULL == sound_data) {
648 /* Request unprepare */
649 ret = audio_out_unprepare(g_audio_h);
650 if (AUDIO_IO_ERROR_NONE != ret) {
651 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
653 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
656 g_audio_state = AUDIO_STATE_READY;
658 /* unset volume policy, volume will be 100% */
659 __unset_policy_for_playing();
662 __set_playing_status(true);
664 SLOG(LOG_INFO, tts_tag(), "[Player] Sound info : id(%d) data(%p) size(%d) audiotype(%d) rate(%d) event(%d)",
665 sound_data->utt_id, sound_data->data, sound_data->data_size, sound_data->audio_type, sound_data->rate, sound_data->event);
666 } else { // NO player->is_paused_data
668 ret = ttsd_data_get_sound_data(player->uid, &sound_data);
669 if (0 != ret || NULL == sound_data) {
671 SLOG(LOG_ERROR, tts_tag(), "[Player] No sound data. Waiting mode");
673 /* wait for new audio data come */
674 while (1) { // 2nd while(1)
676 if (false == __is_player_valid(player)) {
677 /* current playing uid is replaced */
678 SLOG(LOG_INFO, tts_tag(), "[Player] Finish thread");
679 if (AUDIO_STATE_PLAY == g_audio_state) {
680 /* release audio & recover session */
681 ret = audio_out_unprepare(g_audio_h);
682 if (AUDIO_IO_ERROR_NONE != ret) {
683 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
685 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
687 g_audio_state = AUDIO_STATE_READY;
689 /* unset volume policy, volume will be 100% */
690 __unset_policy_for_playing();
692 } else if (0 < ttsd_data_get_sound_data_size(player->uid)) {
693 /* new audio data come */
694 SLOG(LOG_INFO, tts_tag(), "[Player] Resume thread");
695 break; // exit from 2nd while(1)
698 /* If engine is not on processing */
699 ttsd_synthesis_control_e synth_control = ttsd_get_synth_control();
700 if (TTSD_SYNTHESIS_CONTROL_DOING != synth_control) {
701 SLOG(LOG_INFO, tts_tag(), "[Server INFO] synth_control(%d)", synth_control);
702 if (AUDIO_STATE_PLAY == g_audio_state) {
703 /* release audio & recover session */
704 ret = audio_out_unprepare(g_audio_h);
705 if (AUDIO_IO_ERROR_NONE != ret) {
706 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
708 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
710 g_audio_state = AUDIO_STATE_READY;
712 /* unset volume policy, volume will be 100% */
713 __unset_policy_for_playing();
716 } // end of 2nd while(1). waiting for new audio data come
718 SLOG(LOG_INFO, tts_tag(), "[Player] Finish to wait for new audio data come");
720 if (AUDIO_STATE_READY == g_audio_state || AUDIO_STATE_WAIT_FOR_PLAYING == g_audio_state) {
721 /* set volume policy as 40%, when resume play thread*/
722 __set_policy_for_playing();
725 /* resume play thread */
726 player->state = APP_STATE_PLAYING;
728 } // NULL == sound_data
730 /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
731 * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
732 * When previous wdata's event is 'finish' and current wdata's event is 'finish',
733 * the player should send utt started event.
735 if (TTSE_RESULT_EVENT_START == sound_data->event ||
736 (TTSE_RESULT_EVENT_FINISH == player->event && TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
737 int pid = ttsd_data_get_pid(player->uid);
739 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid);
740 /* unset volume policy, volume will be 100% */
741 __unset_policy_for_playing();
742 ttsd_data_destroy_sound_data(sound_data);
748 __open_buffer_dump_file();
751 __set_playing_status(true);
752 if (0 != ttsdc_ipc_send_utt_start_message(pid, player->uid, sound_data->utt_id)) {
753 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%u), uttid(%d)",
754 pid, player->uid, sound_data->utt_id);
756 SLOG(LOG_INFO, tts_tag(), "[Player] Start utterance : uid(%u), uttid(%d)", player->uid, sound_data->utt_id);
757 } // (TTSE_RESULT_EVENT_START == sound_data->event || (TTSE_RESULT_EVENT_FINISH == player->event && TTSE_RESULT_EVENT_FINISH == sound_data->event))
759 /* Save last event to check utterance start */
760 player->event = sound_data->event;
763 if (NULL == sound_data->data || 0 >= sound_data->data_size) {
764 if (TTSE_RESULT_EVENT_FINISH == sound_data->event) {
765 SLOG(LOG_DEBUG, tts_tag(), "No sound data");
766 /* send utterence finish signal */
767 int pid = ttsd_data_get_pid(player->uid);
770 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid);
771 /* unset volume policy, volume will be 100% */
772 __unset_policy_for_playing();
773 ttsd_data_destroy_sound_data(sound_data);
778 __unset_policy_for_playing();
781 __close_buffer_dump_file();
784 __set_playing_status(false);
785 if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
786 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%u), uttid(%d)",
787 pid, player->uid, sound_data->utt_id);
789 SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, sound_data->utt_id);
791 } // TTSE_RESULT_EVENT_FINISH == sound_data->event
792 SLOG(LOG_INFO, tts_tag(), "[Player] Event(%d) utterance : uid(%u), uttid(%d)", sound_data->event, player->uid, sound_data->utt_id);
793 ttsd_data_destroy_sound_data(sound_data);
796 } // (NULL == sound_data->data || 0 >= sound_data->data_size)
797 } // NO player->is_paused_data
799 // If there is any change in audio format, recreate audio handle
800 if (g_sampling_rate != sound_data->rate || g_audio_type != sound_data->audio_type) {
801 SLOG(LOG_INFO, tts_tag(), "[Player] Change audio handle : org type(%d) org rate(%d)", g_audio_type, g_sampling_rate);
802 if (NULL != g_audio_h) {
803 __destroy_audio_out();
806 if (0 > __create_audio_out(sound_data->audio_type, sound_data->rate)) {
807 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio out");
808 /* unset volume policy, volume will be 100% */
809 __unset_policy_for_playing();
811 ttsd_data_destroy_sound_data(sound_data);
816 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Success to destroy and recreate audio out");
817 __set_policy_for_playing();
820 while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) {
821 if ((unsigned int)idx >= sound_data->data_size)
824 if ((unsigned int)idx + SOUND_BUFFER_LENGTH > sound_data->data_size) {
825 len = sound_data->data_size - idx;
827 len = SOUND_BUFFER_LENGTH;
830 // Check whether set_policy is done or not
831 if (false == g_is_set_policy) {
832 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Set policy");
833 __set_policy_for_playing();
836 if (AUDIO_STATE_READY == g_audio_state || AUDIO_STATE_WAIT_FOR_PLAYING == g_audio_state) {
837 /* Request prepare */
838 ret = audio_out_prepare(g_audio_h);
839 if (AUDIO_IO_ERROR_NONE != ret) {
840 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to prepare audio : %d", ret);
841 /* unset volume policy, volume will be 100% */
842 __unset_policy_for_playing();
844 ttsd_data_destroy_sound_data(sound_data);
848 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Prepare audio");
849 g_audio_state = AUDIO_STATE_PLAY;
850 } // (AUDIO_STATE_READY == g_audio_state || AUDIO_STATE_WAIT_FOR_PLAYING == g_audio_state)
852 char* temp_data = sound_data->data;
853 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Before audio_out_write. data(%p), data[%d](%p), uid(%u), utt_id(%d), len(%d)",
854 temp_data, idx, &temp_data[idx], player->uid, sound_data->utt_id, len);
856 __write_buffer_dump_file(&temp_data[idx], len);
858 ret = audio_out_write(g_audio_h, &temp_data[idx], len);
860 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to audio write - %d", ret);
863 SLOG(LOG_INFO, tts_tag(), "[Player INFO] After audio_out_write");
866 if (NULL == g_playing_info && APP_STATE_PAUSED != player->state) {
867 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
868 g_audio_state = AUDIO_STATE_READY;
869 ret = audio_out_unprepare(g_audio_h);
870 if (AUDIO_IO_ERROR_NONE != ret) {
871 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
873 /* unset volume policy, volume will be 100% */
874 __unset_policy_for_playing();
876 ttsd_data_destroy_sound_data(sound_data);
879 } // (NULL == g_playing_info && APP_STATE_PAUSED != player->state)
881 if (APP_STATE_PAUSED == player->state) {
883 SLOG(LOG_DEBUG, tts_tag(), "[Player] player(%p)", player);
884 ttsd_data_destroy_sound_data(player->paused_data);
885 player->paused_data = sound_data;
887 player->is_paused_data = true;
890 g_audio_state = AUDIO_STATE_READY;
892 SLOG(LOG_INFO, tts_tag(), "[Player] Stop player thread by pause");
894 /* Request prepare */
895 ret = audio_out_unprepare(g_audio_h);
896 if (AUDIO_IO_ERROR_NONE != ret) {
897 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
899 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
901 /* unset volume policy, volume will be 100% */
902 __unset_policy_for_playing();
904 } // (APP_STATE_PAUSED == player->state)
905 } // while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state)
907 if (NULL == g_playing_info && APP_STATE_READY == player->state) {
909 g_audio_state = AUDIO_STATE_READY;
910 SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread");
912 /* Request prepare */
913 ret = audio_out_unprepare(g_audio_h);
914 if (AUDIO_IO_ERROR_NONE != ret) {
915 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
917 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
920 /* unset volume policy, volume will be 100% */
921 __unset_policy_for_playing();
922 ttsd_data_destroy_sound_data(sound_data);
925 } // (NULL == g_playing_info && APP_STATE_READY == player->state)
927 if ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) &&
928 (TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
929 /* send utterence finish signal */
930 int pid = ttsd_data_get_pid(player->uid);
933 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid);
934 /* unset volume policy, volume will be 100% */
935 __unset_policy_for_playing();
936 ttsd_data_destroy_sound_data(sound_data);
942 __close_buffer_dump_file();
944 __set_playing_status(false);
945 if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
946 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%u), uttid(%d)",
947 pid, player->uid, sound_data->utt_id);
948 /* unset volume policy, volume will be 100% */
949 __unset_policy_for_playing();
950 ttsd_data_destroy_sound_data(sound_data);
955 SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, sound_data->utt_id);
956 } // ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) && (TTSE_RESULT_EVENT_FINISH == sound_data->event))
958 ttsd_data_destroy_sound_data(sound_data);
961 if (NULL == g_playing_info) {
962 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
963 g_audio_state = AUDIO_STATE_READY;
964 ret = audio_out_unprepare(g_audio_h);
965 if (AUDIO_IO_ERROR_NONE != ret) {
966 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
968 /* unset volume policy, volume will be 100% */
969 __unset_policy_for_playing();
970 ttsd_data_destroy_sound_data(sound_data);
974 } // end of 1st while(1)
977 static void __play_thread(void *data, Ecore_Thread *thread)
979 SLOG(LOG_INFO, tts_tag(), "[Player] play thread is on");
981 while (g_player_init) {
982 SLOG(LOG_INFO, tts_tag(), "[Player] Wait play request...");
983 pthread_cond_wait(&g_play_thread_cond, &g_play_thread_mutex);
984 if (false == g_player_init) {
985 SLOG(LOG_INFO, tts_tag(), "[Player] Player is released");
986 pthread_mutex_unlock(&g_play_thread_mutex);
990 __play_thread_old(data, thread);
991 pthread_mutex_unlock(&g_play_thread_mutex);
992 pthread_mutex_lock(&g_player_control_mutex);
993 g_playing_info = NULL;
994 pthread_mutex_unlock(&g_player_control_mutex);
998 int __create_ducking_handle(void)
1001 if (NULL == g_media_stream_ducking) {
1002 ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_MEDIA, __sound_stream_ducking_state_changed_cb, NULL, &g_media_stream_ducking);
1003 if (SOUND_MANAGER_ERROR_NONE != ret)
1004 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create stream ducking for type media, ret(%d)", ret);
1006 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for media stream is already created");
1009 /* if (NULL == g_system_stream_ducking) {
1010 ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_SYSTEM, __sound_stream_ducking_state_changed_cb, NULL, &g_system_stream_ducking);
1011 if (SOUND_MANAGER_ERROR_NONE != ret)
1012 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create stream ducking for system type, ret(%d)", ret);
1014 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for system stream is already created");
1017 if (NULL == g_notification_stream_ducking) {
1018 ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_NOTIFICATION, __sound_stream_ducking_state_changed_cb, NULL, &g_notification_stream_ducking);
1019 if (SOUND_MANAGER_ERROR_NONE != ret)
1020 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create stream ducking for notification type, ret(%d)", ret);
1022 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for notification stream is already created");
1025 if (NULL == g_alarm_stream_ducking) {
1026 ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_ALARM, __sound_stream_ducking_state_changed_cb, NULL, &g_alarm_stream_ducking);
1027 if (SOUND_MANAGER_ERROR_NONE != ret)
1028 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create stream ducking for alarm type, ret(%d)", ret);
1030 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for alarm stream is already created");
1039 int ttsd_player_init()
1041 pthread_mutex_lock(&g_player_control_mutex);
1042 g_playing_info = NULL;
1043 g_audio_state = AUDIO_STATE_NONE;
1048 ecore_thread_max_set(1);
1052 if (0 == access(FOCUS_SERVER_READY, F_OK)) {
1053 SLOG(LOG_ERROR, tts_tag(), "[Player SUCCESS] focus server is available");
1056 if (0 == cnt++ % 10)
1057 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] focus server is not available");
1062 ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_INFORMATION, __player_focus_state_cb, NULL, &g_stream_info_h);
1063 if (SOUND_MANAGER_ERROR_NONE != ret) {
1064 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create stream info");
1065 pthread_mutex_unlock(&g_player_control_mutex);
1068 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create stream info");
1071 ret = __create_ducking_handle();
1072 if (SOUND_MANAGER_ERROR_NONE != ret) {
1073 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create ducking handle, ret(%d)", ret);
1075 SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Create ducking handle");
1078 ecore_thread_max_set(1);
1080 ret = __create_audio_out(TTSE_AUDIO_TYPE_RAW_S16, 16000);
1082 sound_manager_destroy_stream_information(g_stream_info_h);
1083 g_stream_info_h = NULL;
1084 pthread_mutex_unlock(&g_player_control_mutex);
1089 ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
1091 g_player_init = true;
1093 pthread_mutex_unlock(&g_player_control_mutex);
1098 static void __destroy_all_ducking_handles()
1100 SLOG(LOG_INFO, tts_tag(), "[Player] Destroy stream ducking");
1101 if (__get_duration_from_last_volume_change() <= SND_MGR_DUCKING_DURATION) {
1105 __recover_background_volume();
1108 ret = sound_manager_destroy_stream_ducking(g_media_stream_ducking);
1109 if (SOUND_MANAGER_ERROR_NONE != ret) {
1110 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy ducking handle, ret(%d)", ret);
1112 g_media_stream_ducking = NULL;
1114 /* ret = sound_manager_destroy_stream_ducking(g_system_stream_ducking);
1115 if (SOUND_MANAGER_ERROR_NONE != ret) {
1116 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy ducking handle, ret(%d)", ret);
1118 g_system_stream_ducking = NULL;
1120 ret = sound_manager_destroy_stream_ducking(g_notification_stream_ducking);
1121 if (SOUND_MANAGER_ERROR_NONE != ret) {
1122 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy ducking handle, ret(%d)", ret);
1124 g_notification_stream_ducking = NULL;
1126 ret = sound_manager_destroy_stream_ducking(g_alarm_stream_ducking);
1127 if (SOUND_MANAGER_ERROR_NONE != ret) {
1128 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy ducking handle, ret(%d)", ret);
1130 g_alarm_stream_ducking = NULL;
1133 int ttsd_player_release(void)
1135 #ifdef BUF_SAVE_MODE
1136 __close_buffer_dump_file();
1139 __set_playing_status(false);
1140 pthread_mutex_lock(&g_player_control_mutex);
1141 if (false == g_player_init) {
1142 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1143 pthread_mutex_unlock(&g_player_control_mutex);
1144 return TTSD_ERROR_OPERATION_FAILED;
1149 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] @@@@@");
1150 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
1151 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] @@@@@");
1153 /* The thread should be released */
1154 int thread_count = ecore_thread_active_get();
1156 while (0 < thread_count) {
1161 SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
1165 thread_count = ecore_thread_active_get();
1168 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Thread is released");
1170 ret = __destroy_audio_out();
1172 pthread_mutex_unlock(&g_player_control_mutex);
1176 ret = sound_manager_destroy_stream_information(g_stream_info_h);
1177 if (SOUND_MANAGER_ERROR_NONE != ret) {
1178 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy stream info");
1180 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy stream info");
1183 __destroy_all_ducking_handles();
1185 /* clear g_player_list */
1186 g_playing_info = NULL;
1187 g_player_init = false;
1188 pthread_cond_broadcast(&g_play_thread_cond);
1190 g_stream_info_h = NULL;
1192 pthread_mutex_unlock(&g_player_control_mutex);
1197 int ttsd_player_create_instance(unsigned int uid)
1199 if (false == g_player_init) {
1200 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1201 return TTSD_ERROR_OPERATION_FAILED;
1204 /* Check uid is duplicated */
1205 if (NULL != __player_get_item(uid)) {
1206 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is already registered", uid);
1210 player_s* new_client = (player_s*)calloc(1, sizeof(player_s));
1211 if (NULL == new_client) {
1212 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to allocate memory");
1213 return TTSE_ERROR_OUT_OF_MEMORY;
1216 new_client->uid = uid;
1217 new_client->event = TTSE_RESULT_EVENT_FINISH;
1218 new_client->state = APP_STATE_READY;
1219 new_client->is_paused_data = false;
1220 new_client->idx = 0;
1221 new_client->paused_data = NULL;
1223 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Player] Create player : uid(%u)", uid);
1225 g_player_list = g_list_append(g_player_list, new_client);
1230 int ttsd_player_destroy_instance(unsigned int uid)
1232 pthread_mutex_lock(&g_player_control_mutex);
1233 if (false == g_player_init) {
1234 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1235 pthread_mutex_unlock(&g_player_control_mutex);
1236 return TTSD_ERROR_OPERATION_FAILED;
1240 current = __player_get_item(uid);
1241 if (NULL == current) {
1242 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
1243 pthread_mutex_unlock(&g_player_control_mutex);
1247 if (NULL != g_playing_info) {
1248 if (uid == g_playing_info->uid) {
1249 g_playing_info = NULL;
1254 player_s *data = NULL;
1256 if (0 < g_list_length(g_player_list)) {
1257 /* Get a first item */
1258 iter = g_list_first(g_player_list);
1260 while (NULL != iter) {
1261 /* Get handle data from list */
1262 data = (player_s*)iter->data;
1266 if (uid == data->uid) {
1267 g_player_list = g_list_remove_link(g_player_list, iter);
1276 iter = g_list_next(iter);
1279 pthread_mutex_unlock(&g_player_control_mutex);
1281 SLOG(LOG_DEBUG, tts_tag(), "[PLAYER Success] Destroy instance");
1286 int ttsd_player_play(unsigned int uid)
1288 pthread_mutex_lock(&g_player_control_mutex);
1289 if (false == g_player_init) {
1290 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1291 pthread_mutex_unlock(&g_player_control_mutex);
1292 return TTSD_ERROR_OPERATION_FAILED;
1295 if (NULL != g_playing_info) {
1296 if (uid == g_playing_info->uid) {
1297 SLOG(LOG_DEBUG, tts_tag(), "[Player] uid(%u) has already played", g_playing_info->uid);
1298 pthread_mutex_unlock(&g_player_control_mutex);
1301 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] stop old player (%u)", g_playing_info->uid);
1302 pthread_mutex_unlock(&g_player_control_mutex);
1303 ttsd_player_stop(g_playing_info->uid);
1304 pthread_mutex_lock(&g_player_control_mutex);
1308 SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%u)", uid);
1312 current = __player_get_item(uid);
1313 if (NULL == current) {
1314 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
1315 pthread_mutex_unlock(&g_player_control_mutex);
1319 current->state = APP_STATE_PLAYING;
1320 g_playing_info = current;
1322 SLOG(LOG_INFO, tts_tag(), "[Player] Run thread");
1323 pthread_cond_broadcast(&g_play_thread_cond);
1325 pthread_mutex_unlock(&g_player_control_mutex);
1329 int ttsd_player_stop(unsigned int uid)
1331 pthread_mutex_lock(&g_player_control_mutex);
1332 if (false == g_player_init) {
1333 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1334 pthread_mutex_unlock(&g_player_control_mutex);
1335 return TTSD_ERROR_OPERATION_FAILED;
1338 /* check whether uid is current playing or not */
1339 if (NULL != g_playing_info) {
1340 if (uid == g_playing_info->uid) {
1341 /* release current playing info */
1342 g_playing_info = NULL;
1345 SLOG(LOG_DEBUG, tts_tag(), "[Player] No current playing");
1348 if (NULL == g_playing_info) {
1349 pthread_mutex_lock(&g_play_thread_mutex);
1350 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
1351 pthread_mutex_unlock(&g_play_thread_mutex);
1354 #ifdef BUF_SAVE_MODE
1355 __close_buffer_dump_file();
1358 __set_playing_status(false);
1359 int ret = ttsd_player_clear(uid);
1361 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to stop player, ret(%d)", ret);
1362 pthread_mutex_unlock(&g_player_control_mutex);
1366 SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Stop player : uid(%u)", uid);
1368 pthread_mutex_unlock(&g_player_control_mutex);
1372 int ttsd_player_clear(unsigned int uid)
1374 if (false == g_player_init) {
1375 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1376 return TTSD_ERROR_OPERATION_FAILED;
1381 current = __player_get_item(uid);
1382 if (NULL == current) {
1383 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
1387 if (true == current->is_paused_data) {
1388 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Clear paused data");
1389 ttsd_data_destroy_sound_data(current->paused_data);
1390 current->paused_data = NULL;
1393 current->event = TTSE_RESULT_EVENT_FINISH;
1394 current->state = APP_STATE_READY;
1395 current->is_paused_data = false;
1398 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Clear player : uid(%u)", uid);
1403 int ttsd_player_pause(unsigned int uid)
1405 pthread_mutex_lock(&g_player_control_mutex);
1406 SLOG(LOG_DEBUG, tts_tag(), "[Player] pause player : uid(%u)", uid);
1408 if (false == g_player_init) {
1409 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1410 pthread_mutex_unlock(&g_player_control_mutex);
1411 return TTSD_ERROR_OPERATION_FAILED;
1416 current = __player_get_item(uid);
1417 if (NULL == current) {
1418 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] ttsd_player_pause() : uid(%u) is not valid", uid);
1419 pthread_mutex_unlock(&g_player_control_mutex);
1423 /* check whether uid is current playing or not */
1424 if (NULL != g_playing_info) {
1425 if (uid == g_playing_info->uid) {
1426 /* release current playing info */
1427 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] release current playing info (%u)", uid);
1428 g_playing_info = NULL;
1434 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] current player (%p), g_playing_info(%p)", current, g_playing_info);
1436 current->state = APP_STATE_PAUSED;
1438 if (NULL == g_playing_info) {
1439 pthread_mutex_lock(&g_play_thread_mutex);
1440 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
1441 pthread_mutex_unlock(&g_play_thread_mutex);
1444 #ifdef BUF_SAVE_MODE
1445 __close_buffer_dump_file();
1448 __set_playing_status(false);
1449 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Pause player : uid(%u)", uid);
1451 pthread_mutex_unlock(&g_player_control_mutex);
1455 int ttsd_player_resume(unsigned int uid)
1457 pthread_mutex_lock(&g_player_control_mutex);
1458 SLOG(LOG_DEBUG, tts_tag(), "[Player] Resume player : uid(%u)", uid);
1460 if (false == g_player_init) {
1461 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1462 pthread_mutex_unlock(&g_player_control_mutex);
1463 return TTSD_ERROR_OPERATION_FAILED;
1468 current = __player_get_item(uid);
1469 if (NULL == current) {
1470 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
1471 pthread_mutex_unlock(&g_player_control_mutex);
1475 /* check current player */
1476 if (NULL != g_playing_info)
1477 g_playing_info = NULL;
1479 current->state = APP_STATE_PLAYING;
1480 g_playing_info = current;
1482 SLOG(LOG_INFO, tts_tag(), "[Player] Resume to run thread");
1483 pthread_cond_broadcast(&g_play_thread_cond);
1485 pthread_mutex_unlock(&g_player_control_mutex);
1489 int ttsd_player_all_stop()
1491 pthread_mutex_lock(&g_player_control_mutex);
1492 if (false == g_player_init) {
1493 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1494 pthread_mutex_unlock(&g_player_control_mutex);
1495 return TTSD_ERROR_OPERATION_FAILED;
1498 g_playing_info = NULL;
1501 player_s *data = NULL;
1503 if (0 < g_list_length(g_player_list)) {
1504 /* Get a first item */
1505 iter = g_list_first(g_player_list);
1507 while (NULL != iter) {
1508 /* Get handle data from list */
1509 data = (player_s*)iter->data;
1511 app_tts_state_e state;
1512 if (0 > ttsd_data_get_client_state(data->uid, &state)) {
1513 SLOG(LOG_ERROR, tts_tag(), "[player ERROR] uid(%u) is not valid", data->uid);
1514 pthread_mutex_unlock(&g_player_control_mutex);
1515 ttsd_player_destroy_instance(data->uid);
1516 pthread_mutex_lock(&g_player_control_mutex);
1517 iter = g_list_next(iter);
1521 if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
1522 data->event = TTSE_RESULT_EVENT_FINISH;
1523 data->state = APP_STATE_READY;
1525 if (true == data->is_paused_data) {
1526 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Clear paused data");
1527 ttsd_data_destroy_sound_data(data->paused_data);
1528 data->paused_data = NULL;
1531 data->is_paused_data = false;
1536 iter = g_list_next(iter);
1540 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] player all stop!!");
1542 pthread_mutex_unlock(&g_player_control_mutex);
1546 int ttsd_player_get_background_volume_ratio(double* ratio)
1548 if (false == g_player_init) {
1549 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1550 return TTSD_ERROR_OPERATION_FAILED;
1556 *ratio = g_bg_volume_ratio;
1558 return TTSD_ERROR_NONE;
1561 static Eina_Bool __modify_background_volume_async(void* data)
1563 __recover_background_volume();
1564 __change_background_volume(0);
1565 SLOG(LOG_INFO, tts_tag(), "[BG] Modify background volume with delay");
1567 g_modify_background_volume = NULL;
1571 static void __modify_background_volume(void* data)
1573 if (NULL != g_delayed_unset_policy_timer) {
1574 SLOG(LOG_INFO, tts_tag(), "[BG] Background volume is going to recover soon. Skip modification");
1578 if (NULL != g_modify_background_volume) {
1579 int result = (intptr_t)ecore_timer_del(g_modify_background_volume);
1580 g_modify_background_volume = NULL;
1581 SLOG(LOG_ERROR, tts_tag(), "[BG] Remove modify background volume timer (%d)", result);
1584 long long int diff = __get_duration_from_last_volume_change();
1585 if (diff > SND_MGR_DUCKING_DURATION) {
1586 __recover_background_volume();
1587 __change_background_volume(0);
1588 SLOG(LOG_INFO, tts_tag(), "[BG] Direct modify background volume");
1590 double delay = (double)(SND_MGR_DUCKING_DURATION - diff) / 1000.0;
1591 g_modify_background_volume = ecore_timer_add(delay, __modify_background_volume_async, (void*)CHECK_TIMER_DELETE);
1592 SLOG(LOG_INFO, tts_tag(), "[BG] Delay modifying background volume (%p), delay(%f)", g_modify_background_volume, delay);
1596 int ttsd_player_set_background_volume_ratio(double ratio)
1598 if (false == g_player_init) {
1599 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1600 return TTSD_ERROR_OPERATION_FAILED;
1603 SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] ttsd_player_set_background_volume_ratio : %lf", ratio);
1605 double prev_ratio = g_bg_volume_ratio;
1606 g_bg_volume_ratio = ratio;
1608 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Check whether sound is ducked and Change volume. as-is(%lf), to-be(%lf)", prev_ratio, g_bg_volume_ratio);
1609 if (prev_ratio == g_bg_volume_ratio) {
1610 return TTSD_ERROR_NONE;
1613 if (g_is_set_policy) {
1614 SLOG(LOG_INFO, tts_tag(), "[BG] Direct modify background volume");
1615 ecore_main_loop_thread_safe_call_async(__modify_background_volume, NULL);
1618 return TTSD_ERROR_NONE;
1621 int ttsd_player_wait_to_play(unsigned int uid)
1623 if (false == g_player_init) {
1624 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1625 return TTSD_ERROR_OPERATION_FAILED;
1628 SLOG(LOG_INFO, tts_tag(), "[Player INFO] wait to play (%u)", uid);
1630 g_audio_state = AUDIO_STATE_WAIT_FOR_PLAYING;
1632 return TTSD_ERROR_NONE;