From 41d9c57a34bbb6f91af1e055cdab2d64e7165c32 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Fri, 14 May 2021 14:37:55 +0900 Subject: [PATCH] Fix paused data handling logic By current pause logic, player_s stores pointer of paused sound_data_s and its data index for resuming, and these are stored sperately by member variable of player_s. However, the index and sound_data_s can be managed together if sound_data_s has the member for data index, although current logic has no problem. And also, managing together is easy and safe to handle paused data. If we combine paseud index and data with sound_data_s, player_s should not store the data, because the first data of the list from ttsd_data is the last played data and it should be paused data itself. By this patch, new functions are defined on ttsd_data. These functions provides interface to access sound data. And also this patch creates new functions for checking whether client has pasued data or not. Change-Id: I9ca41a08bafdff97ae7b4ba3981897cd9485bbe4 Signed-off-by: Suyeon Hwang --- server/ttsd_data.cpp | 49 ++++++++++++++--- server/ttsd_data.h | 9 +++- server/ttsd_player.cpp | 143 ++++++++++++++++--------------------------------- 3 files changed, 97 insertions(+), 104 deletions(-) diff --git a/server/ttsd_data.cpp b/server/ttsd_data.cpp index 71baa77..c779083 100644 --- a/server/ttsd_data.cpp +++ b/server/ttsd_data.cpp @@ -37,6 +37,7 @@ typedef struct std::list m_speak_data; std::list m_wav_data; + bool paused_data_existing; std::list m_used_voice; tts_ipc_method_e ipc_method; @@ -166,6 +167,7 @@ int ttsd_data_new_client(int pid, unsigned int uid) app.mode = TTSD_MODE_DEFAULT; app.ipc_method = TTS_IPC_METHOD_UNDEFINED; app.credential = nullptr; + app.paused_data_existing = false; g_app_list.push_back(app); @@ -600,6 +602,7 @@ sound_data_s* ttsd_data_create_sound_data(int utt_id, const void* data, unsigned sound_data->audio_type = audio_type; sound_data->rate = rate; sound_data->channels = channels; + sound_data->played_data_size = 0; return sound_data; } @@ -664,10 +667,20 @@ static sound_data_s* __get_sound_data(app_data_s* app_data) return app_data->m_wav_data.front(); } -int ttsd_data_get_sound_data(unsigned int uid, sound_data_s** data) +sound_data_s* ttsd_data_get_first_sound_data(unsigned int uid) { - SLOG(LOG_DEBUG, tts_tag(), "[DATA] sound_data_s: %p", *data); + lock_guard lock(g_app_data_mutex); + app_data_s* app_data = __get_client_app_data(uid); + if (nullptr == app_data) { + SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid); + return nullptr; + } + + return __get_sound_data(app_data); +} +int ttsd_data_pop_sound_data(unsigned int uid) +{ lock_guard lock(g_app_data_mutex); app_data_s* app_data = __get_client_app_data(uid); if (nullptr == app_data) { @@ -675,15 +688,12 @@ int ttsd_data_get_sound_data(unsigned int uid, sound_data_s** data) return TTSD_ERROR_INVALID_PARAMETER; } - sound_data_s* soundData = __get_sound_data(app_data); - if (nullptr == soundData) { - SLOG(LOG_DEBUG, tts_tag(), "[DATA] There is no wav data"); + if (app_data->m_wav_data.empty()) { + SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] Sound data is empty (%u)", uid); return TTSD_ERROR_OPERATION_FAILED; } app_data->m_wav_data.pop_front(); - *data = soundData; - return TTSD_ERROR_NONE; } @@ -764,6 +774,31 @@ int ttsd_data_set_client_state(unsigned int uid, app_tts_state_e state) return TTSD_ERROR_NONE; } +int ttsd_data_set_paused_data_existing(unsigned int uid, bool is_paused_data_existing) +{ + lock_guard lock(g_app_data_mutex); + app_data_s* app_data = __get_client_app_data(uid); + if (nullptr == app_data) { + SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid); + return TTSD_ERROR_INVALID_PARAMETER; + } + + app_data->paused_data_existing = is_paused_data_existing; + return TTSD_ERROR_NONE; +} + +bool ttsd_data_is_paused_data_existing(unsigned int uid) +{ + lock_guard lock(g_app_data_mutex); + app_data_s* app_data = __get_client_app_data(uid); + if (nullptr == app_data) { + SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid); + return false; + } + + return app_data->paused_data_existing; +} + unsigned int ttsd_data_get_current_playing() { lock_guard lock(g_app_data_mutex); diff --git a/server/ttsd_data.h b/server/ttsd_data.h index f0df92f..8c9a1b6 100644 --- a/server/ttsd_data.h +++ b/server/ttsd_data.h @@ -50,6 +50,7 @@ typedef struct { int utt_id; char* data; unsigned int data_size; + unsigned int played_data_size; ttse_result_event_e event; ttse_audio_type_e audio_type; @@ -104,7 +105,9 @@ void ttsd_data_destroy_sound_data(sound_data_s* sound_data); int ttsd_data_add_sound_data(unsigned int uid, sound_data_s* data); -int ttsd_data_get_sound_data(unsigned int uid, sound_data_s** data); +sound_data_s* ttsd_data_get_first_sound_data(unsigned int uid); + +int ttsd_data_pop_sound_data(unsigned int uid); int ttsd_data_get_sound_data_size(unsigned int uid); @@ -119,6 +122,10 @@ int ttsd_data_get_client_state(unsigned int uid, app_tts_state_e* state); int ttsd_data_set_client_state(unsigned int uid, app_tts_state_e state); +int ttsd_data_set_paused_data_existing(unsigned int uid, bool is_paused_data_existing); + +bool ttsd_data_is_paused_data_existing(unsigned int uid); + unsigned int ttsd_data_get_current_playing(); diff --git a/server/ttsd_player.cpp b/server/ttsd_player.cpp index e268fbe..09292c5 100644 --- a/server/ttsd_player.cpp +++ b/server/ttsd_player.cpp @@ -36,10 +36,6 @@ typedef struct { /* Current utterance information */ ttse_result_event_e event; /** event of last utterance */ - - bool is_paused_data; - int idx; - sound_data_s* paused_data; } player_s; #define SOUND_BUFFER_LENGTH 2048 @@ -344,26 +340,10 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) return; } - if (true == player->is_paused_data && NULL != player->paused_data) { + if (ttsd_data_is_paused_data_existing(player->uid)) { /* Resume player */ - sound_data_s* paused_data = player->paused_data; - player->paused_data = NULL; - - ttsd_data_destroy_sound_data(sound_data); - sound_data = ttsd_data_create_sound_data(paused_data->utt_id, paused_data->data, paused_data->data_size, - paused_data->event, paused_data->audio_type, paused_data->rate, paused_data->channels); - if (NULL == sound_data || paused_data->data_size <= 0) { - SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Out of memory OR paused_data is empty"); - ttsd_data_destroy_sound_data(sound_data); - sound_data = paused_data; - } else { // NULL != sound_data && NULL != temp && player->paused_data->data_size > 0 - ttsd_data_destroy_sound_data(paused_data); - } - - idx = player->idx; - - player->is_paused_data = false; - player->idx = 0; + sound_data = ttsd_data_get_first_sound_data(player->uid); + ttsd_data_set_paused_data_existing(player->uid, false); if (NULL == sound_data) { /* Request unprepare */ @@ -378,9 +358,8 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) 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 { // NO player->is_paused_data - sound_data = NULL; - ret = ttsd_data_get_sound_data(player->uid, &sound_data); - if (0 != ret || NULL == sound_data) { + sound_data = ttsd_data_get_first_sound_data(player->uid); + if (nullptr == sound_data) { /* empty queue */ SLOG(LOG_ERROR, tts_tag(), "[Player] No sound data. Waiting mode"); @@ -441,8 +420,6 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid); /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); - ttsd_data_destroy_sound_data(sound_data); - sound_data = NULL; return; } @@ -463,7 +440,15 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) idx = 0; if (NULL == sound_data->data || 0 >= sound_data->data_size) { - if (TTSE_RESULT_EVENT_FINISH == sound_data->event) { + ttse_result_event_e event = sound_data->event; + int utt_id = sound_data->utt_id; + + if (TTSD_ERROR_NONE == ttsd_data_pop_sound_data(player->uid)) { + ttsd_data_destroy_sound_data(sound_data); + } + sound_data = nullptr; + + if (TTSE_RESULT_EVENT_FINISH == event) { SLOG(LOG_DEBUG, tts_tag(), "No sound data"); /* send utterence finish signal */ int pid = ttsd_data_get_pid(player->uid); @@ -472,8 +457,6 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid); /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); - ttsd_data_destroy_sound_data(sound_data); - sound_data = NULL; return; } @@ -484,16 +467,16 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) #endif __set_playing_status(false); - if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) { + + + if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, utt_id)) { SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%u), uttid(%d)", - pid, player->uid, sound_data->utt_id); + pid, player->uid, utt_id); } else { - SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, sound_data->utt_id); + SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, utt_id); } - } // TTSE_RESULT_EVENT_FINISH == sound_data->event - SLOG(LOG_INFO, tts_tag(), "[Player] Event(%d) utterance : uid(%u), uttid(%d)", sound_data->event, player->uid, sound_data->utt_id); - ttsd_data_destroy_sound_data(sound_data); - sound_data = NULL; + } // TTSE_RESULT_EVENT_FINISH == event + SLOG(LOG_INFO, tts_tag(), "[Player] Event(%d) utterance : uid(%u), uttid(%d)", event, player->uid, utt_id); continue; } // (NULL == sound_data->data || 0 >= sound_data->data_size) } // NO player->is_paused_data @@ -503,9 +486,6 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio out"); /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); - - ttsd_data_destroy_sound_data(sound_data); - sound_data = NULL; return; } @@ -533,8 +513,6 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); - ttsd_data_destroy_sound_data(sound_data); - sound_data = NULL; return; } @@ -552,6 +530,7 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to audio write - %d", ret); } else { idx += len; + sound_data->played_data_size = idx; SLOG(LOG_INFO, tts_tag(), "[Player INFO] After audio_out_write"); } @@ -560,24 +539,15 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) g_audio_stream->unprepareAudioOut(); /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); - - ttsd_data_destroy_sound_data(sound_data); - sound_data = NULL; return; } // (NULL == g_playing_info && APP_STATE_PAUSED != player->state) if (APP_STATE_PAUSED == player->state) { /* Save data */ SLOG(LOG_DEBUG, tts_tag(), "[Player] player(%p)", player); - ttsd_data_destroy_sound_data(player->paused_data); - player->paused_data = sound_data; - - player->is_paused_data = true; - player->idx = idx; - + ttsd_data_set_paused_data_existing(player->uid, true); SLOG(LOG_INFO, tts_tag(), "[Player] Stop player thread by pause"); - /* Request prepare */ g_audio_stream->unprepareAudioOut(); /* unset volume policy, volume will be 100% */ @@ -586,21 +556,16 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) } // (APP_STATE_PAUSED == player->state) } // while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) - if (NULL == g_playing_info && APP_STATE_READY == player->state) { - /* player_stop */ - SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread"); + ttse_result_event_e event = sound_data->event; + int utt_id = sound_data->utt_id; - /* Request prepare */ - g_audio_stream->unprepareAudioOut(); - /* unset volume policy, volume will be 100% */ - __unset_policy_for_playing(); + if (TTSD_ERROR_NONE == ttsd_data_pop_sound_data(player->uid)) { ttsd_data_destroy_sound_data(sound_data); - sound_data = NULL; - return; - } // (NULL == g_playing_info && APP_STATE_READY == player->state) + } + sound_data = nullptr; if ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) && - (TTSE_RESULT_EVENT_FINISH == sound_data->event)) { + (TTSE_RESULT_EVENT_FINISH == event)) { /* send utterence finish signal */ int pid = ttsd_data_get_pid(player->uid); @@ -608,8 +573,6 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid. uid(%u)", player->uid); /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); - ttsd_data_destroy_sound_data(sound_data); - sound_data = NULL; return; } @@ -617,29 +580,34 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) __close_buffer_dump_file(); #endif __set_playing_status(false); - if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) { + + if (0 != ttsdc_ipc_send_utt_finish_message(pid, player->uid, utt_id)) { SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%u), uttid(%d)", - pid, player->uid, sound_data->utt_id); + pid, player->uid, utt_id); /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); - ttsd_data_destroy_sound_data(sound_data); - sound_data = NULL; return; } - SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, sound_data->utt_id); - } // ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) && (TTSE_RESULT_EVENT_FINISH == sound_data->event)) + SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%u), uttid(%d)", player->uid, utt_id); + } // ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) && (TTSE_RESULT_EVENT_FINISH == event)) - ttsd_data_destroy_sound_data(sound_data); - sound_data = NULL; + if (NULL == g_playing_info && APP_STATE_READY == player->state) { + /* player_stop */ + SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread"); + + /* Request prepare */ + g_audio_stream->unprepareAudioOut(); + /* unset volume policy, volume will be 100% */ + __unset_policy_for_playing(); + return; + } // (NULL == g_playing_info && APP_STATE_READY == player->state) if (NULL == g_playing_info) { SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL"); g_audio_stream->unprepareAudioOut(); /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); - ttsd_data_destroy_sound_data(sound_data); - sound_data = NULL; return; } } // end of 1st while(1) @@ -764,9 +732,7 @@ int ttsd_player_create_instance(unsigned int uid) new_client->uid = uid; new_client->event = TTSE_RESULT_EVENT_FINISH; new_client->state = APP_STATE_READY; - new_client->is_paused_data = false; - new_client->idx = 0; - new_client->paused_data = NULL; + ttsd_data_set_paused_data_existing(uid, false); SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Player] Create player : uid(%u)", uid); @@ -932,16 +898,9 @@ int ttsd_player_clear(unsigned int uid) return -1; } - if (true == current->is_paused_data) { - SLOG(LOG_INFO, tts_tag(), "[Player INFO] Clear paused data"); - ttsd_data_destroy_sound_data(current->paused_data); - current->paused_data = NULL; - } - current->event = TTSE_RESULT_EVENT_FINISH; current->state = APP_STATE_READY; - current->is_paused_data = false; - current->idx = 0; + ttsd_data_set_paused_data_existing(uid, false); SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Clear player : uid(%u)", uid); @@ -1070,15 +1029,7 @@ int ttsd_player_all_stop() if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) { data->event = TTSE_RESULT_EVENT_FINISH; data->state = APP_STATE_READY; - - if (true == data->is_paused_data) { - SLOG(LOG_INFO, tts_tag(), "[Player INFO] Clear paused data"); - ttsd_data_destroy_sound_data(data->paused_data); - data->paused_data = NULL; - } - - data->is_paused_data = false; - data->idx = 0; + ttsd_data_set_paused_data_existing(data->uid, false); } /* Get next item */ -- 2.7.4