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"
25 * Internal data structure
35 int uid; /** client id */
36 app_tts_state_e state; /** client state */
38 /* Current utterance information */
39 ttse_result_event_e event; /** event of last utterance */
43 sound_data_s* paused_data;
46 #define SOUND_BUFFER_LENGTH 2048
47 #define FOCUS_SERVER_READY "/tmp/.sound_server_ready"
49 /** player init info */
50 static bool g_player_init = false;
53 static GList *g_player_list;
55 /** current player information */
56 static player_s* g_playing_info;
59 static audio_state_e g_audio_state;
61 static ttse_audio_type_e g_audio_type;
63 static int g_sampling_rate;
65 static audio_out_h g_audio_h;
67 static sound_stream_info_h g_stream_info_h;
73 player_s* __player_get_item(int uid)
76 player_s *data = NULL;
78 if (0 < g_list_length(g_player_list)) {
79 /* Get a first item */
80 iter = g_list_first(g_player_list);
82 while (NULL != iter) {
83 /* Get handle data from list */
84 data = (player_s*)iter->data;
91 iter = g_list_next(iter);
98 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,
99 sound_stream_focus_change_reason_e reason_for_change, int sound_behavior, const char *extra_info, void *user_data)
101 SLOG(LOG_DEBUG, tts_tag(), "@@@ Focus state changed cb");
103 if (stream_info != g_stream_info_h) {
104 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Invalid stream info handle");
107 SLOG(LOG_WARN, tts_tag(), "[Player] focus state changed to (%d) with reason(%d)", (int)focus_state, (int)reason_for_change);
109 if (AUDIO_STATE_PLAY == g_audio_state && focus_mask == SOUND_STREAM_FOCUS_FOR_PLAYBACK && SOUND_STREAM_FOCUS_STATE_RELEASED == focus_state) {
110 if (TTSD_MODE_DEFAULT == ttsd_get_mode()) {
111 g_audio_state = AUDIO_STATE_READY;
113 if (NULL == g_playing_info) {
114 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player");
118 if (APP_STATE_PLAYING == g_playing_info->state) {
119 int uid = g_playing_info->uid;
121 if (0 != ttsd_player_pause(uid)) {
122 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to pause the player");
126 ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
127 int pid = ttsd_data_get_pid(uid);
128 /* send message to client about changing state */
129 ttsdc_send_set_state_message(pid, uid, APP_STATE_PAUSED);
132 SLOG(LOG_DEBUG, tts_tag(), "[Player] Ignore focus state cb - mode(%d)", ttsd_get_mode());
136 SLOG(LOG_DEBUG, tts_tag(), "@@@");
141 static int __create_audio_out(ttse_audio_type_e type, int rate)
144 audio_sample_type_e sample_type;
146 if (TTSE_AUDIO_TYPE_RAW_S16 == type) {
147 sample_type = AUDIO_SAMPLE_TYPE_S16_LE;
149 sample_type = AUDIO_SAMPLE_TYPE_U8;
152 ret = audio_out_create_new(rate, AUDIO_CHANNEL_MONO, sample_type, &g_audio_h);
153 if (AUDIO_IO_ERROR_NONE != ret) {
154 g_audio_state = AUDIO_STATE_NONE;
156 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio");
159 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create audio");
163 g_sampling_rate = rate;
165 g_audio_state = AUDIO_STATE_READY;
170 static int __destroy_audio_out()
172 if (NULL == g_audio_h) {
173 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current handle is not valid");
178 ret = audio_out_destroy(g_audio_h);
179 if (AUDIO_IO_ERROR_NONE != ret) {
180 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to destroy audio");
183 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy audio");
189 g_audio_state = AUDIO_STATE_NONE;
195 static void __end_play_thread(void *data, Ecore_Thread *thread)
197 SLOG(LOG_ERROR, tts_tag(), "@@@ End thread");
200 static void __set_policy_for_playing(int volume)
202 /* Set stream info */
204 if (TTSD_MODE_DEFAULT == ttsd_get_mode()) {
205 ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
206 if (SOUND_MANAGER_ERROR_NONE != ret) {
207 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to acquire focus");
210 ret = audio_out_set_sound_stream_info(g_audio_h, g_stream_info_h);
211 if (AUDIO_IO_ERROR_NONE != ret) {
212 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to set stream info");
218 static void __unset_policy_for_playing()
221 /* Unset stream info */
222 if (TTSD_MODE_DEFAULT == ttsd_get_mode()) {
223 sound_stream_focus_state_e state_for_playing = SOUND_STREAM_FOCUS_STATE_ACQUIRED;
224 ret = sound_manager_get_focus_state(g_stream_info_h, &state_for_playing, NULL);
225 if (SOUND_MANAGER_ERROR_NONE != ret) {
226 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to get focus state: %d", ret);
229 if (SOUND_STREAM_FOCUS_STATE_ACQUIRED == state_for_playing) {
230 ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
231 if (SOUND_MANAGER_ERROR_NONE != ret) {
232 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to release focus");
240 static void __play_thread(void *data, Ecore_Thread *thread)
242 SLOG(LOG_DEBUG, tts_tag(), "@@@ Start thread");
244 if (NULL == g_playing_info) {
245 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] No current player");
249 player_s* player = g_playing_info;
250 sound_data_s* sound_data = NULL;
253 int len = SOUND_BUFFER_LENGTH;
256 /* set volume policy as 40% */
257 __set_policy_for_playing(40);
259 if (true == player->is_paused_data) {
261 sound_data = player->paused_data;
262 player->paused_data = NULL;
266 player->is_paused_data = false;
269 if (NULL == sound_data) {
270 /* Request unprepare */
271 ret = audio_out_unprepare(g_audio_h);
272 if (AUDIO_IO_ERROR_NONE != ret) {
273 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
275 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
278 g_audio_state = AUDIO_STATE_READY;
280 /* unset volume policy, volume will be 100% */
281 __unset_policy_for_playing();
284 SLOG(LOG_INFO, tts_tag(), "[Player] Sound info : id(%d) data(%p) size(%d) audiotype(%d) rate(%d) event(%d)",
285 sound_data->utt_id, sound_data->data, sound_data->data_size, sound_data->audio_type, sound_data->rate, sound_data->event);
288 ret = ttsd_data_get_sound_data(player->uid, &sound_data);
289 if (0 != ret || NULL == sound_data) {
291 SLOG(LOG_DEBUG, tts_tag(), "[Player] No sound data. Waiting mode");
292 /* release audio & recover session */
293 ret = audio_out_unprepare(g_audio_h);
294 if (AUDIO_IO_ERROR_NONE != ret) {
295 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
297 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
299 g_audio_state = AUDIO_STATE_READY;
301 /* unset volume policy, volume will be 100% */
302 __unset_policy_for_playing();
304 /* wait for new audio data come */
307 if (NULL == g_playing_info) {
308 /* current playing uid is replaced */
309 SLOG(LOG_INFO, tts_tag(), "[Player] Finish thread");
311 } else if (0 < ttsd_data_get_sound_data_size(player->uid)) {
312 /* new audio data come */
313 SLOG(LOG_INFO, tts_tag(), "[Player] Resume thread");
318 SLOG(LOG_INFO, tts_tag(), "[Player] Finish to wait for new audio data come");
320 /* set volume policy as 40%, when resume play thread*/
321 __set_policy_for_playing(40);
323 /* resume play thread */
324 player->state = APP_STATE_PLAYING;
328 /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
329 * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
330 * When previous wdata's event is 'finish' and current wdata's event is 'finish',
331 * the player should send utt started event.
333 if (TTSE_RESULT_EVENT_START == sound_data->event ||
334 (TTSE_RESULT_EVENT_FINISH == player->event && TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
335 int pid = ttsd_data_get_pid(player->uid);
338 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
339 /* unset volume policy, volume will be 100% */
340 __unset_policy_for_playing();
342 if (NULL != sound_data->data) {
343 free(sound_data->data);
344 sound_data->data = NULL;
351 if (0 != ttsdc_send_utt_start_message(pid, player->uid, sound_data->utt_id)) {
352 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%d), uttid(%d)",
353 pid, player->uid, sound_data->utt_id);
355 SLOG(LOG_INFO, tts_tag(), "[Player] Start utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
358 /* Save last event to check utterance start */
359 player->event = sound_data->event;
362 if (NULL == sound_data->data || 0 >= sound_data->data_size) {
363 if (TTSE_RESULT_EVENT_FINISH == sound_data->event) {
364 SLOG(LOG_DEBUG, tts_tag(), "No sound data");
365 /* send utterence finish signal */
366 int pid = ttsd_data_get_pid(player->uid);
369 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
370 /* unset volume policy, volume will be 100% */
371 __unset_policy_for_playing();
372 if (NULL != sound_data->data) {
373 free(sound_data->data);
374 sound_data->data = NULL;
380 if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
381 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)",
382 pid, player->uid, sound_data->utt_id);
385 SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
386 if (NULL != sound_data->data) {
387 free(sound_data->data);
388 sound_data->data = NULL;
396 if (g_sampling_rate != sound_data->rate || g_audio_type != sound_data->audio_type) {
397 SLOG(LOG_DEBUG, tts_tag(), "[Player] Change audio handle : org type(%d) org rate(%d)", g_audio_type, g_sampling_rate);
398 if (NULL != g_audio_h) {
399 __destroy_audio_out();
402 if (0 > __create_audio_out(sound_data->audio_type, sound_data->rate)) {
403 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio out");
404 /* unset volume policy, volume will be 100% */
405 __unset_policy_for_playing();
407 if (NULL != sound_data->data) {
408 free(sound_data->data);
409 sound_data->data = NULL;
416 __set_policy_for_playing(40);
419 while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) {
420 if ((unsigned int)idx >= sound_data->data_size)
423 if ((unsigned int)idx + SOUND_BUFFER_LENGTH > sound_data->data_size) {
424 len = sound_data->data_size - idx;
426 len = SOUND_BUFFER_LENGTH;
429 if (AUDIO_STATE_READY == g_audio_state) {
430 /* Request prepare */
431 ret = audio_out_prepare(g_audio_h);
432 if (AUDIO_IO_ERROR_NONE != ret) {
433 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to prepare audio : %d", ret);
434 g_playing_info = NULL;
435 /* unset volume policy, volume will be 100% */
436 __unset_policy_for_playing();
438 if (NULL != sound_data->data) {
439 free(sound_data->data);
440 sound_data->data = NULL;
448 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Prepare audio");
449 g_audio_state = AUDIO_STATE_PLAY;
452 char* temp_data = sound_data->data;
453 ret = audio_out_write(g_audio_h, &temp_data[idx], len);
455 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to audio write - %d", ret);
460 if (NULL == g_playing_info && APP_STATE_PAUSED != player->state) {
461 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
462 g_audio_state = AUDIO_STATE_READY;
463 ret = audio_out_unprepare(g_audio_h);
464 if (AUDIO_IO_ERROR_NONE != ret) {
465 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
467 /* unset volume policy, volume will be 100% */
468 __unset_policy_for_playing();
470 if (NULL != sound_data) {
471 if (NULL != sound_data->data) {
472 free(sound_data->data);
473 sound_data->data = NULL;
483 if (APP_STATE_PAUSED == player->state) {
485 player->paused_data = sound_data;
487 player->is_paused_data = true;
490 g_audio_state = AUDIO_STATE_READY;
491 SLOG(LOG_INFO, tts_tag(), "[Player] Stop player thread by pause");
493 /* Request prepare */
494 ret = audio_out_unprepare(g_audio_h);
495 if (AUDIO_IO_ERROR_NONE != ret) {
496 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
498 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
500 /* unset volume policy, volume will be 100% */
501 __unset_policy_for_playing();
506 if (NULL == g_playing_info && APP_STATE_READY == player->state) {
508 g_audio_state = AUDIO_STATE_READY;
509 SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread");
511 /* Request prepare */
512 ret = audio_out_unprepare(g_audio_h);
513 if (AUDIO_IO_ERROR_NONE != ret) {
514 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
516 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
519 if (NULL != sound_data) {
520 if (NULL != sound_data->data) {
521 free(sound_data->data);
522 sound_data->data = NULL;
528 /* unset volume policy, volume will be 100% */
529 __unset_policy_for_playing();
533 if ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) &&
534 (TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
535 /* send utterence finish signal */
536 int pid = ttsd_data_get_pid(player->uid);
539 SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
540 /* unset volume policy, volume will be 100% */
541 __unset_policy_for_playing();
542 if (NULL != sound_data->data) {
543 free(sound_data->data);
544 sound_data->data = NULL;
552 if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
553 SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)",
554 pid, player->uid, sound_data->utt_id);
555 /* unset volume policy, volume will be 100% */
556 __unset_policy_for_playing();
557 if (NULL != sound_data->data) {
558 free(sound_data->data);
559 sound_data->data = NULL;
567 SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
570 if (NULL != sound_data) {
571 if (NULL != sound_data->data) {
572 free(sound_data->data);
573 sound_data->data = NULL;
580 if (NULL == g_playing_info) {
581 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
582 g_audio_state = AUDIO_STATE_READY;
583 ret = audio_out_unprepare(g_audio_h);
584 if (AUDIO_IO_ERROR_NONE != ret) {
585 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
587 /* unset volume policy, volume will be 100% */
588 __unset_policy_for_playing();
598 int ttsd_player_init()
600 g_playing_info = NULL;
601 g_audio_state = AUDIO_STATE_NONE;
606 ecore_thread_max_set(1);
610 if (0 == access(FOCUS_SERVER_READY, F_OK)) {
611 SLOG(LOG_ERROR, tts_tag(), "[Player SUCCESS] focus server is available");
615 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] focus server is not available");
620 ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_INFORMATION, __player_focus_state_cb, NULL, &g_stream_info_h);
621 if (SOUND_MANAGER_ERROR_NONE != ret) {
622 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create stream info");
625 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create stream info");
628 ecore_thread_max_set(1);
630 ret = __create_audio_out(TTSE_AUDIO_TYPE_RAW_S16, 16000);
634 g_player_init = true;
639 int ttsd_player_release(void)
641 if (false == g_player_init) {
642 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
643 return TTSD_ERROR_OPERATION_FAILED;
648 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] @@@@@");
649 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
650 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] @@@@@");
652 /* The thread should be released */
653 int thread_count = ecore_thread_active_get();
655 while (0 < thread_count) {
660 SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
664 thread_count = ecore_thread_active_get();
667 SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Thread is released");
669 ret = __destroy_audio_out();
673 ret = sound_manager_destroy_stream_information(g_stream_info_h);
674 if (SOUND_MANAGER_ERROR_NONE != ret) {
675 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy stream info");
677 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy stream info");
680 /* clear g_player_list */
681 g_playing_info = NULL;
682 g_player_init = false;
687 int ttsd_player_create_instance(int uid)
689 if (false == g_player_init) {
690 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
694 /* Check uid is duplicated */
695 if (NULL != __player_get_item(uid)) {
696 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is already registered", uid);
700 player_s* new_client = (player_s*)calloc(1, sizeof(player_s));
701 if (NULL == new_client) {
702 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to allocate memory");
703 return TTSE_ERROR_OUT_OF_MEMORY;
706 new_client->uid = uid;
707 new_client->event = TTSE_RESULT_EVENT_FINISH;
708 new_client->state = APP_STATE_READY;
709 new_client->is_paused_data = false;
711 new_client->paused_data = NULL;
713 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Player] Create player : uid(%d)", uid);
715 g_player_list = g_list_append(g_player_list, new_client);
720 int ttsd_player_destroy_instance(int uid)
722 if (false == g_player_init) {
723 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
728 current = __player_get_item(uid);
729 if (NULL == current) {
730 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
734 if (NULL != g_playing_info) {
735 if (uid == g_playing_info->uid) {
736 g_playing_info = NULL;
741 player_s *data = NULL;
743 if (0 < g_list_length(g_player_list)) {
744 /* Get a first item */
745 iter = g_list_first(g_player_list);
747 while (NULL != iter) {
748 /* Get handle data from list */
749 data = (player_s*)iter->data;
753 if (uid == data->uid) {
754 g_player_list = g_list_remove_link(g_player_list, iter);
762 iter = g_list_next(iter);
766 SLOG(LOG_DEBUG, tts_tag(), "[PLAYER Success] Destroy instance");
771 int ttsd_player_play(int uid)
773 if (false == g_player_init) {
774 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
778 if (NULL != g_playing_info) {
779 if (uid == g_playing_info->uid) {
780 SLOG(LOG_DEBUG, tts_tag(), "[Player] uid(%d) has already played", g_playing_info->uid);
783 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] stop old player (%d)", g_playing_info->uid);
784 ttsd_player_stop(g_playing_info->uid);
788 SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%d)", uid);
790 /* Check sound queue size */
791 if (0 == ttsd_data_get_sound_data_size(uid)) {
792 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
798 current = __player_get_item(uid);
799 if (NULL == current) {
800 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
804 current->state = APP_STATE_PLAYING;
806 g_playing_info = current;
808 SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
810 if (0 < ttsd_data_get_sound_data_size(current->uid)) {
811 SLOG(LOG_INFO, tts_tag(), "[Player] Run thread");
812 ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
818 int ttsd_player_stop(int uid)
820 if (false == g_player_init) {
821 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
827 current = __player_get_item(uid);
828 if (NULL == current) {
829 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
833 /* check whether uid is current playing or not */
834 if (NULL != g_playing_info) {
835 if (uid == g_playing_info->uid) {
836 /* release current playing info */
837 g_playing_info = NULL;
840 SLOG(LOG_DEBUG, tts_tag(), "[Player] No current playing");
843 if (true == current->is_paused_data) {
844 if (NULL != current->paused_data) {
845 if (NULL != current->paused_data->data) {
846 free(current->paused_data->data);
847 current->paused_data->data = NULL;
850 free(current->paused_data);
851 current->paused_data = NULL;
855 current->event = TTSE_RESULT_EVENT_FINISH;
856 current->state = APP_STATE_READY;
857 current->is_paused_data = false;
860 if (NULL == g_playing_info) {
861 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
862 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
863 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
865 /* The thread should be released */
866 int thread_count = ecore_thread_active_get();
868 while (0 < thread_count) {
873 SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
877 thread_count = ecore_thread_active_get();
880 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
881 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
882 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
885 SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Stop player : uid(%d)", uid);
890 int ttsd_player_clear(int uid)
892 if (false == g_player_init) {
893 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
899 current = __player_get_item(uid);
900 if (NULL == current) {
901 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
905 if (true == current->is_paused_data) {
906 if (NULL != current->paused_data) {
907 if (NULL != current->paused_data->data) {
908 free(current->paused_data->data);
909 current->paused_data->data = NULL;
912 free(current->paused_data);
913 current->paused_data = NULL;
917 current->event = TTSE_RESULT_EVENT_FINISH;
918 current->state = APP_STATE_READY;
919 current->is_paused_data = false;
922 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Clear player : uid(%d)", uid);
927 int ttsd_player_pause(int uid)
929 SLOG(LOG_DEBUG, tts_tag(), "[Player] pause player : uid(%d)", uid);
931 if (false == g_player_init) {
932 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
938 current = __player_get_item(uid);
939 if (NULL == current) {
940 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] ttsd_player_pause() : uid(%d) is not valid", uid);
944 /* check whether uid is current playing or not */
945 if (NULL != g_playing_info) {
946 if (uid == g_playing_info->uid) {
947 /* release current playing info */
948 g_playing_info = NULL;
954 current->state = APP_STATE_PAUSED;
956 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
957 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
958 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
960 /* The thread should be released */
961 int thread_count = ecore_thread_active_get();
963 while (0 < thread_count) {
968 SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
972 thread_count = ecore_thread_active_get();
975 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
976 SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
977 SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
979 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Pause player : uid(%d)", uid);
984 int ttsd_player_resume(int uid)
986 SLOG(LOG_DEBUG, tts_tag(), "[Player] Resume player : uid(%d)", uid);
988 if (false == g_player_init) {
989 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
995 current = __player_get_item(uid);
996 if (NULL == current) {
997 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
1001 /* check current player */
1002 if (NULL != g_playing_info)
1003 g_playing_info = NULL;
1005 current->state = APP_STATE_PLAYING;
1006 g_playing_info = current;
1008 SLOG(LOG_INFO, tts_tag(), "[Player] Resume to run thread");
1009 ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
1014 int ttsd_player_all_stop()
1016 if (false == g_player_init) {
1017 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1021 g_playing_info = NULL;
1024 player_s *data = NULL;
1026 if (0 < g_list_length(g_player_list)) {
1027 /* Get a first item */
1028 iter = g_list_first(g_player_list);
1030 while (NULL != iter) {
1031 /* Get handle data from list */
1032 data = (player_s*)iter->data;
1034 app_tts_state_e state;
1035 if (0 > ttsd_data_get_client_state(data->uid, &state)) {
1036 SLOG(LOG_ERROR, tts_tag(), "[player ERROR] uid(%d) is not valid", data->uid);
1037 ttsd_player_destroy_instance(data->uid);
1038 iter = g_list_next(iter);
1042 if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
1043 data->event = TTSE_RESULT_EVENT_FINISH;
1044 data->state = APP_STATE_READY;
1046 if (true == data->is_paused_data) {
1047 if (NULL != data->paused_data) {
1048 if (NULL != data->paused_data->data) {
1049 free(data->paused_data->data);
1050 data->paused_data->data = NULL;
1053 free(data->paused_data);
1054 data->paused_data = NULL;
1058 data->is_paused_data = false;
1063 iter = g_list_next(iter);
1067 SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] player all stop!!");
1072 int ttsd_player_play_pcm(int uid)
1074 if (false == g_player_init) {
1075 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
1079 if (NULL != g_playing_info) {
1080 if (uid == g_playing_info->uid) {
1081 SLOG(LOG_DEBUG, tts_tag(), "[Player] uid(%d) has already played", g_playing_info->uid);
1084 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] stop old player (%d)", g_playing_info->uid);
1085 ttsd_player_stop(g_playing_info->uid);
1089 SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%d)", uid);
1091 /* Check sound queue size */
1092 if (0 == ttsd_data_get_sound_data_size(uid)) {
1093 SLOG(LOG_WARN, tts_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
1098 current = __player_get_item(uid);
1099 if (NULL == current) {
1100 SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
1104 current->state = APP_STATE_PLAYING;
1106 g_playing_info = current;
1108 SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
1110 // if (0 < ttsd_data_get_sound_data_size(current->uid)) {
1111 SLOG(LOG_INFO, tts_tag(), "[Player] Run thread");
1112 ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);