#include <sys/wait.h>
#include <system_info.h>
#include <vconf.h>
+#include <package-manager.h>
#include "tts.h"
#include "tts_client.h"
static int g_max_text_size = -1;
+static Ecore_Timer* g_check_state_timer = NULL;
+
+
+/* for repetition */
+static char* g_language = NULL;
+
+static int g_voice_type = -1;
+
+static int g_speed = -1;
+
+/* for checking engine update */
+static pkgmgr_client* g_pkgmgr = NULL;
+static char* g_engine_name = NULL;
+static int g_engine_update_status = 0;
+
/* Function definition */
static Eina_Bool __tts_notify_state_changed(void *data);
static Eina_Bool __tts_notify_error(void *data);
+int __tts_cb_error(int uid, tts_error_e reason, int utt_id, char* err_msg);
+
const char* tts_tag()
{
return code;
}
+//LCOV_EXCL_START
void __tts_config_voice_changed_cb(const char* before_lang, int before_voice_type, const char* language, int voice_type, bool auto_voice, void* user_data)
{
SLOG(LOG_DEBUG, TAG_TTSC, "Voice changed : Before lang(%s) type(%d) , Current lang(%s), type(%d)",
language, voice_type, data->default_voice_changed_user_data);
}
+ /* 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;
+ }
+ }
+
/* Next item */
iter = g_list_next(iter);
}
}
return;
}
+//LCOV_EXCL_STOP
+
+void __tts_unset_all_callbacks(tts_h tts)
+{
+ SLOG(LOG_INFO, TAG_TTSC, "@@@ unset all callbacks");
+
+ tts_unset_state_changed_cb(tts);
+ tts_unset_utterance_started_cb(tts);
+ tts_unset_utterance_completed_cb(tts);
+ tts_unset_error_cb(tts);
+ tts_unset_default_voice_changed_cb(tts);
+ tts_unset_engine_changed_cb(tts);
+
+ SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
+}
+
+static int __pkgmgr_status_cb(uid_t target_uid, int req_id, const char *type, const char *pkgname, const char *key, const char *val, const void *pmsg, void *data)
+{
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] pkgmgr status cb is invoked. pkgname(%s), type(%s), key(%s), val(%s)", pkgname, type, key, val);
+
+ if (0 != strncmp(g_engine_name, pkgname, strlen(g_engine_name))) {
+ SLOG(LOG_DEBUG, TAG_TTSC, "[WARN] this is not tts engine");
+ return 0;
+ } else {
+ if (key && 0 == strncmp(key, "start", strlen(key))) {
+ if (val && (0 == strncmp(val, "update", strlen(val) || 0 == strncmp(val, "uninstall", strlen(val))))) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] start to install.");
+ g_engine_update_status = 1;
+ }
+ } else if (key && 0 == strncmp(key, "end", strlen(key))) {
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] finish to install");
+ g_engine_update_status = 0;
+ }
+ }
+
+ return 0;
+}
+
+static void __create_pkgmgr_thread(void* data, Ecore_Thread* thread)
+{
+ SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] create pkgmgr thread");
+
+ while (!g_pkgmgr) {
+ g_pkgmgr = pkgmgr_client_new(PC_LISTENING);
+ if (NULL == g_pkgmgr) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create pkgmgr handle");
+ } else {
+ if (pkgmgr_client_listen_status(g_pkgmgr, __pkgmgr_status_cb, NULL) < 0) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to listen pkgmgr status. remove and recreate client");
+ pkgmgr_client_free(g_pkgmgr);
+ g_pkgmgr = NULL;
+ continue;
+ } else {
+ SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] Succeed to register pkgmgr cb");
+ }
+ }
+ usleep(10000);
+ }
+
+ return ;
+}
+
+static void __finish_pkgmgr_thread(void* data, Ecore_Thread* thread)
+{
+ SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] Finish pkgmgr thread");
+}
+
+static void __pkgmgr_thread(void* data)
+{
+ SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] call pkgmgr_thread");
+
+ ecore_thread_run(__create_pkgmgr_thread, __finish_pkgmgr_thread, NULL, NULL);
+
+ return ;
+}
int tts_create(tts_h* tts)
{
return __tts_convert_config_error_code(ret);
}
- ret = tts_config_mgr_set_callback(client->uid, _tts_config_engine_changed_cb, __tts_config_voice_changed_cb, NULL, NULL, client->tts);
+ ret = tts_config_mgr_set_callback(client->uid, _tts_config_engine_changed_cb, __tts_config_voice_changed_cb, NULL, NULL, NULL, client->tts);
if (0 != ret) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to set config changed : %d", ret);
tts_client_destroy(*tts);
return __tts_convert_config_error_code(ret);
}
+ ecore_main_loop_thread_safe_call_async(__pkgmgr_thread, NULL);
+
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] call ecore thread for creating pkgmgr thread");
+
+ g_engine_name = vconf_get_str(TTS_ENGINE_DB_DEFAULT);
+ if (NULL == g_engine_name) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get engine name");
+ } else {
+ SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Engine name(%s)", g_engine_name);
+ }
+
SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
SLOG(LOG_DEBUG, TAG_TTSC, " ");
return TTS_ERROR_OPERATION_FAILED;
}
+ if (g_pkgmgr) {
+ pkgmgr_client_remove_listen_status(g_pkgmgr);
+ pkgmgr_client_free(g_pkgmgr);
+ g_pkgmgr = NULL;
+ }
+
tts_config_mgr_finalize(client->uid);
int ret = -1;
do {
ret = tts_dbus_request_finalize(client->uid);
if (0 != ret) {
+ //LCOV_EXCL_START
if (TTS_ERROR_TIMED_OUT != ret) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret));
break;
break;
}
}
+ //LCOV_EXCL_STOP
}
} while (0 != ret);
} else {
ecore_timer_del(client->conn_timer);
client->conn_timer = NULL;
}
+ /* Unset registered callbacks */
+ __tts_unset_all_callbacks(tts);
+
/* Free resources */
tts_client_destroy(tts);
break;
}
}
+ if (NULL != g_language) {
+ free(g_language);
+ g_language = NULL;
+ }
+
+ /* Delete state timer before destroying handle */
+ if (NULL != g_check_state_timer) {
+ ecore_timer_del(g_check_state_timer);
+ g_check_state_timer = NULL;
+ }
+
tts = NULL;
SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
return TTS_ERROR_NONE;
}
+//LCOV_EXCL_START
void __tts_screen_reader_changed_cb(bool value)
{
g_screen_reader = value;
}
+//LCOV_EXCL_STOP
int tts_set_mode(tts_h tts, tts_mode_e mode)
{
return TTS_ERROR_NONE;
}
+//LCOV_EXCL_START
int tts_set_server_tts(tts_h tts, const char* credential)
{
if (0 != __tts_get_feature_enabled()) {
return TTS_ERROR_NONE;
}
+// LCOV_EXCL_STOP
static Eina_Bool __tts_connect_daemon(void *data)
{
return EINA_FALSE;
}
+ /* check whether engine is updating or not */
+ if (g_engine_update_status) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] cannot prepare due to engine update");
+ __tts_cb_error(-1, TTS_ERROR_SERVICE_RESET, -1, "Daemon Reset");
+
+ return EINA_FALSE;
+ }
+
/* Send hello */
if (0 != tts_dbus_request_hello(client->uid)) {
return EINA_TRUE;
client->utt_id = -1;
ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
- client->conn_timer = NULL;
+ if (client->conn_timer) {
+ ecore_timer_del(client->conn_timer);
+ client->conn_timer = NULL;
+ }
return EINA_FALSE;
} else if (TTS_ERROR_PERMISSION_DENIED == ret) {
client->utt_id = -1;
ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
- client->conn_timer = NULL;
+ if (client->conn_timer) {
+ ecore_timer_del(client->conn_timer);
+ client->conn_timer = NULL;
+ }
return EINA_FALSE;
} else if (TTS_ERROR_NONE != ret) {
SLOG(LOG_ERROR, TAG_TTSC, "Supported options : credential(%s)", credential_needed ? "need" : "no need");
}
- client->conn_timer = NULL;
+ if (client->conn_timer) {
+ ecore_timer_del(client->conn_timer);
+ client->conn_timer = NULL;
+ }
client = tts_client_get(tts);
/* check handle */
return TTS_ERROR_INVALID_STATE;
}
+ ecore_thread_main_loop_begin();
+ if (client->conn_timer) {
+ ecore_timer_del(client->conn_timer);
+ client->conn_timer = NULL;
+ }
client->conn_timer = ecore_timer_add(0.02, __tts_connect_daemon, (void*)tts);
+ ecore_thread_main_loop_end();
SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
return TTS_ERROR_NONE;
}
+//LCOV_EXCL_START
int tts_prepare_sync(tts_h tts)
{
if (0 != __tts_get_feature_enabled()) {
}
int cnt = 0;
- while (EINA_TRUE == __tts_connect_daemon(NULL) && TTS_CONNECTION_RETRY_COUNT > cnt) {
+ while (EINA_TRUE == __tts_connect_daemon((void*)tts) && TTS_CONNECTION_RETRY_COUNT > cnt) {
cnt++;
}
return TTS_ERROR_NONE;
}
+//LCOV_EXCL_STOP
int tts_unprepare(tts_h tts)
{
do {
ret = tts_dbus_request_finalize(client->uid);
if (0 != ret) {
+ //LCOV_EXCL_START
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
+ client->current_state = TTS_STATE_CREATED;
if (0 == tts_prepare_sync(tts)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
break;
}
}
+ //LCOV_EXCL_STOP
}
} while (0 != ret);
} else {
}
SLOG(LOG_DEBUG, TAG_TTSC, "Text is valid - text is '%s'", 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;
while (0 != ret) {
ret = tts_dbus_request_add_text(client->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) {
+ client->current_state = TTS_STATE_CREATED;
if (0 == tts_prepare_sync(tts)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
break;
}
}
+ //LCOV_EXCL_STOP
} else {
*utt_id = client->current_utt_id;
}
return ret;
}
+//LCOV_EXCL_START
static void __tts_play_async(void *data)
{
tts_h tts = (tts_h)data;
ret = tts_dbus_request_play(client->uid, client->credential);
if (0 != ret) {
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
+ client->current_state = TTS_STATE_CREATED;
if (0 == tts_prepare_sync(tts)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
return TTS_ERROR_NONE;
}
-
+//LCOV_EXCL_STOP
int tts_play(tts_h tts)
{
if (0 != __tts_get_feature_enabled()) {
while (0 != ret) {
ret = tts_dbus_request_play(client->uid, client->credential);
if (0 != ret) {
+ //LCOV_EXCL_START
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
+ client->current_state = TTS_STATE_CREATED;
if (0 == tts_prepare_sync(tts)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
return ret;
}
}
+ //LCOV_EXCL_STOP
}
}
return TTS_ERROR_NONE;
}
-
+//LCOV_EXCL_START
static void __tts_stop_async(void *data)
{
tts_h tts = (tts_h)data;
ret = tts_dbus_request_stop(client->uid);
if (0 != ret) {
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
+ client->current_state = TTS_STATE_CREATED;
if (0 == tts_prepare_sync(tts)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
return TTS_ERROR_NONE;
}
-
+//LCOV_EXCL_STOP
int tts_stop(tts_h tts)
{
if (0 != __tts_get_feature_enabled()) {
while (0 != ret) {
ret = tts_dbus_request_stop(client->uid);
if (0 != ret) {
+ //LCOV_EXCL_START
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
+ client->current_state = TTS_STATE_CREATED;
if (0 == tts_prepare_sync(tts)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
return ret;
}
}
+ //LCOV_EXCL_STOP
}
}
return TTS_ERROR_NONE;
}
-
+//LCOV_EXCL_START
static void __tts_pause_async(void *data)
{
tts_h tts = (tts_h)data;
ret = tts_dbus_request_pause(client->uid);
if (0 != ret) {
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
+ client->current_state = TTS_STATE_CREATED;
if (0 == tts_prepare_sync(tts)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
return TTS_ERROR_NONE;
}
-
+//LCOV_EXCL_STOP
int tts_pause(tts_h tts)
{
if (0 != __tts_get_feature_enabled()) {
while (0 != ret) {
ret = tts_dbus_request_pause(client->uid);
if (0 != ret) {
+ //LCOV_EXCL_START
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
+ client->current_state = TTS_STATE_CREATED;
if (0 == tts_prepare_sync(tts)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
return ret;
}
}
+ //LCOV_EXCL_STOP
}
}
SLOG(LOG_INFO, TAG_TTSC, "@@@ Set private data, key(%s), data(%s)", key, data);
if (NULL == tts) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle isnull");
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
return TTS_ERROR_INVALID_PARAMETER;
}
while (0 != ret) {
ret = tts_dbus_request_set_private_data(client->uid, key, data);
if (0 != ret) {
+ //LCOV_EXCL_START
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
+ client->current_state = TTS_STATE_CREATED;
if (0 == tts_prepare_sync(tts)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
return ret;
}
}
+ //LCOV_EXCL_STOP
}
}
while (0 != ret) {
ret = tts_dbus_request_get_private_data(client->uid, key, data);
if (0 != ret) {
+ //LCOV_EXCL_START
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
+ client->current_state = TTS_STATE_CREATED;
if (0 == tts_prepare_sync(tts)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
return ret;
}
}
+ //LCOV_EXCL_STOP
}
}
return 0;
}
+//LCOV_EXCL_START
static Eina_Bool __tts_notify_error(void *data)
{
tts_h tts = (tts_h)data;
return EINA_FALSE;
}
+static void __start_reprepare_thread(void* data, Ecore_Thread* thread)
+{
+ SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] start reprepare thread. engine update status(%d)", g_engine_update_status);
+
+ tts_client_s* temp = (tts_client_s*)data;
+ if (NULL == temp) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] data is null");
+ return ;
+ }
+
+ int cnt = 0;
+ while (!g_engine_update_status && (cnt < 10)) {
+ SLOG(LOG_WARN, TAG_TTSC, "[WARNING] wait for starting update");
+ usleep(50000);
+ cnt++;
+ }
+
+ SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] update status(%d)", g_engine_update_status);
+
+ while (g_engine_update_status && (NULL != g_pkgmgr)) {
+// SLOG(LOG_WARN, TAG_TTSC, "[WARNING] wait for finishing update");
+ usleep(200000);
+ }
+
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] finish updating. request to prepare");
+
+ if (0 != tts_prepare(temp->tts)) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare");
+ }
+
+ return ;
+}
+
+static void __end_reprepare_thread(void* data, Ecore_Thread* thread)
+{
+ SLOG(LOG_INFO, TAG_TTSC, "[INFO] end reprepare thread");
+}
+
int __tts_cb_error(int uid, tts_error_e reason, int utt_id, char* err_msg)
{
if (-1 == uid) {
SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset");
data->current_state = TTS_STATE_CREATED;
- if (0 != tts_prepare(data->tts)) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare");
- }
+ ecore_thread_run(__start_reprepare_thread, __end_reprepare_thread, NULL, data);
}
/* Next item */
SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset");
client->current_state = TTS_STATE_CREATED;
- if (0 != tts_prepare(client->tts)) {
- SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare");
- }
+
+ ecore_thread_run(__start_reprepare_thread, __end_reprepare_thread, NULL, client);
}
}
}
if (NULL != client->state_changed_cb) {
- ecore_timer_add(0, __tts_notify_state_changed, client->tts);
+ if (NULL != g_check_state_timer) {
+ ecore_timer_del(g_check_state_timer);
+ g_check_state_timer = NULL;
+ }
+ g_check_state_timer = ecore_timer_add(0, __tts_notify_state_changed, client->tts);
} else {
SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
}
return 0;
}
+//LCOV_EXCL_STOP
int __tts_cb_utt_started(int uid, int utt_id)
{
client->state_changed_cb = NULL;
client->state_changed_user_data = NULL;
+ if (NULL != g_check_state_timer) {
+ ecore_timer_del(g_check_state_timer);
+ g_check_state_timer = NULL;
+ }
+
SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset state changed cb");
return 0;
return 0;
}
+//LCOV_EXCL_START
int tts_add_pcm(tts_h tts, int event, const void* data, unsigned int data_size, int audio_type, int rate)
{
if (0 != __tts_get_feature_enabled()) {
ret = tts_dbus_request_add_pcm(client->uid, event, data, data_size, audio_type, rate);
if (0 != ret) {
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
+ client->current_state = TTS_STATE_CREATED;
if (0 == tts_prepare_sync(tts)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
ret = tts_dbus_request_play_pcm(client->uid);
if (0 != ret) {
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
+ client->current_state = TTS_STATE_CREATED;
if (0 == tts_prepare_sync(tts)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
ret = tts_dbus_request_stop_pcm(client->uid);
if (0 != ret) {
if (TTS_ERROR_INVALID_PARAMETER == ret && false == is_prepared) {
+ client->current_state = TTS_STATE_CREATED;
if (0 == tts_prepare_sync(tts)) {
is_prepared = true;
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Success tts_prepare_sync");
return TTS_ERROR_NONE;
}
+//LCOV_EXCL_STOP
+
+int tts_repeat(tts_h tts, char** text_repeat, int* utt_id)
+{
+ if (0 != __tts_get_feature_enabled()) {
+ return TTS_ERROR_NOT_SUPPORTED;
+ }
+
+ SLOG(LOG_INFO, TAG_TTSC, "@@@ Repeat TTS");
+
+ if (NULL == tts) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null.");
+ SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
+ return TTS_ERROR_INVALID_PARAMETER;
+ }
+
+ if (NULL == text_repeat || NULL == utt_id) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null.");
+ SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
+ return TTS_ERROR_INVALID_PARAMETER;
+ }
+
+ *text_repeat = NULL;
+ *utt_id = -1;
+
+ tts_client_s* client = tts_client_get(tts);
+
+ if (NULL == client) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid.");
+ SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
+ return TTS_ERROR_INVALID_PARAMETER;
+ }
+
+ if (TTS_STATE_READY != client->current_state) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid. (%d)", client->current_state);
+ return TTS_ERROR_INVALID_STATE;
+ }
+
+ /* 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 (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;
+ }
+
+ /* Play added texts */
+ ret = tts_play(tts);
+ 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;
+ return ret;
+ }
+
+ return TTS_ERROR_NONE;
+}