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>
19 #include "ttsd_main.h"
20 #include "ttsd_player.h"
21 #include "ttsd_data.h"
22 #include "ttsd_dbus.h"
24 #include "tts_internal.h"
25 #include "ttsd_server.h"
28 * Internal data structure
38 int uid; /** client id */
39 app_tts_state_e state; /** client state */
41 /* Current utterance information */
42 ttse_result_event_e event; /** event of last utterance */
46 sound_data_s* paused_data;
49 #define SOUND_BUFFER_LENGTH 2048
50 #define FOCUS_SERVER_READY "/tmp/.sound_server_ready"
52 /* Sound buf save for test */
57 static char g_temp_file_name[128] = {'\0',};
61 static int g_count = 1;
64 /** player init info */
65 static bool g_player_init = false;
68 static GList *g_player_list;
70 /** current player information */
71 static player_s* g_playing_info;
74 static audio_state_e g_audio_state;
76 static ttse_audio_type_e g_audio_type;
78 static int g_sampling_rate;
80 static audio_out_h g_audio_h;
82 static sound_stream_info_h g_stream_info_h;
84 static sound_stream_ducking_h g_stream_ducking;
86 static bool ducking_flag;
88 #define SND_MGR_DUCKING_DURATION 500
90 static int g_focus_watch_id;
92 static double g_bg_volume_ratio;
98 player_s* __player_get_item(int uid)
101 player_s *data = NULL;
103 if (0 < g_list_length(g_player_list)) {
104 /* Get a first item */
105 iter = g_list_first(g_player_list);
107 while (NULL != iter) {
108 /* Get handle data from list */
109 data = (player_s*)iter->data;
112 if (uid == data->uid)
116 iter = g_list_next(iter);
123 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,
124 sound_stream_focus_change_reason_e reason_for_change, int sound_behavior, const char *extra_info, void *user_data)
126 SLOG(LOG_DEBUG, tts_tag(), "@@@ Focus state changed cb");
128 if (stream_info != g_stream_info_h) {
129 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Invalid stream info handle");
132 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);
134 if (NULL == g_playing_info) {
135 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player");
139 if (APP_STATE_PLAYING == g_playing_info->state && focus_mask == SOUND_STREAM_FOCUS_FOR_PLAYBACK && SOUND_STREAM_FOCUS_STATE_RELEASED == focus_state) {
140 if (TTSD_MODE_DEFAULT == ttsd_get_mode()) {
141 g_audio_state = AUDIO_STATE_READY;
143 int uid = g_playing_info->uid;
145 if (0 != ttsd_player_pause(uid)) {
146 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to pause the player");
150 ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
151 int pid = ttsd_data_get_pid(uid);
152 /* send message to client about changing state */
153 ttsdc_send_set_state_message(pid, uid, APP_STATE_PAUSED);
155 SLOG(LOG_DEBUG, tts_tag(), "[Player] Ignore focus state cb - mode(%d)", ttsd_get_mode());
159 /* if (AUDIO_STATE_READY == g_audio_state && focus_mask == SOUND_STREAM_FOCUS_FOR_PLAYBACK && SOUND_STREAM_FOCUS_STATE_ACQUIRED == focus_state) {
160 if (TTSD_MODE_DEFAULT == ttsd_get_mode()) {
161 g_audio_state = AUDIO_STATE_PLAY;
163 if (NULL == g_playing_info) {
164 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player");
168 if (APP_STATE_PAUSED == g_playing_info->state) {
169 int uid = g_playing_info->uid;
171 g_audio_state = AUDIO_STATE_PLAY;
172 if (0 != ttsd_player_resume(uid)) {
173 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to resume the player");
174 g_audio_state = AUDIO_STATE_READY;
178 ttsd_data_set_client_state(uid, APP_STATE_PLAYING);
179 int pid = ttsd_data_get_pid(uid);
180 ttsdc_send_set_state_message(pid, uid, APP_STATE_PLAYING);
184 SLOG(LOG_DEBUG, tts_tag(), "[Player] Ignore focus state cb - mode(%d)", ttsd_get_mode());
188 SLOG(LOG_DEBUG, tts_tag(), "@@@");
193 void __player_focus_state_watch_cb(int id, sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state, sound_stream_focus_change_reason_e reason,
194 const char *extra_info, void *user_data)
196 SLOG(LOG_DEBUG, tts_tag(), "@@@ Focus state watch cb");
198 ttsd_mode_e mode = ttsd_get_mode();
200 if (TTSD_MODE_SCREEN_READER != mode && TTSD_MODE_NOTIFICATION != mode) {
201 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] This is not screen-reader mode and notification mode.");
205 if (NULL == g_playing_info) {
206 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player");
210 if (APP_STATE_PLAYING == g_playing_info->state && SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION == reason &&
211 NULL != extra_info && 0 == strncmp(extra_info, "TTSD_MODE_INTERRUPT", strlen(extra_info))) {
212 /* If the focus is changed by "Interrupt" mode and current players of "SR" and "Noti" modes are on going, please stop the current players. */
213 g_audio_state = AUDIO_STATE_READY;
215 int uid = g_playing_info->uid;
217 if (0 != ttsd_server_stop(uid)) {
218 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to stop TTS server");
221 if (0 != ttsd_player_stop(uid)) {
222 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to stop the player");
226 ttsd_data_set_client_state(uid, APP_STATE_READY);
227 int pid = ttsd_data_get_pid(uid);
228 /* send message to client about changing state */
229 ttsdc_send_set_state_message(pid, uid, APP_STATE_READY);
231 SLOG(LOG_DEBUG, tts_tag(), "[Player] Extra info is not Interrupt mode(%s) or not playing state(%d).", extra_info, g_playing_info->state);
237 void __sound_stream_ducking_state_changed_cb(sound_stream_ducking_h stream_ducking, bool is_ducked, void *user_data)
239 SLOG(LOG_DEBUG, tts_tag(), "@@@ ducking state changed cb");
241 SLOG(LOG_DEBUG, tts_tag(), "[Player] is ducked : %d", is_ducked);
247 static void __change_background_volume()
249 int ret = SOUND_MANAGER_ERROR_NONE;
250 bool is_ducked = false;
251 ret = sound_manager_is_ducked(g_stream_ducking, &is_ducked);
253 SLOG(LOG_DEBUG, tts_tag(), "[Player] The background volume is already ducked");
257 ducking_flag = false;
258 ret = sound_manager_activate_ducking(g_stream_ducking, SND_MGR_DUCKING_DURATION, g_bg_volume_ratio);
259 if (SOUND_MANAGER_ERROR_NONE != ret) {
260 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to activate ducking");
263 SLOG(LOG_DEBUG, tts_tag(), "[Player] Activate ducking");
266 while (ducking_flag == false) {
268 SLOG(LOG_DEBUG, tts_tag(), "ducking waiting");
272 static void __recover_background_volume()
274 int ret = SOUND_MANAGER_ERROR_NONE;
275 bool is_ducked = false;
276 ret = sound_manager_is_ducked(g_stream_ducking, &is_ducked);
278 SLOG(LOG_DEBUG, tts_tag(), "[Player] The background volume is already recovered");
282 ret = sound_manager_deactivate_ducking(g_stream_ducking);
283 if (SOUND_MANAGER_ERROR_NONE != ret)
284 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to deactivate ducking");
286 SLOG(LOG_WARN, tts_tag(), "[Player] Deactivate ducking");
289 static int __create_audio_out(ttse_audio_type_e type, int rate)
292 audio_sample_type_e sample_type;
294 if (TTSE_AUDIO_TYPE_RAW_S16 == type) {
295 sample_type = AUDIO_SAMPLE_TYPE_S16_LE;
297 sample_type = AUDIO_SAMPLE_TYPE_U8;
300 ret = audio_out_create_new(rate, AUDIO_CHANNEL_MONO, sample_type, &g_audio_h);
301 if (AUDIO_IO_ERROR_NONE != ret) {
302 g_audio_state = AUDIO_STATE_NONE;
304 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio");
307 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create audio");
311 g_sampling_rate = rate;
313 g_audio_state = AUDIO_STATE_READY;
318 static int __destroy_audio_out()
320 if (NULL == g_audio_h) {
321 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current handle is not valid");
326 ret = audio_out_destroy(g_audio_h);
327 if (AUDIO_IO_ERROR_NONE != ret) {
328 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to destroy audio");
331 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy audio");
337 g_audio_state = AUDIO_STATE_NONE;
343 static void __end_play_thread(void *data, Ecore_Thread *thread)
345 SLOG(LOG_ERROR, tts_tag(), "@@@ End thread");
352 static void __set_policy_for_playing(int volume)
354 /* Set stream info */
356 ttsd_mode_e mode = ttsd_get_mode();
357 if (TTSD_MODE_DEFAULT == mode) {
358 ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
359 if (SOUND_MANAGER_ERROR_NONE != ret) {
360 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to acquire focus");
362 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Success to acquire focus (default mode)");
364 } else if (TTSD_MODE_INTERRUPT == mode) {
365 ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, "TTSD_MODE_INTERRUPT");
366 if (SOUND_MANAGER_ERROR_NONE != ret) {
367 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to acquire focus");
369 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Success to acquire focus (interrupt mode)");
373 ret = audio_out_set_sound_stream_info(g_audio_h, g_stream_info_h);
374 if (AUDIO_IO_ERROR_NONE != ret) {
375 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to set stream info");
378 __change_background_volume();
380 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] set policy for playing");
385 static void __unset_policy_for_playing()
388 ttsd_mode_e mode = ttsd_get_mode();
389 /* Unset stream info */
390 if (TTSD_MODE_DEFAULT == mode || TTSD_MODE_INTERRUPT == mode) {
391 sound_stream_focus_state_e state_for_playing = SOUND_STREAM_FOCUS_STATE_ACQUIRED;
392 ret = sound_manager_get_focus_state(g_stream_info_h, &state_for_playing, NULL);
393 if (SOUND_MANAGER_ERROR_NONE != ret) {
394 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to get focus state: %d", ret);
397 if (SOUND_STREAM_FOCUS_STATE_ACQUIRED == state_for_playing) {
398 if (TTSD_MODE_DEFAULT == mode || TTSD_MODE_INTERRUPT == mode) {
399 ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
400 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] release focus (mode: %d)", mode);
403 if (SOUND_MANAGER_ERROR_NONE != ret) {
404 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to release focus");
409 __recover_background_volume();
411 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] unset policy for playing");
416 int ttsd_player_check_current_playback_focus(bool *is_current_interrupt)
419 ttsd_mode_e mode = ttsd_get_mode();
421 if (TTSD_MODE_INTERRUPT != mode) {
422 /* check the current playback focus */
423 sound_stream_focus_change_reason_e reason;
424 int sound_behavior = 0;
425 char *extra_info = NULL;
427 ret = sound_manager_get_current_playback_focus(&reason, &sound_behavior, &extra_info);
429 SLOG(LOG_DEBUG, tts_tag(), "[Player] current playback focus: extra_info(%s), reason(%d), sound_behavior(%d)", extra_info, reason, sound_behavior);
431 if (SOUND_MANAGER_ERROR_NONE == ret && NULL != extra_info && 0 < strlen(extra_info)) {
432 if (SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION == reason && 0 == strncmp(extra_info, "TTSD_MODE_INTERRUPT", strlen(extra_info))) {
433 SLOG(LOG_DEBUG, tts_tag(), "[Player] The current focus in Interrupt. Cannot play the requested sound data");
434 *is_current_interrupt = true;
439 return TTSD_ERROR_NONE;
443 if (NULL != extra_info) {
449 *is_current_interrupt = false;
451 return TTSD_ERROR_NONE;
454 static void __play_thread(void *data, Ecore_Thread *thread)
456 SLOG(LOG_DEBUG, tts_tag(), "@@@ Start thread");
462 snprintf(g_temp_file_name, sizeof(g_temp_file_name), "/tmp/tts_temp_%d_%d", getpid(), g_count);
463 int ret = access(g_temp_file_name, 0);
466 SLOG(LOG_ERROR, tts_tag(), "[Recorder ERROR] File is already exist");
467 if (0 == remove(g_temp_file_name)) {
468 SLOG(LOG_DEBUG, tts_tag(), "[Recorder] Remove file");
478 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Recorder] Temp file name=[%s]", g_temp_file_name);
481 g_pFile = fopen(g_temp_file_name, "wb+x");
483 SLOG(LOG_ERROR, tts_tag(), "[Recorder ERROR] File not found!");
488 if (NULL == g_playing_info) {
489 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] No current player");
493 player_s* player = g_playing_info;
494 sound_data_s* sound_data = NULL;
497 int len = SOUND_BUFFER_LENGTH;
500 /* set volume policy as 40% */
501 __set_policy_for_playing(40);
503 if (true == player->is_paused_data) {
505 sound_data = player->paused_data;
506 player->paused_data = NULL;
510 player->is_paused_data = false;
513 if (NULL == sound_data) {
514 /* Request unprepare */
515 ret = audio_out_unprepare(g_audio_h);
516 if (AUDIO_IO_ERROR_NONE != ret) {
517 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
519 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
522 g_audio_state = AUDIO_STATE_READY;
524 /* unset volume policy, volume will be 100% */
525 __unset_policy_for_playing();
528 SLOG(LOG_INFO, tts_tag(), "[Player] Sound info : id(%d) data(%p) size(%d) audiotype(%d) rate(%d) event(%d)",
529 sound_data->utt_id, sound_data->data, sound_data->data_size, sound_data->audio_type, sound_data->rate, sound_data->event);
532 ret = ttsd_data_get_sound_data(player->uid, &sound_data);
533 if (0 != ret || NULL == sound_data) {
535 SLOG(LOG_DEBUG, tts_tag(), "[Player] No sound data. Waiting mode");
537 /* wait for new audio data come */
540 if (NULL == g_playing_info) {
541 /* current playing uid is replaced */
542 SLOG(LOG_INFO, tts_tag(), "[Player] Finish thread");
543 if (AUDIO_STATE_PLAY == g_audio_state) {
544 /* release audio & recover session */
545 ret = audio_out_unprepare(g_audio_h);
546 if (AUDIO_IO_ERROR_NONE != ret) {
547 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
549 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
551 g_audio_state = AUDIO_STATE_READY;
553 /* unset volume policy, volume will be 100% */
554 __unset_policy_for_playing();
556 } else if (0 < ttsd_data_get_sound_data_size(player->uid)) {
557 /* new audio data come */
558 SLOG(LOG_INFO, tts_tag(), "[Player] Resume thread");
562 /* If engine is not on processing */
563 if (TTSD_SYNTHESIS_CONTROL_DOING != ttsd_get_synth_control()) {
564 if (AUDIO_STATE_PLAY == g_audio_state) {
565 /* release audio & recover session */
566 ret = audio_out_unprepare(g_audio_h);
567 if (AUDIO_IO_ERROR_NONE != ret) {
568 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
570 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
572 g_audio_state = AUDIO_STATE_READY;
574 /* unset volume policy, volume will be 100% */
575 __unset_policy_for_playing();
580 SLOG(LOG_INFO, tts_tag(), "[Player] Finish to wait for new audio data come");
582 if (AUDIO_STATE_READY == g_audio_state) {
583 /* set volume policy as 40%, when resume play thread*/
584 __set_policy_for_playing(40);
587 /* resume play thread */
588 player->state = APP_STATE_PLAYING;
592 /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
593 * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
594 * When previous wdata's event is 'finish' and current wdata's event is 'finish',
595 * the player should send utt started event.
597 if (TTSE_RESULT_EVENT_START == sound_data->event ||
598 (TTSE_RESULT_EVENT_FINISH == player->event && TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
599 int pid = ttsd_data_get_pid(player->uid);
602 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
603 /* unset volume policy, volume will be 100% */
604 __unset_policy_for_playing();
609 if (0 != ttsdc_send_utt_start_message(pid, player->uid, sound_data->utt_id)) {
610 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%d), uttid(%d)",
611 pid, player->uid, sound_data->utt_id);
613 SLOG(LOG_INFO, tts_tag(), "[Player] Start utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
616 /* Save last event to check utterance start */
617 player->event = sound_data->event;
620 if (NULL == sound_data->data || 0 >= sound_data->data_size) {
621 if (TTSE_RESULT_EVENT_FINISH == sound_data->event) {
622 SLOG(LOG_DEBUG, tts_tag(), "No sound data");
623 /* send utterence finish signal */
624 int pid = ttsd_data_get_pid(player->uid);
627 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
628 /* unset volume policy, volume will be 100% */
629 __unset_policy_for_playing();
633 __unset_policy_for_playing();
635 if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
636 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)",
637 pid, player->uid, sound_data->utt_id);
639 SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
642 SLOG(LOG_INFO, tts_tag(), "[Player] Event(%d) utterance : uid(%d), uttid(%d)", sound_data->event, player->uid, sound_data->utt_id);
643 ttsd_data_clear_sound_data(player->uid, &sound_data);
648 if (g_sampling_rate != sound_data->rate || g_audio_type != sound_data->audio_type) {
649 SLOG(LOG_INFO, tts_tag(), "[Player] Change audio handle : org type(%d) org rate(%d)", g_audio_type, g_sampling_rate);
650 if (NULL != g_audio_h) {
651 __destroy_audio_out();
654 if (0 > __create_audio_out(sound_data->audio_type, sound_data->rate)) {
655 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio out");
656 /* unset volume policy, volume will be 100% */
657 __unset_policy_for_playing();
659 ttsd_data_clear_sound_data(player->uid, &sound_data);
664 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Success to destroy and recreate audio out");
665 __set_policy_for_playing(40);
668 while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) {
669 if ((unsigned int)idx >= sound_data->data_size)
672 if ((unsigned int)idx + SOUND_BUFFER_LENGTH > sound_data->data_size) {
673 len = sound_data->data_size - idx;
675 len = SOUND_BUFFER_LENGTH;
678 if (AUDIO_STATE_READY == g_audio_state) {
679 /* Request prepare */
680 ret = audio_out_prepare(g_audio_h);
681 if (AUDIO_IO_ERROR_NONE != ret) {
682 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to prepare audio : %d", ret);
683 g_playing_info = NULL;
684 /* unset volume policy, volume will be 100% */
685 __unset_policy_for_playing();
687 ttsd_data_clear_sound_data(player->uid, &sound_data);
691 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Prepare audio");
692 g_audio_state = AUDIO_STATE_PLAY;
695 char* temp_data = sound_data->data;
696 SLOG(LOG_INFO, tts_tag(), "[Player INFO] Before audio_out_write. data(%p), data[%d](%p), uid(%d), utt_id(%d), len(%d)",
697 temp_data, idx, &temp_data[idx], player->uid, sound_data->utt_id, len);
699 /* write pcm buffer */
700 fwrite(&temp_data[idx], 1, len, g_pFile);
702 ret = audio_out_write(g_audio_h, &temp_data[idx], len);
704 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to audio write - %d", ret);
707 SLOG(LOG_INFO, tts_tag(), "[Player INFO] After audio_out_write");
710 if (NULL == g_playing_info && APP_STATE_PAUSED != player->state) {
711 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
712 g_audio_state = AUDIO_STATE_READY;
713 ret = audio_out_unprepare(g_audio_h);
714 if (AUDIO_IO_ERROR_NONE != ret) {
715 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
717 /* unset volume policy, volume will be 100% */
718 __unset_policy_for_playing();
720 ttsd_data_clear_sound_data(player->uid, &sound_data);
725 if (APP_STATE_PAUSED == player->state) {
727 SLOG(LOG_DEBUG, tts_tag(), "[Player] player(%p)", player);
728 player->paused_data = sound_data;
730 player->is_paused_data = true;
733 g_audio_state = AUDIO_STATE_READY;
735 SLOG(LOG_INFO, tts_tag(), "[Player] Stop player thread by pause");
737 /* Request prepare */
738 ret = audio_out_unprepare(g_audio_h);
739 if (AUDIO_IO_ERROR_NONE != ret) {
740 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
742 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
744 /* unset volume policy, volume will be 100% */
745 __unset_policy_for_playing();
750 if (NULL == g_playing_info && APP_STATE_READY == player->state) {
752 g_audio_state = AUDIO_STATE_READY;
753 SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread");
755 /* Request prepare */
756 ret = audio_out_unprepare(g_audio_h);
757 if (AUDIO_IO_ERROR_NONE != ret) {
758 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
760 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
763 ttsd_data_clear_sound_data(player->uid, &sound_data);
764 /* unset volume policy, volume will be 100% */
765 __unset_policy_for_playing();
769 if ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) &&
770 (TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
771 /* send utterence finish signal */
772 int pid = ttsd_data_get_pid(player->uid);
775 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
776 /* unset volume policy, volume will be 100% */
777 __unset_policy_for_playing();
782 if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
783 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)",
784 pid, player->uid, sound_data->utt_id);
785 /* unset volume policy, volume will be 100% */
786 __unset_policy_for_playing();
788 ttsd_data_clear_sound_data(player->uid, &sound_data);
792 SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
795 ttsd_data_clear_sound_data(player->uid, &sound_data);
797 if (NULL == g_playing_info) {
798 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
799 g_audio_state = AUDIO_STATE_READY;
800 ret = audio_out_unprepare(g_audio_h);
801 if (AUDIO_IO_ERROR_NONE != ret) {
802 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
804 /* unset volume policy, volume will be 100% */
805 __unset_policy_for_playing();
815 int ttsd_player_init()
817 g_playing_info = NULL;
818 g_audio_state = AUDIO_STATE_NONE;
823 ecore_thread_max_set(1);
827 if (0 == access(FOCUS_SERVER_READY, F_OK)) {
828 SLOG(LOG_ERROR, tts_tag(), "[Player SUCCESS] focus server is available");
832 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] focus server is not available");
837 ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_INFORMATION, __player_focus_state_cb, NULL, &g_stream_info_h);
838 if (SOUND_MANAGER_ERROR_NONE != ret) {
839 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create stream info");
842 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create stream info");
845 /* add sound focus state watch callback */
846 ret = sound_manager_add_focus_state_watch_cb(SOUND_STREAM_FOCUS_FOR_PLAYBACK, __player_focus_state_watch_cb, NULL, &g_focus_watch_id);
847 if (SOUND_MANAGER_ERROR_NONE != ret) {
848 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to add sound focus watch callback");
849 sound_manager_destroy_stream_information(g_stream_info_h);
852 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Add sound focus watch callback");
855 ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_MEDIA, __sound_stream_ducking_state_changed_cb, NULL, &g_stream_ducking);
856 if (SOUND_MANAGER_ERROR_NONE != ret)
857 SLOG(LOG_ERROR, tts_tag(), "[Player WARNING] Fail to create stream ducking");
859 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create stream ducking");
861 ecore_thread_max_set(1);
863 ret = __create_audio_out(TTSE_AUDIO_TYPE_RAW_S16, 16000);
865 sound_manager_destroy_stream_information(g_stream_info_h);
866 sound_manager_remove_focus_state_watch_cb(g_focus_watch_id);
870 g_player_init = true;
875 int ttsd_player_release(void)
877 if (false == g_player_init) {
878 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
879 return TTSD_ERROR_OPERATION_FAILED;
884 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] @@@@@");
885 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
886 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] @@@@@");
888 /* The thread should be released */
889 int thread_count = ecore_thread_active_get();
891 while (0 < thread_count) {
896 SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
900 thread_count = ecore_thread_active_get();
903 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Thread is released");
905 ret = __destroy_audio_out();
909 ret = sound_manager_destroy_stream_information(g_stream_info_h);
910 if (SOUND_MANAGER_ERROR_NONE != ret) {
911 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy stream info");
913 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy stream info");
916 /* remove focus state watch callback */
917 ret = sound_manager_remove_focus_state_watch_cb(g_focus_watch_id);
918 if (SOUND_MANAGER_ERROR_NONE != ret) {
919 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to remove the focus state watch cb");
921 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Remove the focus state watch cb");
924 ret = sound_manager_destroy_stream_ducking(g_stream_ducking);
925 if (SOUND_MANAGER_ERROR_NONE != ret)
926 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy stream ducking");
928 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy stream ducking");
930 /* clear g_player_list */
931 g_playing_info = NULL;
932 g_player_init = false;
937 int ttsd_player_create_instance(int uid)
939 if (false == g_player_init) {
940 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
944 /* Check uid is duplicated */
945 if (NULL != __player_get_item(uid)) {
946 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is already registered", uid);
950 player_s* new_client = (player_s*)calloc(1, sizeof(player_s));
951 if (NULL == new_client) {
952 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to allocate memory");
953 return TTSE_ERROR_OUT_OF_MEMORY;
956 new_client->uid = uid;
957 new_client->event = TTSE_RESULT_EVENT_FINISH;
958 new_client->state = APP_STATE_READY;
959 new_client->is_paused_data = false;
961 new_client->paused_data = NULL;
963 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Player] Create player : uid(%d)", uid);
965 g_player_list = g_list_append(g_player_list, new_client);
970 int ttsd_player_destroy_instance(int uid)
972 if (false == g_player_init) {
973 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
978 current = __player_get_item(uid);
979 if (NULL == current) {
980 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
984 if (NULL != g_playing_info) {
985 if (uid == g_playing_info->uid) {
986 g_playing_info = NULL;
991 player_s *data = NULL;
993 if (0 < g_list_length(g_player_list)) {
994 /* Get a first item */
995 iter = g_list_first(g_player_list);
997 while (NULL != iter) {
998 /* Get handle data from list */
999 data = (player_s*)iter->data;
1003 if (uid == data->uid) {
1004 g_player_list = g_list_remove_link(g_player_list, iter);
1012 iter = g_list_next(iter);
1016 SLOG(LOG_DEBUG, tts_tag(), "[PLAYER Success] Destroy instance");
1021 int ttsd_player_play(int uid)
1023 if (false == g_player_init) {
1024 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1028 if (NULL != g_playing_info) {
1029 if (uid == g_playing_info->uid) {
1030 SLOG(LOG_DEBUG, tts_tag(), "[Player] uid(%d) has already played", g_playing_info->uid);
1033 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] stop old player (%d)", g_playing_info->uid);
1034 ttsd_player_stop(g_playing_info->uid);
1038 SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%d)", uid);
1040 /* Check sound queue size */
1041 if (0 == ttsd_data_get_sound_data_size(uid)) {
1042 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
1048 current = __player_get_item(uid);
1049 if (NULL == current) {
1050 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
1054 current->state = APP_STATE_PLAYING;
1056 g_playing_info = current;
1058 SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
1060 if (0 < ttsd_data_get_sound_data_size(current->uid)) {
1061 SLOG(LOG_INFO, tts_tag(), "[Player] Run thread");
1062 ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
1068 int ttsd_player_stop(int uid)
1070 if (false == g_player_init) {
1071 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1077 current = __player_get_item(uid);
1078 if (NULL == current) {
1079 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
1083 /* check whether uid is current playing or not */
1084 if (NULL != g_playing_info) {
1085 if (uid == g_playing_info->uid) {
1086 /* release current playing info */
1087 g_playing_info = NULL;
1090 SLOG(LOG_DEBUG, tts_tag(), "[Player] No current playing");
1093 if (true == current->is_paused_data) {
1094 if (NULL != current->paused_data) {
1095 if (NULL != current->paused_data->data) {
1096 free(current->paused_data->data);
1097 current->paused_data->data = NULL;
1100 free(current->paused_data);
1101 current->paused_data = NULL;
1105 current->event = TTSE_RESULT_EVENT_FINISH;
1106 current->state = APP_STATE_READY;
1107 current->is_paused_data = false;
1110 if (NULL == g_playing_info) {
1111 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
1112 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
1113 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
1115 /* The thread should be released */
1116 int thread_count = ecore_thread_active_get();
1118 while (0 < thread_count) {
1123 SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
1127 thread_count = ecore_thread_active_get();
1130 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
1131 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
1132 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
1135 SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Stop player : uid(%d)", uid);
1140 int ttsd_player_clear(int uid)
1142 if (false == g_player_init) {
1143 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1149 current = __player_get_item(uid);
1150 if (NULL == current) {
1151 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
1155 if (true == current->is_paused_data) {
1156 if (NULL != current->paused_data) {
1157 if (NULL != current->paused_data->data) {
1158 free(current->paused_data->data);
1159 current->paused_data->data = NULL;
1162 free(current->paused_data);
1163 current->paused_data = NULL;
1167 current->event = TTSE_RESULT_EVENT_FINISH;
1168 current->state = APP_STATE_READY;
1169 current->is_paused_data = false;
1172 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Clear player : uid(%d)", uid);
1177 int ttsd_player_pause(int uid)
1179 SLOG(LOG_DEBUG, tts_tag(), "[Player] pause player : uid(%d)", uid);
1181 if (false == g_player_init) {
1182 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1188 current = __player_get_item(uid);
1189 if (NULL == current) {
1190 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] ttsd_player_pause() : uid(%d) is not valid", uid);
1194 /* check whether uid is current playing or not */
1195 if (NULL != g_playing_info) {
1196 if (uid == g_playing_info->uid) {
1197 /* release current playing info */
1198 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] release current playing info (%d)", uid);
1199 g_playing_info = NULL;
1205 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] current player (%p), g_playing_info(%p)", current, g_playing_info);
1207 current->state = APP_STATE_PAUSED;
1209 if (NULL == g_playing_info) {
1210 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
1211 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
1212 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
1214 /* The thread should be released */
1215 int thread_count = ecore_thread_active_get();
1217 while (0 < thread_count) {
1221 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] current(%p), state(%d)", current, current->state);
1224 SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue. current(%p) current state(%d)", current, current->state);
1228 thread_count = ecore_thread_active_get();
1231 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
1232 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
1233 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
1237 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Pause player : uid(%d)", uid);
1242 int ttsd_player_resume(int uid)
1244 SLOG(LOG_DEBUG, tts_tag(), "[Player] Resume player : uid(%d)", uid);
1246 if (false == g_player_init) {
1247 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1253 current = __player_get_item(uid);
1254 if (NULL == current) {
1255 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
1259 /* check current player */
1260 if (NULL != g_playing_info)
1261 g_playing_info = NULL;
1263 current->state = APP_STATE_PLAYING;
1264 g_playing_info = current;
1266 SLOG(LOG_INFO, tts_tag(), "[Player] Resume to run thread");
1267 ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
1272 int ttsd_player_all_stop()
1274 if (false == g_player_init) {
1275 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1279 g_playing_info = NULL;
1282 player_s *data = NULL;
1284 if (0 < g_list_length(g_player_list)) {
1285 /* Get a first item */
1286 iter = g_list_first(g_player_list);
1288 while (NULL != iter) {
1289 /* Get handle data from list */
1290 data = (player_s*)iter->data;
1292 app_tts_state_e state;
1293 if (0 > ttsd_data_get_client_state(data->uid, &state)) {
1294 SLOG(LOG_ERROR, tts_tag(), "[player ERROR] uid(%d) is not valid", data->uid);
1295 ttsd_player_destroy_instance(data->uid);
1296 iter = g_list_next(iter);
1300 if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
1301 data->event = TTSE_RESULT_EVENT_FINISH;
1302 data->state = APP_STATE_READY;
1304 if (true == data->is_paused_data) {
1305 if (NULL != data->paused_data) {
1306 if (NULL != data->paused_data->data) {
1307 free(data->paused_data->data);
1308 data->paused_data->data = NULL;
1311 free(data->paused_data);
1312 data->paused_data = NULL;
1316 data->is_paused_data = false;
1321 iter = g_list_next(iter);
1325 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] player all stop!!");
1330 int ttsd_player_play_pcm(int uid)
1332 if (false == g_player_init) {
1333 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1337 if (NULL != g_playing_info) {
1338 if (uid == g_playing_info->uid) {
1339 SLOG(LOG_DEBUG, tts_tag(), "[Player] uid(%d) has already played", g_playing_info->uid);
1342 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] stop old player (%d)", g_playing_info->uid);
1343 ttsd_player_stop(g_playing_info->uid);
1347 SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%d)", uid);
1349 /* Check sound queue size */
1350 if (0 == ttsd_data_get_sound_data_size(uid)) {
1351 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
1356 current = __player_get_item(uid);
1357 if (NULL == current) {
1358 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
1362 current->state = APP_STATE_PLAYING;
1364 g_playing_info = current;
1366 SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
1368 if (0 <= ttsd_data_get_sound_data_size(current->uid)) {
1369 SLOG(LOG_INFO, tts_tag(), "[Player] Run thread");
1370 ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
1376 int ttsd_player_get_background_volume_ratio(double* ratio)
1381 *ratio = g_bg_volume_ratio;
1383 return TTSD_ERROR_NONE;
1386 int ttsd_player_set_background_volume_ratio(double ratio)
1388 SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] ttsd_player_set_background_volume_ratio : %lf", ratio);
1390 g_bg_volume_ratio = ratio;
1391 return TTSD_ERROR_NONE;