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>
19 #include "ttsd_main.h"
20 #include "ttsd_player.h"
21 #include "ttsd_data.h"
22 #include "ttsd_dbus.h"
25 #include "BackgroundVolume.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 bool g_is_set_policy;
94 If you change this constant value. Please check the function '__set_timer_for_delay_recover()'.
95 If you choose too big value, it may cause integer overflow issue.
97 #define SND_MGR_DUCKING_DURATION 500
99 static pthread_mutex_t g_play_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
100 static pthread_mutex_t g_player_control_mutex = PTHREAD_MUTEX_INITIALIZER;
102 static pthread_cond_t g_play_thread_cond = PTHREAD_COND_INITIALIZER;
104 static BackgroundVolume* g_background_volume = nullptr;
107 * Internal Interfaces
109 static void __set_playing_status(bool is_playing)
111 int ret = vconf_set_bool(TTS_PLAYING_STATUS_KEY, is_playing ? 1 : 0);
112 SLOG(LOG_INFO, tts_tag(), "[Player] Set playing status (%s). ret(%d)", is_playing ? "True" : "False", ret);
116 static void __open_buffer_dump_file()
118 pthread_mutex_lock(&g_buf_save_mutex);
120 SLOG(LOG_ERROR, tts_tag(), "[Buffer Dump] File is already opened(%s)", g_temp_file_name);
121 pthread_mutex_unlock(&g_buf_save_mutex);
127 snprintf(g_temp_file_name, sizeof(g_temp_file_name), "/tmp/tts_temp_%d_%d", getpid(), g_count);
128 int ret = access(g_temp_file_name, 0);
131 SLOG(LOG_ERROR, tts_tag(), "[Recorder ERROR] File is already exist");
132 if (0 == remove(g_temp_file_name)) {
133 SLOG(LOG_DEBUG, tts_tag(), "[Recorder] Remove file");
143 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Recorder] Temp file name=[%s]", g_temp_file_name);
146 g_pFile = fopen(g_temp_file_name, "wb+x");
147 if (NULL == g_pFile) {
148 SLOG(LOG_ERROR, tts_tag(), "[Recorder ERROR] File not found!");
151 pthread_mutex_unlock(&g_buf_save_mutex);
154 static void __close_buffer_dump_file()
156 pthread_mutex_lock(&g_buf_save_mutex);
163 pthread_mutex_unlock(&g_buf_save_mutex);
166 static void __write_buffer_dump_file(const void* buffer, size_t length)
168 pthread_mutex_lock(&g_buf_save_mutex);
171 size_t ret = fwrite(buffer, 1, length, g_pFile);
172 SLOG(LOG_DEBUG, tts_tag(), "[Buffer Dump] Stored size(%zu / %zu)", ret, length);
174 SLOG(LOG_ERROR, tts_tag(), "[Buffer Dump] File is not opened. Please check the file open");
177 pthread_mutex_unlock(&g_buf_save_mutex);
181 static bool __is_player_valid(player_s* player)
183 if (NULL == player || NULL == g_playing_info) {
184 SLOG(LOG_ERROR, tts_tag(), "[ERROR] player is NULL");
188 if (g_playing_info != player || g_playing_info->uid != player->uid) {
189 SLOG(LOG_ERROR, tts_tag(), "[ERROR] player is not current player");
196 player_s* __player_get_item(unsigned int uid)
199 player_s *data = NULL;
201 if (0 < g_list_length(g_player_list)) {
202 /* Get a first item */
203 iter = g_list_first(g_player_list);
205 while (NULL != iter) {
206 /* Get handle data from list */
207 data = (player_s*)iter->data;
210 if (uid == data->uid)
214 iter = g_list_next(iter);
221 static bool __is_focus_released_on_playing(sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state)
223 if (NULL == g_playing_info) {
224 SLOG(LOG_INFO, tts_tag(), "[Player] No current player");
228 if (APP_STATE_PLAYING != g_playing_info->state || AUDIO_STATE_NONE == g_audio_state || AUDIO_STATE_READY == g_audio_state) {
229 SLOG(LOG_INFO, tts_tag(), "[Player] Audio is not played");
233 if (SOUND_STREAM_FOCUS_FOR_PLAYBACK != focus_mask || SOUND_STREAM_FOCUS_STATE_RELEASED != focus_state) {
234 SLOG(LOG_INFO, tts_tag(), "[Player] Playback focus is not released");
241 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,
242 sound_stream_focus_change_reason_e reason_for_change, int sound_behavior, const char *extra_info, void *user_data)
244 SLOG(LOG_DEBUG, tts_tag(), "@@@ Focus state changed cb");
245 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);
247 if (stream_info != g_stream_info_h) {
248 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Invalid stream info handle");
252 if (false == __is_focus_released_on_playing(focus_mask, focus_state)) {
253 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Playback focus is not released on playing");
257 unsigned int uid = g_playing_info->uid;
258 ttsd_mode_e mode = ttsd_data_get_mode(uid);
261 case TTSD_MODE_DEFAULT:
263 SLOG(LOG_DEBUG, tts_tag(), "[Player] Pause current player - mode(%d)", mode);
264 g_audio_state = AUDIO_STATE_READY;
266 if (0 != ttsd_player_pause(uid)) {
267 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to pause the player");
271 ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
272 int pid = ttsd_data_get_pid(uid);
274 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to get pid. uid(%u)", uid);
276 /* send message to client about changing state */
277 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Player paused. pid(%d), uid(%u)", pid, uid);
278 ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_PAUSED);
283 case TTSD_MODE_NOTIFICATION:
284 case TTSD_MODE_SCREEN_READER:
286 SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop current player - mode(%d)", mode);
287 g_audio_state = AUDIO_STATE_READY;
288 ttsd_send_all_stop();
292 case TTSD_MODE_INTERRUPT:
293 SLOG(LOG_DEBUG, tts_tag(), "[Player] Ignore focus release - mode(%d)", mode);
297 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Invalid mode - mode(%d)", mode);
301 SLOG(LOG_DEBUG, tts_tag(), "@@@");
306 static int __create_audio_out(ttse_audio_type_e type, int rate)
309 audio_sample_type_e sample_type;
311 if (TTSE_AUDIO_TYPE_RAW_S16 == type) {
312 sample_type = AUDIO_SAMPLE_TYPE_S16_LE;
314 sample_type = AUDIO_SAMPLE_TYPE_U8;
317 ret = audio_out_create_new(rate, AUDIO_CHANNEL_MONO, sample_type, &g_audio_h);
318 if (AUDIO_IO_ERROR_NONE != ret) {
319 g_audio_state = AUDIO_STATE_NONE;
321 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio");
324 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create audio");
328 g_sampling_rate = rate;
330 g_audio_state = AUDIO_STATE_READY;
335 static int __destroy_audio_out()
337 if (NULL == g_audio_h) {
338 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current handle is not valid");
343 ret = audio_out_destroy(g_audio_h);
344 if (AUDIO_IO_ERROR_NONE != ret) {
345 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to destroy audio");
348 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy audio");
351 g_audio_type = TTSE_AUDIO_TYPE_RAW_S16;
354 g_audio_state = AUDIO_STATE_NONE;
360 static void __end_play_thread(void *data, Ecore_Thread *thread)
362 SLOG(LOG_ERROR, tts_tag(), "@@@ End thread");
365 static void __set_policy_for_playing(void)
367 /* Set stream info */
368 const char* extra_info = NULL;
369 if (TTSD_MODE_INTERRUPT == ttsd_get_mode()) {
370 extra_info = "TTSD_MODE_INTERRUPT";
373 int ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, extra_info);
374 if (SOUND_MANAGER_ERROR_NONE != ret) {
375 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to acquire focus");
377 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Success to acquire focus");
380 ret = audio_out_set_sound_stream_info(g_audio_h, g_stream_info_h);
381 if (AUDIO_IO_ERROR_NONE != ret) {
382 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to set stream info");
385 g_background_volume->applyVolumeRatio();
386 g_is_set_policy = true;
387 SLOG(LOG_ERROR, tts_tag(), "[BG] g_is_set_policy(%d)", g_is_set_policy);
388 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] set policy for playing");
393 static void __unset_policy_for_playing()
395 /* Unset stream info */
396 sound_stream_focus_state_e state_for_playing = SOUND_STREAM_FOCUS_STATE_ACQUIRED;
397 int ret = sound_manager_get_focus_state(g_stream_info_h, &state_for_playing, NULL);
398 if (SOUND_MANAGER_ERROR_NONE != ret) {
399 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to get focus state: %d", ret);
402 if (SOUND_STREAM_FOCUS_STATE_ACQUIRED == state_for_playing) {
403 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] release focus (mode: %d)", ttsd_get_mode());
404 ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
405 if (SOUND_MANAGER_ERROR_NONE != ret) {
406 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to release focus: %d", ret);
410 g_background_volume->recoverVolumeRatio();
411 g_is_set_policy = false;
412 SLOG(LOG_ERROR, tts_tag(), "[BG] g_is_set_policy(%d)", g_is_set_policy);
413 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] unset policy for playing");
418 static bool __does_interrupt_have_focus(sound_stream_focus_change_reason_e reason, int sound_behavior, char *extra_info)
420 SLOG(LOG_DEBUG, tts_tag(), "[Player] current Playback focus: extra_info(%s), reason(%d), sound_behavior(%d)", extra_info, reason, sound_behavior);
421 if (SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION != reason) {
425 if (NULL == extra_info || 0 >= strlen(extra_info) || 0 != strncmp(extra_info, "TTSD_MODE_INTERRUPT", EXTRA_INFO_LENGTH)) {
432 bool ttsd_player_does_interrupt_have_playback_focus()
434 sound_stream_focus_change_reason_e reason;
435 int sound_behavior = 0;
436 char *extra_info = NULL;
437 if (SOUND_MANAGER_ERROR_NONE != sound_manager_get_current_playback_focus(&reason, &sound_behavior, &extra_info)) {
438 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to get focus information");
442 bool result = __does_interrupt_have_focus(reason, sound_behavior, extra_info);
447 static void __play_thread_old(void *data, Ecore_Thread *thread)
449 SLOG(LOG_DEBUG, tts_tag(), "@@@ Start thread");
451 if (NULL == g_playing_info) {
452 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] No current player");
456 player_s* player = g_playing_info;
457 sound_data_s* sound_data = NULL;
460 int len = SOUND_BUFFER_LENGTH;
463 /* set volume policy as 40% */
464 __set_policy_for_playing();
465 while (1) { // 1st while(1)
466 /* check g_playing_info one more time */
467 if (false == __is_player_valid(player)) {
468 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Player is not valid");
469 g_audio_state = AUDIO_STATE_READY;
470 ret = audio_out_unprepare(g_audio_h);
471 if (AUDIO_IO_ERROR_NONE != ret) {
472 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
474 __unset_policy_for_playing();
478 if (true == player->is_paused_data && NULL != player->paused_data) {
480 sound_data_s* paused_data = player->paused_data;
481 player->paused_data = NULL;
483 ttsd_data_destroy_sound_data(sound_data);
484 sound_data = ttsd_data_create_sound_data(paused_data->utt_id, paused_data->data, paused_data->data_size,
485 paused_data->event, paused_data->audio_type, paused_data->rate, paused_data->channels);
486 if (NULL == sound_data || paused_data->data_size <= 0) {
487 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Out of memory OR paused_data is empty");
488 ttsd_data_destroy_sound_data(sound_data);
489 sound_data = paused_data;
490 } else { // NULL != sound_data && NULL != temp && player->paused_data->data_size > 0
491 ttsd_data_destroy_sound_data(paused_data);
496 player->is_paused_data = false;
499 if (NULL == sound_data) {
500 /* Request unprepare */
501 ret = audio_out_unprepare(g_audio_h);
502 if (AUDIO_IO_ERROR_NONE != ret) {
503 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
505 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
508 g_audio_state = AUDIO_STATE_READY;
510 /* unset volume policy, volume will be 100% */
511 __unset_policy_for_playing();
514 __set_playing_status(true);
516 SLOG(LOG_INFO, tts_tag(), "[Player] Sound info : id(%d) data(%p) size(%d) audiotype(%d) rate(%d) event(%d)",
517 sound_data->utt_id, sound_data->data, sound_data->data_size, sound_data->audio_type, sound_data->rate, sound_data->event);
518 } else { // NO player->is_paused_data
520 ret = ttsd_data_get_sound_data(player->uid, &sound_data);
521 if (0 != ret || NULL == sound_data) {
523 SLOG(LOG_ERROR, tts_tag(), "[Player] No sound data. Waiting mode");
525 /* wait for new audio data come */
526 while (1) { // 2nd while(1)
528 if (false == __is_player_valid(player)) {
529 /* current playing uid is replaced */
530 SLOG(LOG_INFO, tts_tag(), "[Player] Finish thread");
531 if (AUDIO_STATE_PLAY == g_audio_state) {
532 /* release audio & recover session */
533 ret = audio_out_unprepare(g_audio_h);
534 if (AUDIO_IO_ERROR_NONE != ret) {
535 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
537 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
539 g_audio_state = AUDIO_STATE_READY;
541 /* unset volume policy, volume will be 100% */
542 __unset_policy_for_playing();
544 } else if (0 < ttsd_data_get_sound_data_size(player->uid)) {
545 /* new audio data come */
546 SLOG(LOG_INFO, tts_tag(), "[Player] Resume thread");
547 break; // exit from 2nd while(1)
550 /* If engine is not on processing */
551 ttsd_synthesis_control_e synth_control = ttsd_get_synth_control();
552 if (TTSD_SYNTHESIS_CONTROL_DOING != synth_control) {
553 SLOG(LOG_INFO, tts_tag(), "[Server INFO] synth_control(%d)", synth_control);
554 if (AUDIO_STATE_PLAY == g_audio_state) {
555 /* release audio & recover session */
556 ret = audio_out_unprepare(g_audio_h);
557 if (AUDIO_IO_ERROR_NONE != ret) {
558 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
560 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
562 g_audio_state = AUDIO_STATE_READY;
564 /* unset volume policy, volume will be 100% */
565 __unset_policy_for_playing();
568 } // end of 2nd while(1). waiting for new audio data come
570 SLOG(LOG_INFO, tts_tag(), "[Player] Finish to wait for new audio data come");
572 if (AUDIO_STATE_READY == g_audio_state || AUDIO_STATE_WAIT_FOR_PLAYING == g_audio_state) {
573 /* set volume policy as 40%, when resume play thread*/
574 __set_policy_for_playing();
577 /* resume play thread */
578 player->state = APP_STATE_PLAYING;
580 } // NULL == sound_data
582 /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
583 * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
584 * When previous wdata's event is 'finish' and current wdata's event is 'finish',
585 * the player should send utt started event.
587 if (TTSE_RESULT_EVENT_START == sound_data->event ||
588 (TTSE_RESULT_EVENT_FINISH == player->event && TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
589 int pid = ttsd_data_get_pid(player->uid);
591 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid);
592 /* unset volume policy, volume will be 100% */
593 __unset_policy_for_playing();
594 ttsd_data_destroy_sound_data(sound_data);
600 __open_buffer_dump_file();
603 __set_playing_status(true);
604 if (0 != ttsdc_ipc_send_utt_start_message(pid, player->uid, sound_data->utt_id)) {
605 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%u), uttid(%d)",
606 pid, player->uid, sound_data->utt_id);
608 SLOG(LOG_INFO, tts_tag(), "[Player] Start utterance : uid(%u), uttid(%d)", player->uid, sound_data->utt_id);
609 } // (TTSE_RESULT_EVENT_START == sound_data->event || (TTSE_RESULT_EVENT_FINISH == player->event && TTSE_RESULT_EVENT_FINISH == sound_data->event))
611 /* Save last event to check utterance start */
612 player->event = sound_data->event;
615 if (NULL == sound_data->data || 0 >= sound_data->data_size) {
616 if (TTSE_RESULT_EVENT_FINISH == sound_data->event) {
617 SLOG(LOG_DEBUG, tts_tag(), "No sound data");
618 /* send utterence finish signal */
619 int pid = ttsd_data_get_pid(player->uid);
622 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid);
623 /* unset volume policy, volume will be 100% */
624 __unset_policy_for_playing();
625 ttsd_data_destroy_sound_data(sound_data);
630 __unset_policy_for_playing();
633 __close_buffer_dump_file();
636 __set_playing_status(false);
637 if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
638 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%u), uttid(%d)",
639 pid, player->uid, sound_data->utt_id);
641 SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, sound_data->utt_id);
643 } // TTSE_RESULT_EVENT_FINISH == sound_data->event
644 SLOG(LOG_INFO, tts_tag(), "[Player] Event(%d) utterance : uid(%u), uttid(%d)", sound_data->event, player->uid, sound_data->utt_id);
645 ttsd_data_destroy_sound_data(sound_data);
648 } // (NULL == sound_data->data || 0 >= sound_data->data_size)
649 } // NO player->is_paused_data
651 // If there is any change in audio format, recreate audio handle
652 if (g_sampling_rate != sound_data->rate || g_audio_type != sound_data->audio_type) {
653 SLOG(LOG_INFO, tts_tag(), "[Player] Change audio handle : org type(%d) org rate(%d)", g_audio_type, g_sampling_rate);
654 if (NULL != g_audio_h) {
655 __destroy_audio_out();
658 if (0 > __create_audio_out(sound_data->audio_type, sound_data->rate)) {
659 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio out");
660 /* unset volume policy, volume will be 100% */
661 __unset_policy_for_playing();
663 ttsd_data_destroy_sound_data(sound_data);
668 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Success to destroy and recreate audio out");
669 __set_policy_for_playing();
672 while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) {
673 if ((unsigned int)idx >= sound_data->data_size)
676 if ((unsigned int)idx + SOUND_BUFFER_LENGTH > sound_data->data_size) {
677 len = sound_data->data_size - idx;
679 len = SOUND_BUFFER_LENGTH;
682 // Check whether set_policy is done or not
683 if (false == g_is_set_policy) {
684 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Set policy");
685 __set_policy_for_playing();
688 if (AUDIO_STATE_READY == g_audio_state || AUDIO_STATE_WAIT_FOR_PLAYING == g_audio_state) {
689 /* Request prepare */
690 ret = audio_out_prepare(g_audio_h);
691 if (AUDIO_IO_ERROR_NONE != ret) {
692 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to prepare audio : %d", ret);
693 /* unset volume policy, volume will be 100% */
694 __unset_policy_for_playing();
696 ttsd_data_destroy_sound_data(sound_data);
700 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Prepare audio");
701 g_audio_state = AUDIO_STATE_PLAY;
702 } // (AUDIO_STATE_READY == g_audio_state || AUDIO_STATE_WAIT_FOR_PLAYING == g_audio_state)
704 char* temp_data = sound_data->data;
705 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Before audio_out_write. data(%p), data[%d](%p), uid(%u), utt_id(%d), len(%d)",
706 temp_data, idx, &temp_data[idx], player->uid, sound_data->utt_id, len);
708 __write_buffer_dump_file(&temp_data[idx], len);
710 ret = audio_out_write(g_audio_h, &temp_data[idx], len);
712 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to audio write - %d", ret);
715 SLOG(LOG_INFO, tts_tag(), "[Player INFO] After audio_out_write");
718 if (NULL == g_playing_info && APP_STATE_PAUSED != player->state) {
719 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
720 g_audio_state = AUDIO_STATE_READY;
721 ret = audio_out_unprepare(g_audio_h);
722 if (AUDIO_IO_ERROR_NONE != ret) {
723 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
725 /* unset volume policy, volume will be 100% */
726 __unset_policy_for_playing();
728 ttsd_data_destroy_sound_data(sound_data);
731 } // (NULL == g_playing_info && APP_STATE_PAUSED != player->state)
733 if (APP_STATE_PAUSED == player->state) {
735 SLOG(LOG_DEBUG, tts_tag(), "[Player] player(%p)", player);
736 ttsd_data_destroy_sound_data(player->paused_data);
737 player->paused_data = sound_data;
739 player->is_paused_data = true;
742 g_audio_state = AUDIO_STATE_READY;
744 SLOG(LOG_INFO, tts_tag(), "[Player] Stop player thread by pause");
746 /* Request prepare */
747 ret = audio_out_unprepare(g_audio_h);
748 if (AUDIO_IO_ERROR_NONE != ret) {
749 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
751 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
753 /* unset volume policy, volume will be 100% */
754 __unset_policy_for_playing();
756 } // (APP_STATE_PAUSED == player->state)
757 } // while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state)
759 if (NULL == g_playing_info && APP_STATE_READY == player->state) {
761 g_audio_state = AUDIO_STATE_READY;
762 SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread");
764 /* Request prepare */
765 ret = audio_out_unprepare(g_audio_h);
766 if (AUDIO_IO_ERROR_NONE != ret) {
767 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
769 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
772 /* unset volume policy, volume will be 100% */
773 __unset_policy_for_playing();
774 ttsd_data_destroy_sound_data(sound_data);
777 } // (NULL == g_playing_info && APP_STATE_READY == player->state)
779 if ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) &&
780 (TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
781 /* send utterence finish signal */
782 int pid = ttsd_data_get_pid(player->uid);
785 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid);
786 /* unset volume policy, volume will be 100% */
787 __unset_policy_for_playing();
788 ttsd_data_destroy_sound_data(sound_data);
794 __close_buffer_dump_file();
796 __set_playing_status(false);
797 if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
798 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%u), uttid(%d)",
799 pid, player->uid, sound_data->utt_id);
800 /* unset volume policy, volume will be 100% */
801 __unset_policy_for_playing();
802 ttsd_data_destroy_sound_data(sound_data);
807 SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, sound_data->utt_id);
808 } // ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) && (TTSE_RESULT_EVENT_FINISH == sound_data->event))
810 ttsd_data_destroy_sound_data(sound_data);
813 if (NULL == g_playing_info) {
814 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
815 g_audio_state = AUDIO_STATE_READY;
816 ret = audio_out_unprepare(g_audio_h);
817 if (AUDIO_IO_ERROR_NONE != ret) {
818 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
820 /* unset volume policy, volume will be 100% */
821 __unset_policy_for_playing();
822 ttsd_data_destroy_sound_data(sound_data);
826 } // end of 1st while(1)
829 static void __play_thread(void *data, Ecore_Thread *thread)
831 SLOG(LOG_INFO, tts_tag(), "[Player] play thread is on");
833 while (g_player_init) {
834 SLOG(LOG_INFO, tts_tag(), "[Player] Wait play request...");
835 pthread_mutex_lock(&g_play_thread_mutex);
836 pthread_cond_wait(&g_play_thread_cond, &g_play_thread_mutex);
837 if (false == g_player_init) {
838 SLOG(LOG_INFO, tts_tag(), "[Player] Player is released");
839 pthread_mutex_unlock(&g_play_thread_mutex);
843 __play_thread_old(data, thread);
844 pthread_mutex_unlock(&g_play_thread_mutex);
845 pthread_mutex_lock(&g_player_control_mutex);
846 g_playing_info = NULL;
847 pthread_mutex_unlock(&g_player_control_mutex);
854 int ttsd_player_init()
856 pthread_mutex_lock(&g_player_control_mutex);
857 g_playing_info = NULL;
858 g_audio_state = AUDIO_STATE_NONE;
863 ecore_thread_max_set(1);
867 if (0 == access(FOCUS_SERVER_READY, F_OK)) {
868 SLOG(LOG_ERROR, tts_tag(), "[Player SUCCESS] focus server is available");
872 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] focus server is not available");
877 ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_INFORMATION, __player_focus_state_cb, NULL, &g_stream_info_h);
878 if (SOUND_MANAGER_ERROR_NONE != ret) {
879 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create stream info");
880 pthread_mutex_unlock(&g_player_control_mutex);
883 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create stream info");
886 g_background_volume = new BackgroundVolume(SND_MGR_DUCKING_DURATION);
888 ecore_thread_max_set(1);
890 ret = __create_audio_out(TTSE_AUDIO_TYPE_RAW_S16, 16000);
892 sound_manager_destroy_stream_information(g_stream_info_h);
893 g_stream_info_h = NULL;
894 pthread_mutex_unlock(&g_player_control_mutex);
899 ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
901 g_is_set_policy = false;
902 g_player_init = true;
904 pthread_mutex_unlock(&g_player_control_mutex);
909 int ttsd_player_release(void)
912 __close_buffer_dump_file();
915 __set_playing_status(false);
916 pthread_mutex_lock(&g_player_control_mutex);
917 if (false == g_player_init) {
918 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
919 pthread_mutex_unlock(&g_player_control_mutex);
920 return TTSD_ERROR_OPERATION_FAILED;
925 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] @@@@@");
926 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
927 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] @@@@@");
929 /* The thread should be released */
930 int thread_count = ecore_thread_active_get();
932 while (0 < thread_count) {
937 SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
941 thread_count = ecore_thread_active_get();
944 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Thread is released");
946 ret = __destroy_audio_out();
948 pthread_mutex_unlock(&g_player_control_mutex);
952 ret = sound_manager_destroy_stream_information(g_stream_info_h);
953 if (SOUND_MANAGER_ERROR_NONE != ret) {
954 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy stream info");
956 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy stream info");
959 /* clear g_player_list */
960 g_playing_info = NULL;
961 g_player_init = false;
962 pthread_cond_broadcast(&g_play_thread_cond);
964 g_stream_info_h = NULL;
966 delete g_background_volume;
967 g_background_volume = nullptr;
969 pthread_mutex_unlock(&g_player_control_mutex);
974 int ttsd_player_create_instance(unsigned int uid)
976 if (false == g_player_init) {
977 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
978 return TTSD_ERROR_OPERATION_FAILED;
981 /* Check uid is duplicated */
982 if (NULL != __player_get_item(uid)) {
983 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is already registered", uid);
987 player_s* new_client = (player_s*)calloc(1, sizeof(player_s));
988 if (NULL == new_client) {
989 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to allocate memory");
990 return TTSE_ERROR_OUT_OF_MEMORY;
993 new_client->uid = uid;
994 new_client->event = TTSE_RESULT_EVENT_FINISH;
995 new_client->state = APP_STATE_READY;
996 new_client->is_paused_data = false;
998 new_client->paused_data = NULL;
1000 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Player] Create player : uid(%u)", uid);
1002 g_player_list = g_list_append(g_player_list, new_client);
1007 int ttsd_player_destroy_instance(unsigned int uid)
1009 pthread_mutex_lock(&g_player_control_mutex);
1010 if (false == g_player_init) {
1011 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1012 pthread_mutex_unlock(&g_player_control_mutex);
1013 return TTSD_ERROR_OPERATION_FAILED;
1017 current = __player_get_item(uid);
1018 if (NULL == current) {
1019 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
1020 pthread_mutex_unlock(&g_player_control_mutex);
1024 if (NULL != g_playing_info) {
1025 if (uid == g_playing_info->uid) {
1026 g_playing_info = NULL;
1031 player_s *data = NULL;
1033 if (0 < g_list_length(g_player_list)) {
1034 /* Get a first item */
1035 iter = g_list_first(g_player_list);
1037 while (NULL != iter) {
1038 /* Get handle data from list */
1039 data = (player_s*)iter->data;
1043 if (uid == data->uid) {
1044 g_player_list = g_list_remove_link(g_player_list, iter);
1053 iter = g_list_next(iter);
1056 pthread_mutex_unlock(&g_player_control_mutex);
1058 SLOG(LOG_DEBUG, tts_tag(), "[PLAYER Success] Destroy instance");
1063 int ttsd_player_play(unsigned int uid)
1065 pthread_mutex_lock(&g_player_control_mutex);
1066 if (false == g_player_init) {
1067 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1068 pthread_mutex_unlock(&g_player_control_mutex);
1069 return TTSD_ERROR_OPERATION_FAILED;
1072 if (NULL != g_playing_info) {
1073 if (uid == g_playing_info->uid) {
1074 SLOG(LOG_DEBUG, tts_tag(), "[Player] uid(%u) has already played", g_playing_info->uid);
1075 pthread_mutex_unlock(&g_player_control_mutex);
1078 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] stop old player (%u)", g_playing_info->uid);
1079 pthread_mutex_unlock(&g_player_control_mutex);
1080 ttsd_player_stop(g_playing_info->uid);
1081 pthread_mutex_lock(&g_player_control_mutex);
1085 SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%u)", uid);
1089 current = __player_get_item(uid);
1090 if (NULL == current) {
1091 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
1092 pthread_mutex_unlock(&g_player_control_mutex);
1096 current->state = APP_STATE_PLAYING;
1097 g_playing_info = current;
1099 SLOG(LOG_INFO, tts_tag(), "[Player] Run thread");
1100 pthread_cond_broadcast(&g_play_thread_cond);
1102 pthread_mutex_unlock(&g_player_control_mutex);
1106 int ttsd_player_stop(unsigned int uid)
1108 pthread_mutex_lock(&g_player_control_mutex);
1109 if (false == g_player_init) {
1110 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1111 pthread_mutex_unlock(&g_player_control_mutex);
1112 return TTSD_ERROR_OPERATION_FAILED;
1115 /* check whether uid is current playing or not */
1116 if (NULL != g_playing_info) {
1117 if (uid == g_playing_info->uid) {
1118 /* release current playing info */
1119 g_playing_info = NULL;
1122 SLOG(LOG_DEBUG, tts_tag(), "[Player] No current playing");
1125 if (NULL == g_playing_info) {
1126 pthread_mutex_lock(&g_play_thread_mutex);
1127 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
1128 pthread_mutex_unlock(&g_play_thread_mutex);
1131 #ifdef BUF_SAVE_MODE
1132 __close_buffer_dump_file();
1135 __set_playing_status(false);
1136 int ret = ttsd_player_clear(uid);
1138 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to stop player, ret(%d)", ret);
1139 pthread_mutex_unlock(&g_player_control_mutex);
1143 SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Stop player : uid(%u)", uid);
1145 pthread_mutex_unlock(&g_player_control_mutex);
1149 int ttsd_player_clear(unsigned int uid)
1151 if (false == g_player_init) {
1152 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1153 return TTSD_ERROR_OPERATION_FAILED;
1158 current = __player_get_item(uid);
1159 if (NULL == current) {
1160 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
1164 if (true == current->is_paused_data) {
1165 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Clear paused data");
1166 ttsd_data_destroy_sound_data(current->paused_data);
1167 current->paused_data = NULL;
1170 current->event = TTSE_RESULT_EVENT_FINISH;
1171 current->state = APP_STATE_READY;
1172 current->is_paused_data = false;
1175 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Clear player : uid(%u)", uid);
1180 int ttsd_player_pause(unsigned int uid)
1182 pthread_mutex_lock(&g_player_control_mutex);
1183 SLOG(LOG_DEBUG, tts_tag(), "[Player] pause player : uid(%u)", uid);
1185 if (false == g_player_init) {
1186 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1187 pthread_mutex_unlock(&g_player_control_mutex);
1188 return TTSD_ERROR_OPERATION_FAILED;
1193 current = __player_get_item(uid);
1194 if (NULL == current) {
1195 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] ttsd_player_pause() : uid(%u) is not valid", uid);
1196 pthread_mutex_unlock(&g_player_control_mutex);
1200 /* check whether uid is current playing or not */
1201 if (NULL != g_playing_info) {
1202 if (uid == g_playing_info->uid) {
1203 /* release current playing info */
1204 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] release current playing info (%u)", uid);
1205 g_playing_info = NULL;
1211 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] current player (%p), g_playing_info(%p)", current, g_playing_info);
1213 current->state = APP_STATE_PAUSED;
1215 if (NULL == g_playing_info) {
1216 pthread_mutex_lock(&g_play_thread_mutex);
1217 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
1218 pthread_mutex_unlock(&g_play_thread_mutex);
1221 #ifdef BUF_SAVE_MODE
1222 __close_buffer_dump_file();
1225 __set_playing_status(false);
1226 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Pause player : uid(%u)", uid);
1228 pthread_mutex_unlock(&g_player_control_mutex);
1232 int ttsd_player_resume(unsigned int uid)
1234 pthread_mutex_lock(&g_player_control_mutex);
1235 SLOG(LOG_DEBUG, tts_tag(), "[Player] Resume player : uid(%u)", uid);
1237 if (false == g_player_init) {
1238 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1239 pthread_mutex_unlock(&g_player_control_mutex);
1240 return TTSD_ERROR_OPERATION_FAILED;
1245 current = __player_get_item(uid);
1246 if (NULL == current) {
1247 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
1248 pthread_mutex_unlock(&g_player_control_mutex);
1252 /* check current player */
1253 if (NULL != g_playing_info)
1254 g_playing_info = NULL;
1256 current->state = APP_STATE_PLAYING;
1257 g_playing_info = current;
1259 SLOG(LOG_INFO, tts_tag(), "[Player] Resume to run thread");
1260 pthread_cond_broadcast(&g_play_thread_cond);
1262 pthread_mutex_unlock(&g_player_control_mutex);
1266 int ttsd_player_all_stop()
1268 pthread_mutex_lock(&g_player_control_mutex);
1269 if (false == g_player_init) {
1270 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1271 pthread_mutex_unlock(&g_player_control_mutex);
1272 return TTSD_ERROR_OPERATION_FAILED;
1275 g_playing_info = NULL;
1278 player_s *data = NULL;
1280 if (0 < g_list_length(g_player_list)) {
1281 /* Get a first item */
1282 iter = g_list_first(g_player_list);
1284 while (NULL != iter) {
1285 /* Get handle data from list */
1286 data = (player_s*)iter->data;
1288 app_tts_state_e state;
1289 if (0 > ttsd_data_get_client_state(data->uid, &state)) {
1290 SLOG(LOG_ERROR, tts_tag(), "[player ERROR] uid(%u) is not valid", data->uid);
1291 iter = g_list_next(iter);
1293 pthread_mutex_unlock(&g_player_control_mutex);
1294 ttsd_player_destroy_instance(data->uid);
1295 pthread_mutex_lock(&g_player_control_mutex);
1299 if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
1300 data->event = TTSE_RESULT_EVENT_FINISH;
1301 data->state = APP_STATE_READY;
1303 if (true == data->is_paused_data) {
1304 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Clear paused data");
1305 ttsd_data_destroy_sound_data(data->paused_data);
1306 data->paused_data = NULL;
1309 data->is_paused_data = false;
1314 iter = g_list_next(iter);
1318 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] player all stop!!");
1320 pthread_mutex_unlock(&g_player_control_mutex);
1324 int ttsd_player_get_background_volume_ratio(double* ratio)
1326 if (false == g_player_init) {
1327 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1328 return TTSD_ERROR_OPERATION_FAILED;
1331 if (NULL == ratio) {
1332 return TTSD_ERROR_INVALID_PARAMETER;
1335 *ratio = g_background_volume->getVolumeRatio();
1336 return TTSD_ERROR_NONE;
1339 int ttsd_player_set_background_volume_ratio(double ratio)
1341 if (false == g_player_init) {
1342 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1343 return TTSD_ERROR_OPERATION_FAILED;
1346 SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] ttsd_player_set_background_volume_ratio : %lf", ratio);
1347 g_background_volume->setVolumeRatio(ratio);
1349 return TTSD_ERROR_NONE;
1352 int ttsd_player_wait_to_play(unsigned int uid)
1354 if (false == g_player_init) {
1355 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1356 return TTSD_ERROR_OPERATION_FAILED;
1359 SLOG(LOG_INFO, tts_tag(), "[Player INFO] wait to play (%u)", uid);
1361 g_audio_state = AUDIO_STATE_WAIT_FOR_PLAYING;
1363 return TTSD_ERROR_NONE;