From c823951a7cdcc72df45cfbdd149bb6eb7830d01f Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Fri, 20 Nov 2020 10:31:09 +0900 Subject: [PATCH] Refactor the APIs about playing text This patch refactors the next APIs about playing text. - tts_add_text - tts_play - tts_stop - tts_pause - tts_add_pcm - tts_play_pcm - tts_stop_pcm By this patch, tts.c provides simple business logic and tts_core provides core logic. Change-Id: Ieb81972acc5e305733f0bbceb357b1866f7c05c2 Signed-off-by: Suyeon Hwang --- client/tts.c | 457 ++++++---------------------------------------------- client/tts_client.c | 40 +++++ client/tts_client.h | 5 + client/tts_core.c | 402 ++++++++++++++++++++++++++++++++++++++++++++- client/tts_core.h | 10 ++ 5 files changed, 501 insertions(+), 413 deletions(-) diff --git a/client/tts.c b/client/tts.c index 4824e29..81dfaaf 100644 --- a/client/tts.c +++ b/client/tts.c @@ -36,13 +36,6 @@ static int g_feature_enabled = -1; static int g_max_text_size = -1; -/* for repetition */ -static char* g_language = NULL; - -static int g_voice_type = -1; - -static int g_speed = -1; - static int __tts_get_feature_enabled() { @@ -137,10 +130,7 @@ void __tts_config_voice_changed_cb(const char* before_lang, int before_voice_typ /* Check whether language is changed or not. If it is changed, make 'text_repeat' NULL */ if (0 != strncmp(before_lang, language, strlen(before_lang))) { - if (NULL != data->text_repeat) { - free(data->text_repeat); - data->text_repeat = NULL; - } + tts_client_set_repeat_text(data, NULL); } /* Next item */ @@ -390,11 +380,6 @@ int tts_destroy(tts_h tts) } } - if (NULL != g_language) { - free(g_language); - g_language = NULL; - } - SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); return TTS_ERROR_NONE; @@ -919,83 +904,13 @@ int tts_add_text(tts_h tts, const char* text, const char* language, int voice_ty return TTS_ERROR_PERMISSION_DENIED; } - SLOG(LOG_DEBUG, TAG_TTSC, "Text is valid - text(%zu byte) is '%s'", strlen(text), text); - - /* save texts for repetition */ - if (NULL != client->text_repeat) { - free(client->text_repeat); - client->text_repeat = NULL; - } - - client->text_repeat = strdup(text); - - if (NULL != g_language) { - free(g_language); - g_language = NULL; - } - if (NULL == language) - g_language = NULL; - else - g_language = strdup(language); - - g_voice_type = voice_type; - g_speed = speed; - - SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] repeat: text(%s), language(%s), voice type(%d), speed(%d)", client->text_repeat, (g_language) ? g_language : "NULL", g_voice_type, g_speed); - - /* change default language value */ - char* temp = NULL; - - if (NULL == language) - temp = strdup("default"); - else - temp = strdup(language); - - client->current_utt_id++; - if (client->current_utt_id == 10000) { - client->current_utt_id = 1; - } - - /* do request */ - int uid = tts_client_get_uid(client); - int ret = -1; - int count = 0; - bool is_prepared = false; - while (0 != ret) { - ret = tts_ipc_request_add_text(uid, text, temp, voice_type, speed, client->current_utt_id, client->credential); - if (0 != ret) { - //LCOV_EXCL_START - if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { - tts_client_set_current_state(client, TTS_STATE_CREATED); - if (0 == tts_core_prepare_sync(client)) { - is_prepared = true; - SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); - } - } else if (TTS_ERROR_TIMED_OUT != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); - break; - } else { - SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry add text : %s", __tts_get_error_code(ret)); - usleep(10000); - count++; - if (TTS_RETRY_COUNT == count) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); - break; - } - } - //LCOV_EXCL_STOP - } else { - *utt_id = client->current_utt_id; - } - } - - if (NULL != temp) { - free(temp); - temp = NULL; + int ret = tts_core_add_text(client, text, language, voice_type, speed, utt_id); + if (TTS_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request add text. ret(%s)", __tts_get_error_code(ret)); + return ret; } SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); - return ret; } @@ -1010,43 +925,13 @@ static void __tts_play_async(void *data) return; } - int uid = tts_client_get_uid(client); - int ret = -1; - int count = 0; - bool is_prepared = false; - while (0 != ret) { - ret = tts_ipc_request_play(uid, client->credential); - if (0 != ret) { - if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { - tts_client_set_current_state(client, TTS_STATE_CREATED); - if (0 == tts_core_prepare_sync(client)) { - is_prepared = true; - SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); - } - } else if (TTS_ERROR_TIMED_OUT != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); - break; - } else { - SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry play : %s", __tts_get_error_code(ret)); - usleep(10000); - count++; - if (TTS_RETRY_COUNT == count) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); - break; - } - } - } - } - + int ret = tts_core_play(client); if (0 != ret) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to play tts : %s", __tts_get_error_code(ret)); - tts_core_notify_error_async(client, ret, -1, NULL); return; } - tts_core_set_current_state(client, TTS_STATE_PLAYING); - SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); return; } @@ -1084,10 +969,10 @@ int tts_play_async(tts_h tts) ecore_main_loop_thread_safe_call_async(__tts_play_async, (void*)tts); SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); - return TTS_ERROR_NONE; } //LCOV_EXCL_STOP + int tts_play(tts_h tts) { if (0 != __tts_get_feature_enabled()) { @@ -1096,8 +981,7 @@ int tts_play(tts_h tts) SLOG(LOG_INFO, TAG_TTSC, "@@@ Play tts"); - int ret = -1; - + // Check handle tts_client_s* client = tts_client_get(tts); if (NULL == client) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid. tts(%p)", tts); @@ -1120,38 +1004,12 @@ int tts_play(tts_h tts) return TTS_ERROR_PERMISSION_DENIED; } - int uid = tts_client_get_uid(client); - ret = -1; - int count = 0; - bool is_prepared = false; - while (0 != ret) { - ret = tts_ipc_request_play(uid, client->credential); - if (0 != ret) { - //LCOV_EXCL_START - if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { - tts_client_set_current_state(client, TTS_STATE_CREATED); - if (0 == tts_core_prepare_sync(client)) { - is_prepared = true; - SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); - } - } else if (TTS_ERROR_TIMED_OUT != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); - return ret; - } else { - SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry play : %s", __tts_get_error_code(ret)); - usleep(10000); - count++; - if (TTS_RETRY_COUNT == count) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); - return ret; - } - } - //LCOV_EXCL_STOP - } + int ret = tts_core_play(client); + if (TTS_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request play. ret(%s)", __tts_get_error_code(ret)); + return ret; } - tts_core_set_current_state(client, TTS_STATE_PLAYING); - SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); return TTS_ERROR_NONE; } @@ -1167,43 +1025,13 @@ static void __tts_stop_async(void *data) return; } - int uid = tts_client_get_uid(client); - int ret = -1; - int count = 0; - bool is_prepared = false; - while (0 != ret) { - ret = tts_ipc_request_stop(uid); - if (0 != ret) { - if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { - tts_client_set_current_state(client, TTS_STATE_CREATED); - if (0 == tts_core_prepare_sync(client)) { - is_prepared = true; - SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); - } - } else if (TTS_ERROR_TIMED_OUT != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); - break; - } else { - SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry stop : %s", __tts_get_error_code(ret)); - usleep(10000); - count++; - if (TTS_RETRY_COUNT == count) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); - break; - } - } - } - } - + int ret = tts_core_stop(client); if (0 != ret) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to stop tts : %s", __tts_get_error_code(ret)); - tts_core_notify_error_async(client, ret, -1, NULL); return; } - tts_core_set_current_state(client, TTS_STATE_READY); - SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); return; } @@ -1236,10 +1064,10 @@ int tts_stop_aync(tts_h tts) ecore_main_loop_thread_safe_call_async(__tts_stop_async, (void*)tts); SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); - return TTS_ERROR_NONE; } //LCOV_EXCL_STOP + int tts_stop(tts_h tts) { if (0 != __tts_get_feature_enabled()) { @@ -1265,42 +1093,17 @@ int tts_stop(tts_h tts) return TTS_ERROR_INVALID_STATE; } - int uid = tts_client_get_uid(client); - int ret = -1; - int count = 0; - bool is_prepared = false; - while (0 != ret) { - ret = tts_ipc_request_stop(uid); - if (0 != ret) { - //LCOV_EXCL_START - if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { - tts_client_set_current_state(client, TTS_STATE_CREATED); - if (0 == tts_core_prepare_sync(client)) { - is_prepared = true; - SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); - } - } else if (TTS_ERROR_TIMED_OUT != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); - return ret; - } else { - SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry stop : %s", __tts_get_error_code(ret)); - usleep(10000); - count++; - if (TTS_RETRY_COUNT == count) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); - return ret; - } - } - //LCOV_EXCL_STOP - } + int ret = tts_core_stop(client); + if (TTS_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request stop. ret(%s)", __tts_get_error_code(ret)); + return ret; } - tts_core_set_current_state(client, TTS_STATE_READY); - SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); return TTS_ERROR_NONE; } //LCOV_EXCL_START + static void __tts_pause_async(void *data) { tts_h tts = (tts_h)data; @@ -1311,43 +1114,13 @@ static void __tts_pause_async(void *data) return; } - int uid = tts_client_get_uid(client); - int ret = -1; - int count = 0; - bool is_prepared = false; - while (0 != ret) { - ret = tts_ipc_request_pause(uid); - if (0 != ret) { - if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { - tts_client_set_current_state(client, TTS_STATE_CREATED); - if (0 == tts_core_prepare_sync(client)) { - is_prepared = true; - SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); - } - } else if (TTS_ERROR_TIMED_OUT != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); - break; - } else { - SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry pause : %s", __tts_get_error_code(ret)); - usleep(10000); - count++; - if (TTS_RETRY_COUNT == count) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); - break; - } - } - } - } - + int ret = tts_core_pause(client); if (0 != ret) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to pause tts : %s", __tts_get_error_code(ret)); - tts_core_notify_error_async(client, ret, -1, NULL); return; } - tts_core_set_current_state(client, TTS_STATE_PAUSED); - SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); return; } @@ -1408,38 +1181,12 @@ int tts_pause(tts_h tts) return TTS_ERROR_INVALID_STATE; } - int uid = tts_client_get_uid(client); - int ret = -1; - int count = 0; - bool is_prepared = false; - while (0 != ret) { - ret = tts_ipc_request_pause(uid); - if (0 != ret) { - //LCOV_EXCL_START - if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { - tts_client_set_current_state(client, TTS_STATE_CREATED); - if (0 == tts_core_prepare_sync(client)) { - is_prepared = true; - SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); - } - } else if (TTS_ERROR_TIMED_OUT != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); - return ret; - } else { - SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry pause : %s", __tts_get_error_code(ret)); - usleep(10000); - count++; - if (TTS_RETRY_COUNT == count) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); - return ret; - } - } - //LCOV_EXCL_STOP - } + int ret = tts_core_pause(client); + if (TTS_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request pause. ret(%s)", __tts_get_error_code(ret)); + return ret; } - tts_core_set_current_state(client, TTS_STATE_PAUSED); - SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); return TTS_ERROR_NONE; } @@ -1930,36 +1677,13 @@ int tts_add_pcm(tts_h tts, int event, const void* data, unsigned int data_size, return TTS_ERROR_INVALID_STATE; } - int uid = tts_client_get_uid(client); - int ret = -1; - int count = 0; - bool is_prepared = false; - while (0 != ret) { - ret = tts_ipc_request_add_pcm(uid, event, data, data_size, audio_type, rate); - if (0 != ret) { - if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { - tts_client_set_current_state(client, TTS_STATE_CREATED); - if (0 == tts_core_prepare_sync(client)) { - is_prepared = true; - SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); - } - } else if (TTS_ERROR_TIMED_OUT != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); - return ret; - } else { - SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry add pcm : %s", __tts_get_error_code(ret)); - usleep(10000); - count++; - if (TTS_RETRY_COUNT == count) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); - return ret; - } - } - } + int ret = tts_core_add_pcm(client, event, data, data_size, audio_type, rate); + if (TTS_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request add_pcm. ret(%s)", __tts_get_error_code(ret)); + return ret; } SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); - return TTS_ERROR_NONE; } @@ -1988,36 +1712,12 @@ int tts_play_pcm(tts_h tts) return TTS_ERROR_INVALID_STATE; } - int uid = tts_client_get_uid(client); - int ret = -1; - int count = 0; - bool is_prepared = false; - while (0 != ret) { - ret = tts_ipc_request_play_pcm(uid); - if (0 != ret) { - if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { - tts_client_set_current_state(client, TTS_STATE_CREATED); - if (0 == tts_core_prepare_sync(client)) { - is_prepared = true; - SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); - } - } else if (TTS_ERROR_TIMED_OUT != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); - return ret; - } else { - SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry play pcm : %s", __tts_get_error_code(ret)); - usleep(10000); - count++; - if (TTS_RETRY_COUNT == count) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); - return ret; - } - } - } + int ret = tts_core_play_pcm(client); + if (TTS_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request play_pcm. ret(%s)", __tts_get_error_code(ret)); + return ret; } - tts_core_set_current_state(client, TTS_STATE_PLAYING); - SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); return TTS_ERROR_NONE; } @@ -2047,36 +1747,12 @@ int tts_stop_pcm(tts_h tts) return TTS_ERROR_INVALID_STATE; } - int uid = tts_client_get_uid(client); - int ret = -1; - int count = 0; - bool is_prepared = false; - while (0 != ret) { - ret = tts_ipc_request_stop_pcm(uid); - if (0 != ret) { - if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { - tts_client_set_current_state(client, TTS_STATE_CREATED); - if (0 == tts_core_prepare_sync(client)) { - is_prepared = true; - SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); - } - } else if (TTS_ERROR_TIMED_OUT != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); - return ret; - } else { - SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry stop pcm : %s", __tts_get_error_code(ret)); - usleep(10000); - count++; - if (TTS_RETRY_COUNT == count) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); - return ret; - } - } - } + int ret = tts_core_stop_pcm(client); + if (TTS_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request stop_pcm. ret(%s)", __tts_get_error_code(ret)); + return ret; } - tts_core_set_current_state(client, TTS_STATE_READY); - SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); return TTS_ERROR_NONE; } @@ -2107,62 +1783,25 @@ int tts_repeat(tts_h tts, char** text_repeat, int* utt_id) return TTS_ERROR_INVALID_STATE; } - *text_repeat = NULL; - *utt_id = -1; - - /* Clear the legacy and Add texts to be played repeatedly */ - int ret = -1; - ret = tts_stop(tts); - if (TTS_ERROR_NONE != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to clear the legacy"); - return ret; + if (false == tts_core_check_screen_reader(client)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Screen reader option is not available"); + return TTS_ERROR_INVALID_STATE; } - if (NULL != client->text_repeat) { - char* tmp_text = strdup(client->text_repeat); - char* tmp_lang = NULL; - if (NULL != g_language) { - tmp_lang = strdup(g_language); - } - ret = tts_add_text(tts, tmp_text, tmp_lang, g_voice_type, g_speed, utt_id); - if (TTS_ERROR_NONE != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to add texts for repetition."); - if (NULL != tmp_text) { - free(tmp_text); - tmp_text = NULL; - } - if (NULL != tmp_lang) { - free(tmp_lang); - tmp_lang = NULL; - } - return ret; - } - *text_repeat = strdup(client->text_repeat); - SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] text to repeat(%s), utt_id(%d)", (*text_repeat) ? *text_repeat : "NULL", *utt_id); - if (NULL != tmp_text) { - free(tmp_text); - tmp_text = NULL; - } - if (NULL != tmp_lang) { - free(tmp_lang); - tmp_lang = NULL; - } - } else { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] There is no previous added texts. Please add texts"); - return TTS_ERROR_OPERATION_FAILED; + if (true == client->credential_needed && NULL == client->credential) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Do not have app credential for this engine"); + return TTS_ERROR_PERMISSION_DENIED; } - /* Play added texts */ - ret = tts_play(tts); + *text_repeat = NULL; + *utt_id = -1; + + int ret = tts_core_repeat(client, text_repeat, utt_id); if (TTS_ERROR_NONE != ret) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to play texts for repetition."); - if (NULL != *text_repeat) { - free(*text_repeat); - *text_repeat = NULL; - } - *utt_id = -1; + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request stop. ret(%s)", __tts_get_error_code(ret)); return ret; } + SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); return TTS_ERROR_NONE; } diff --git a/client/tts_client.c b/client/tts_client.c index 241c756..652f8d5 100644 --- a/client/tts_client.c +++ b/client/tts_client.c @@ -445,6 +445,46 @@ tts_mode_e tts_client_get_mode(tts_client_s* client) return client->mode; } +void tts_client_set_repeat_text(tts_client_s* client, const char* text) +{ + if (NULL == client || false == tts_client_is_valid_client(client)) { + return; + } + + if (NULL != client->text_repeat) { + free(client->text_repeat); + } + + if (NULL != text) { + client->text_repeat = strdup(text); + } else { + client->text_repeat = NULL; + } +} + +const char* tts_client_get_repeat_text(tts_client_s* client) +{ + if (NULL == client || false == tts_client_is_valid_client(client)) { + return NULL; + } + + return client->text_repeat; +} + +int tts_client_new_utterance_id(tts_client_s* client) +{ + if (NULL == client || false == tts_client_is_valid_client(client)) { + return INVALID_HANDLE; + } + + client->current_utt_id++; + if (client->current_utt_id == 10000) { + client->current_utt_id = 1; + } + + return client->current_utt_id; +} + void tts_client_set_error_message(tts_client_s* client, const char* error_message) { if (false == tts_client_is_valid_client(client)) { diff --git a/client/tts_client.h b/client/tts_client.h index e0c54ba..729fe5c 100644 --- a/client/tts_client.h +++ b/client/tts_client.h @@ -117,6 +117,11 @@ bool tts_client_is_listening_started(int uid); void tts_client_set_mode(tts_client_s* client, tts_mode_e mode); tts_mode_e tts_client_get_mode(tts_client_s* client); +void tts_client_set_repeat_text(tts_client_s* client, const char* text); +const char* tts_client_get_repeat_text(tts_client_s* client); + +int tts_client_new_utterance_id(tts_client_s* client); + void tts_client_set_error_message(tts_client_s* client, const char* error_message); const char* tts_client_get_error_message(tts_client_s* client); diff --git a/client/tts_core.c b/client/tts_core.c index 3713e1c..e187022 100644 --- a/client/tts_core.c +++ b/client/tts_core.c @@ -37,6 +37,10 @@ static pkgmgr_client* g_pkgmgr = NULL; static Ecore_Thread* g_pkgmgr_thread = NULL; static pthread_mutex_t g_pkgmgr_mutex = PTHREAD_MUTEX_INITIALIZER; +static char* g_language = NULL; +static int g_voice_type = -1; +static int g_speed = -1; + /* Static functions */ static const char* __tts_get_error_code(tts_error_e err) @@ -609,9 +613,8 @@ static int __update_screen_reader_state() { SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Update screen reader state"); - int ret = -1; int screen_reader = 0; - ret = vconf_get_bool(TTS_ACCESSIBILITY_KEY, &screen_reader); + int ret = vconf_get_bool(TTS_ACCESSIBILITY_KEY, &screen_reader); if (0 != ret) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get screen reader vconf(%d)", ret); return TTS_ERROR_OPERATION_FAILED; @@ -630,6 +633,92 @@ static void __screen_reader_state_changed_cb(bool value) } //LCOV_EXCL_STOP +static inline int __request_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id) +{ + /* change default language value */ + const char* convert_language = (NULL == language ? "default" : language); + int new_utt_id = tts_client_new_utterance_id(client); + if (0 > new_utt_id) { + return TTS_ERROR_OPERATION_FAILED; + } + + int uid = tts_client_get_uid(client); + int ret = -1; + int count = 0; + bool is_prepared = false; + while (TTS_RETRY_COUNT > count) { + ret = tts_ipc_request_add_text(uid, text, convert_language, voice_type, speed, new_utt_id, client->credential); + if (0 == ret) { + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_ipc_request_add_text"); + *utt_id = new_utt_id; + break; + } + + //LCOV_EXCL_START + if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { + tts_client_set_current_state(client, TTS_STATE_CREATED); + if (0 == tts_core_prepare_sync(client)) { + is_prepared = true; + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); + } + } else if (TTS_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry add text : %s", __tts_get_error_code(ret)); + usleep(10000); + } + //LCOV_EXCL_STOP + + count++; + } + + if (TTS_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); + return TTS_ERROR_TIMED_OUT; + } + + return TTS_ERROR_NONE; +} + +static inline int __request_play(tts_client_s* client) +{ + int uid = tts_client_get_uid(client); + int ret = -1; + int count = 0; + bool is_prepared = false; + while (TTS_RETRY_COUNT > count) { + ret = tts_ipc_request_play(uid, client->credential); + if (0 == ret) { + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_ipc_request_play"); + break; + } + + if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { + tts_client_set_current_state(client, TTS_STATE_CREATED); + if (0 == tts_core_prepare_sync(client)) { + is_prepared = true; + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); + } + } else if (TTS_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry play : %s", __tts_get_error_code(ret)); + usleep(10000); + } + + count++; + } + + if (TTS_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); + return TTS_ERROR_TIMED_OUT; + } + + return tts_core_set_current_state(client, TTS_STATE_PLAYING); +} + /* Public functions */ int tts_core_initialize() { @@ -657,6 +746,16 @@ int tts_core_deinitialize() g_is_thread_canceled = true; } + if (NULL != g_language) { + free(g_language); + g_language = NULL; + } + + if (NULL != g_engine_name) { + free(g_engine_name); + g_engine_name = NULL; + } + pthread_mutex_lock(&g_pkgmgr_mutex); if (NULL != g_pkgmgr) { pkgmgr_client_remove_listen_status(g_pkgmgr); @@ -826,12 +925,17 @@ int tts_core_notify_engine_changed(tts_client_s* client, const char* engine_id, int tts_core_set_current_state(tts_client_s* client, tts_state_e state) { - tts_state_e before_state = tts_client_get_current_state(client); - if (TTS_STATE_INVALID == before_state) { + if (false == tts_client_is_valid_client(client)) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is invalid."); return TTS_ERROR_INVALID_PARAMETER; } + tts_state_e before_state = tts_client_get_current_state(client); + if (before_state == state) { + SLOG(LOG_INFO, TAG_TTSC, "[INFO] State is not changed. before(%s), current(%s)", __convert_state(before_state), __convert_state(state)); + return TTS_ERROR_NONE; + } + SLOG(LOG_DEBUG, TAG_TTSC, "State changed to (%s).", __convert_state(state)); tts_client_set_current_state(client, state); __client_state_changed_cb(client, before_state, state); @@ -1156,3 +1260,293 @@ int tts_core_handle_service_reset() return TTS_ERROR_NONE; } + +int tts_core_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id) +{ + if (NULL == text || NULL == utt_id) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Parameter is invalid."); + return TTS_ERROR_INVALID_PARAMETER; + } + + if (false == tts_client_is_valid_client(client)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid."); + return TTS_ERROR_INVALID_PARAMETER; + } + + tts_client_set_repeat_text(client, text); + + if (NULL != g_language) { + free(g_language); + } + + g_language = (NULL == language ? NULL : strdup(language)); + g_voice_type = voice_type; + g_speed = speed; + + SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] text(%s), language(%s), voice type(%d), speed(%d)", text, (g_language) ? g_language : "NULL", g_voice_type, g_speed); + return __request_add_text(client, text, language, voice_type, speed, utt_id); +} + +int tts_core_play(tts_client_s* client) +{ + if (false == tts_client_is_valid_client(client)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid."); + return TTS_ERROR_INVALID_PARAMETER; + } + + return __request_play(client); +} + +int tts_core_stop(tts_client_s* client) +{ + if (false == tts_client_is_valid_client(client)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid."); + return TTS_ERROR_INVALID_PARAMETER; + } + + int uid = tts_client_get_uid(client); + int ret = 0; + int count = 0; + bool is_prepared = false; + while (TTS_RETRY_COUNT > count) { + ret = tts_ipc_request_stop(uid); + if (0 == ret) { + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_ipc_request_play"); + break; + } + + if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { + tts_client_set_current_state(client, TTS_STATE_CREATED); + if (0 == tts_core_prepare_sync(client)) { + is_prepared = true; + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); + } + } else if (TTS_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry play : %s", __tts_get_error_code(ret)); + usleep(10000); + } + + count++; + } + + if (TTS_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); + return TTS_ERROR_TIMED_OUT; + } + + return tts_core_set_current_state(client, TTS_STATE_READY); +} + +int tts_core_pause(tts_client_s* client) +{ + if (false == tts_client_is_valid_client(client)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid."); + return TTS_ERROR_INVALID_PARAMETER; + } + + int uid = tts_client_get_uid(client); + int ret = 0; + int count = 0; + bool is_prepared = false; + while (TTS_RETRY_COUNT > count) { + ret = tts_ipc_request_pause(uid); + if (0 == ret) { + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_ipc_request_pause"); + break; + } + + if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { + tts_client_set_current_state(client, TTS_STATE_CREATED); + if (0 == tts_core_prepare_sync(client)) { + is_prepared = true; + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); + } + } else if (TTS_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry pause : %s", __tts_get_error_code(ret)); + usleep(10000); + } + + count++; + } + + if (TTS_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); + return TTS_ERROR_TIMED_OUT; + } + + return tts_core_set_current_state(client, TTS_STATE_PAUSED); +} + +int tts_core_repeat(tts_client_s* client, char** text_repeat, int* utt_id) +{ + if (NULL == text_repeat || NULL == utt_id) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Parameter is invalid."); + return TTS_ERROR_INVALID_PARAMETER; + } + + if (false == tts_client_is_valid_client(client)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid."); + return TTS_ERROR_INVALID_PARAMETER; + } + + const char* repeat_text = tts_client_get_repeat_text(client); + if (NULL == repeat_text) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] There is no previous added texts. Please add texts"); + return TTS_ERROR_OPERATION_FAILED; + } + + int new_utt_id = -1; + int ret = __request_add_text(client, repeat_text, g_language, g_voice_type, g_speed, &new_utt_id); + if (TTS_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to add texts for repetition."); + return ret; + } + + /* Play added texts */ + ret = __request_play(client); + if (TTS_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to play texts for repetition."); + return ret; + } + + SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] text to repeat(%s), utt_id(%d)", repeat_text, new_utt_id); + + *utt_id = new_utt_id; + *text_repeat = strdup(repeat_text); + return TTS_ERROR_NONE; +} + +int tts_core_add_pcm(tts_client_s* client, int event, const void* data, unsigned int data_size, int audio_type, int rate) +{ + if (false == tts_client_is_valid_client(client)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid."); + return TTS_ERROR_INVALID_PARAMETER; + } + + int uid = tts_client_get_uid(client); + int ret = 0; + int count = 0; + bool is_prepared = false; + while (TTS_RETRY_COUNT > count) { + ret = tts_ipc_request_add_pcm(uid, event, data, data_size, audio_type, rate); + if (0 == ret) { + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_ipc_request_add_pcm"); + break; + } + + if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { + tts_client_set_current_state(client, TTS_STATE_CREATED); + if (0 == tts_core_prepare_sync(client)) { + is_prepared = true; + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); + } + } else if (TTS_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry add pcm : %s", __tts_get_error_code(ret)); + usleep(10000); + } + + count++; + } + + if (TTS_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); + return TTS_ERROR_TIMED_OUT; + } + + return TTS_ERROR_NONE; +} + +int tts_core_play_pcm(tts_client_s* client) +{ + if (false == tts_client_is_valid_client(client)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid."); + return TTS_ERROR_INVALID_PARAMETER; + } + + int uid = tts_client_get_uid(client); + int ret = 0; + int count = 0; + bool is_prepared = false; + while (TTS_RETRY_COUNT > count) { + ret = tts_ipc_request_play_pcm(uid); + if (0 == ret) { + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_ipc_request_play_pcm"); + break; + } + + if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { + tts_client_set_current_state(client, TTS_STATE_CREATED); + if (0 == tts_core_prepare_sync(client)) { + is_prepared = true; + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); + } + } else if (TTS_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry play pcm : %s", __tts_get_error_code(ret)); + usleep(10000); + } + + count++; + } + + if (TTS_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); + return TTS_ERROR_TIMED_OUT; + } + + return tts_core_set_current_state(client, TTS_STATE_PLAYING); +} + +int tts_core_stop_pcm(tts_client_s* client) +{ + if (false == tts_client_is_valid_client(client)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client is not valid."); + return TTS_ERROR_INVALID_PARAMETER; + } + + int uid = tts_client_get_uid(client); + int ret = 0; + int count = 0; + bool is_prepared = false; + while (TTS_RETRY_COUNT > count) { + ret = tts_ipc_request_stop_pcm(uid); + if (0 == ret) { + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_ipc_request_stop_pcm"); + break; + } + + if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { + tts_client_set_current_state(client, TTS_STATE_CREATED); + if (0 == tts_core_prepare_sync(client)) { + is_prepared = true; + SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync"); + } + } else if (TTS_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry stop pcm : %s", __tts_get_error_code(ret)); + usleep(10000); + } + + count++; + } + + if (TTS_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); + return TTS_ERROR_TIMED_OUT; + } + + return tts_core_set_current_state(client, TTS_STATE_READY); +} diff --git a/client/tts_core.h b/client/tts_core.h index 3374a5b..af3fdc5 100644 --- a/client/tts_core.h +++ b/client/tts_core.h @@ -49,6 +49,16 @@ int tts_core_reprepare(); int tts_core_foreach_supported_voices(tts_client_s* client, const char* engine_id, tts_supported_voice_cb callback, void* user_data); // called by tts_ipc +int tts_core_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id); +int tts_core_play(tts_client_s* client); +int tts_core_stop(tts_client_s* client); +int tts_core_pause(tts_client_s* client); +int tts_core_repeat(tts_client_s* client, char** text_repeat, int* utt_id); + +int tts_core_add_pcm(tts_client_s* client, int event, const void* data, unsigned int data_size, int audio_type, int rate); +int tts_core_play_pcm(tts_client_s* client); +int tts_core_stop_pcm(tts_client_s* client); + int tts_core_receive_hello(int uid, int ret, int credential_needed); int tts_core_handle_service_reset(); -- 2.7.4