+ int ret = -1;
+ int len = SOUND_BUFFER_LENGTH;
+ int idx = 0;
+
+ /* set volume policy as 40% */
+ __set_policy_for_playing(40);
+ while (1) {
+ if (true == player->is_paused_data) {
+ /* Resume player */
+ sound_data = player->paused_data;
+ player->paused_data = NULL;
+
+ idx = player->idx;
+
+ player->is_paused_data = false;
+ player->idx = 0;
+
+ if (NULL == sound_data) {
+ /* Request unprepare */
+ ret = audio_out_unprepare(g_audio_h);
+ if (AUDIO_IO_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
+ }
+
+ g_audio_state = AUDIO_STATE_READY;
+
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+ return;
+ }
+ SLOG(LOG_INFO, tts_tag(), "[Player] Sound info : id(%d) data(%p) size(%d) audiotype(%d) rate(%d) event(%d)",
+ sound_data->utt_id, sound_data->data, sound_data->data_size, sound_data->audio_type, sound_data->rate, sound_data->event);
+ } else {
+ sound_data = NULL;
+ ret = ttsd_data_get_sound_data(player->uid, &sound_data);
+ if (0 != ret || NULL == sound_data) {
+ /* empty queue */
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] No sound data. Waiting mode");
+ /* release audio & recover session */
+ ret = audio_out_unprepare(g_audio_h);
+ if (AUDIO_IO_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
+ }
+ g_audio_state = AUDIO_STATE_READY;
+
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+
+ /* wait for new audio data come */
+ while (1) {
+ usleep(10000);
+ if (NULL == g_playing_info) {
+ /* current playing uid is replaced */
+ SLOG(LOG_INFO, tts_tag(), "[Player] Finish thread");
+ return;
+ } else if (0 < ttsd_data_get_sound_data_size(player->uid)) {
+ /* new audio data come */
+ SLOG(LOG_INFO, tts_tag(), "[Player] Resume thread");
+ break;
+ }
+ }
+
+ SLOG(LOG_INFO, tts_tag(), "[Player] Finish to wait for new audio data come");
+
+ /* set volume policy as 40%, when resume play thread*/
+ __set_policy_for_playing(40);
+
+ /* resume play thread */
+ player->state = APP_STATE_PLAYING;
+ continue;
+ }
+
+ /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
+ * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
+ * When previous wdata's event is 'finish' and current wdata's event is 'finish',
+ * the player should send utt started event.
+ */
+ if (TTSE_RESULT_EVENT_START == sound_data->event ||
+ (TTSE_RESULT_EVENT_FINISH == player->event && TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
+ int pid = ttsd_data_get_pid(player->uid);
+
+ if (pid <= 0) {
+ SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+
+ if (NULL != sound_data->data) {
+ free(sound_data->data);
+ sound_data->data = NULL;
+ }
+ free(sound_data);
+ sound_data = NULL;
+ return;
+ }
+
+ if (0 != ttsdc_send_utt_start_message(pid, player->uid, sound_data->utt_id)) {
+ SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%d), uttid(%d)",
+ pid, player->uid, sound_data->utt_id);
+ }
+ SLOG(LOG_INFO, tts_tag(), "[Player] Start utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
+ }
+
+ /* Save last event to check utterance start */
+ player->event = sound_data->event;
+ idx = 0;
+
+ if (NULL == sound_data->data || 0 >= sound_data->data_size) {
+ if (TTSE_RESULT_EVENT_FINISH == sound_data->event) {
+ SLOG(LOG_DEBUG, tts_tag(), "No sound data");
+ /* send utterence finish signal */
+ int pid = ttsd_data_get_pid(player->uid);
+
+ if (pid <= 0) {
+ SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+ if (NULL != sound_data->data) {
+ free(sound_data->data);
+ sound_data->data = NULL;
+ }
+ free(sound_data);
+ sound_data = NULL;
+ return;
+ }
+ if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
+ SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)",
+ pid, player->uid, sound_data->utt_id);
+ }
+ }
+ SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
+ if (NULL != sound_data->data) {
+ free(sound_data->data);
+ sound_data->data = NULL;
+ }
+ free(sound_data);
+ sound_data = NULL;
+ continue;
+ }
+ }
+
+ if (g_sampling_rate != sound_data->rate || g_audio_type != sound_data->audio_type) {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] Change audio handle : org type(%d) org rate(%d)", g_audio_type, g_sampling_rate);
+ if (NULL != g_audio_h) {
+ __destroy_audio_out();
+ }
+
+ if (0 > __create_audio_out(sound_data->audio_type, sound_data->rate)) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio out");
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+
+ if (NULL != sound_data->data) {
+ free(sound_data->data);
+ sound_data->data = NULL;
+ }
+ free(sound_data);
+ sound_data = NULL;
+
+ return;
+ }
+
+ __set_policy_for_playing(40);
+ }
+
+ while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) {
+ if ((unsigned int)idx >= sound_data->data_size)
+ break;
+
+ if ((unsigned int)idx + SOUND_BUFFER_LENGTH > sound_data->data_size) {
+ len = sound_data->data_size - idx;
+ } else {
+ len = SOUND_BUFFER_LENGTH;
+ }
+
+ if (AUDIO_STATE_READY == g_audio_state) {
+ /* Request prepare */
+ ret = audio_out_prepare(g_audio_h);
+ if (AUDIO_IO_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to prepare audio : %d", ret);
+ g_playing_info = NULL;
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+
+ if (NULL != sound_data->data) {
+ free(sound_data->data);
+ sound_data->data = NULL;
+ }
+
+ free(sound_data);
+ sound_data = NULL;
+
+ return;
+ }
+ SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Prepare audio");
+ g_audio_state = AUDIO_STATE_PLAY;
+ }
+
+ char* temp_data = sound_data->data;
+ ret = audio_out_write(g_audio_h, &temp_data[idx], len);
+ if (0 > ret) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to audio write - %d", ret);
+ } else {
+ idx += len;
+ }
+
+ if (NULL == g_playing_info && APP_STATE_PAUSED != player->state) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
+ g_audio_state = AUDIO_STATE_READY;
+ ret = audio_out_unprepare(g_audio_h);
+ if (AUDIO_IO_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
+ }
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+
+ if (NULL != sound_data) {
+ if (NULL != sound_data->data) {
+ free(sound_data->data);
+ sound_data->data = NULL;
+ }
+
+ free(sound_data);
+ sound_data = NULL;
+ }
+
+ return;
+ }
+
+ if (APP_STATE_PAUSED == player->state) {
+ /* Save data */
+ player->paused_data = sound_data;
+
+ player->is_paused_data = true;
+ player->idx = idx;
+
+ g_audio_state = AUDIO_STATE_READY;
+ SLOG(LOG_INFO, tts_tag(), "[Player] Stop player thread by pause");
+
+ /* Request prepare */
+ ret = audio_out_unprepare(g_audio_h);
+ if (AUDIO_IO_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
+ }
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+ return;
+ }
+ }
+
+ if (NULL == g_playing_info && APP_STATE_READY == player->state) {
+ /* player_stop */
+ g_audio_state = AUDIO_STATE_READY;
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread");
+
+ /* Request prepare */
+ ret = audio_out_unprepare(g_audio_h);
+ if (AUDIO_IO_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio");
+ }
+
+ if (NULL != sound_data) {
+ if (NULL != sound_data->data) {
+ free(sound_data->data);
+ sound_data->data = NULL;
+ }
+
+ free(sound_data);
+ sound_data = NULL;
+ }
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+ return;
+ }
+
+ if ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) &&
+ (TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
+ /* send utterence finish signal */
+ int pid = ttsd_data_get_pid(player->uid);
+
+ if (pid <= 0) {
+ SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+ if (NULL != sound_data->data) {
+ free(sound_data->data);
+ sound_data->data = NULL;
+ }
+
+ free(sound_data);
+ sound_data = NULL;
+ return;
+ }
+
+ if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
+ SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)",
+ pid, player->uid, sound_data->utt_id);
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+ if (NULL != sound_data->data) {
+ free(sound_data->data);
+ sound_data->data = NULL;
+ }
+
+ free(sound_data);
+ sound_data = NULL;
+ return;
+ }
+
+ SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
+ }
+
+ if (NULL != sound_data) {
+ if (NULL != sound_data->data) {
+ free(sound_data->data);
+ sound_data->data = NULL;
+ }
+
+ free(sound_data);
+ sound_data = NULL;
+ }
+
+ if (NULL == g_playing_info) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
+ g_audio_state = AUDIO_STATE_READY;
+ ret = audio_out_unprepare(g_audio_h);
+ if (AUDIO_IO_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
+ }
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+
+ return;
+ }
+ }
+}
+
+/*
+* Player Interfaces
+*/
+int ttsd_player_init()
+{