} tts_config_client_s;
typedef struct {
- const char* engine_id;
- const char* setting;
- const char* language;
+ char* engine_id;
+ char* setting;
+ char* language;
int voice_type;
bool auto_voice;
bool need_credential;
} engine_changed_cb_parameter_s;
typedef struct {
- const char* before_language;
+ char* before_language;
int before_voice_type;
- const char* current_language;
+ char* current_language;
int current_voice_type;
bool auto_voice;
} voice_changed_cb_parameter_s;
static int g_client_type = 0x0;
+static Ecore_Idler *g_engine_changed_event_idler = NULL;
+static Ecore_Idler *g_voice_changed_event_idler = NULL;
+static Ecore_Idler *g_speech_rate_changed_event_idler = NULL;
+static Ecore_Idler *g_pitch_changed_event_idler = NULL;
+static Ecore_Idler *g_bg_volume_ratio_changed_event_idler = NULL;
+
/* For engine directory monitoring */
typedef struct {
Ecore_Fd_Handler* dir_fd_handler;
return TTS_CONFIG_ERROR_OPERATION_FAILED;
}
-static void __invoke_engine_changed_cb(gpointer data, gpointer user_data)
+static inline void release_engine_changed_cb_params(engine_changed_cb_parameter_s *params)
+{
+ if (NULL == params) {
+ return;
+ }
+
+ free(params->engine_id);
+ free(params->setting);
+ free(params->language);
+ free(params);
+}
+
+static void invoke_engine_changed_cb(gpointer data, gpointer user_data)
{
tts_config_client_s* client = (tts_config_client_s*)data;
engine_changed_cb_parameter_s* params = (engine_changed_cb_parameter_s*)user_data;
}
}
-static void __invoke_voice_changed_cb(gpointer data, gpointer user_data)
+static Eina_Bool invoke_engine_changed_event_by_idler(void *data)
+{
+ engine_changed_cb_parameter_s *params = (engine_changed_cb_parameter_s *)data;
+ if (NULL != params) {
+ SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@ Config changed callback event");
+ SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Engine change(%s)", params->engine_id);
+
+ g_slist_foreach(g_config_client_list, invoke_engine_changed_cb, params);
+ release_engine_changed_cb_params(params);
+ }
+
+ g_engine_changed_event_idler = NULL;
+ return EINA_FALSE;
+}
+
+static inline void delete_engine_changed_event_invoker()
+{
+ if (NULL != g_engine_changed_event_idler) {
+ engine_changed_cb_parameter_s *params = (engine_changed_cb_parameter_s *)ecore_idler_del(g_engine_changed_event_idler);
+ g_engine_changed_event_idler = NULL;
+ release_engine_changed_cb_params(params);
+ }
+}
+
+static void invoke_engine_changed_event(const char* engine_id, const char* setting, const char* language, int voice_type, bool auto_voice, bool need_credential)
+{
+ delete_engine_changed_event_invoker();
+
+ engine_changed_cb_parameter_s *params = (engine_changed_cb_parameter_s *)calloc(1, sizeof(engine_changed_cb_parameter_s));
+ if (NULL == params) {
+ SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to allocate the memory for parameter");
+ return;
+ }
+
+ params->engine_id = strdup(engine_id);
+ params->setting = strdup(setting);
+ params->language = strdup(language);
+ params->voice_type = voice_type;
+ params->auto_voice = auto_voice;
+ params->need_credential = need_credential;
+ g_engine_changed_event_idler = ecore_idler_add(invoke_engine_changed_event_by_idler, params);
+}
+
+static inline void release_voice_changed_cb_params(voice_changed_cb_parameter_s *params)
+{
+ if (NULL == params) {
+ return;
+ }
+
+ free(params->before_language);
+ free(params->current_language);
+ free(params);
+}
+
+static void invoke_voice_changed_cb(gpointer data, gpointer user_data)
{
tts_config_client_s* client = (tts_config_client_s*)data;
voice_changed_cb_parameter_s* params = (voice_changed_cb_parameter_s*)user_data;
}
}
-Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler)
+static Eina_Bool invoke_voice_changed_event_by_idler(void *data)
+{
+ voice_changed_cb_parameter_s *params = (voice_changed_cb_parameter_s *)data;
+ if (NULL != params) {
+ SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@ Config changed callback event");
+ SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Voice change(%s, %d)", params->current_language, params->current_voice_type);
+
+ g_slist_foreach(g_config_client_list, invoke_voice_changed_cb, params);
+ release_voice_changed_cb_params(params);
+ }
+
+ g_voice_changed_event_idler = NULL;
+ return EINA_FALSE;
+}
+
+static inline void delete_voice_changed_event_invoker()
+{
+ if (NULL != g_voice_changed_event_idler) {
+ voice_changed_cb_parameter_s *params = (voice_changed_cb_parameter_s *)ecore_idler_del(g_voice_changed_event_idler);
+ g_voice_changed_event_idler = NULL;
+ release_voice_changed_cb_params(params);
+ }
+}
+
+static void invoke_voice_changed_event(const char* before_language, int before_voice_type, const char* current_language, int current_voice_type, bool auto_voice)
+{
+ delete_voice_changed_event_invoker();
+
+ voice_changed_cb_parameter_s *params = (voice_changed_cb_parameter_s *)calloc(1, sizeof(voice_changed_cb_parameter_s));
+ if (NULL == params) {
+ SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to allocate the memory for parameter");
+ return;
+ }
+
+ params->before_language = strdup(before_language);
+ params->before_voice_type = before_voice_type;
+ params->current_language = strdup(current_language);
+ params->current_voice_type = current_voice_type;
+ params->auto_voice = auto_voice;
+ g_voice_changed_event_idler = ecore_idler_add(invoke_voice_changed_event_by_idler, params);
+}
+
+static void invoke_speech_rate_changed_cb(gpointer data, gpointer user_data)
+{
+ tts_config_client_s* client = (tts_config_client_s*)data;
+ int* params = (int*)user_data;
+
+ if (NULL == client || NULL == params) {
+ SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] parmeter is NULL. client(%p), params(%p)", client, params);
+ return;
+ }
+
+ if (NULL != client->speech_cb) {
+ SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Speech rate changed callback : uid(%u)", client->uid);
+ client->speech_cb(*params, client->user_data);
+ }
+}
+
+static Eina_Bool invoke_speech_rate_changed_event_by_idler(void *data)
+{
+ int *params = (int *)data;
+ if (NULL != params) {
+ SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@ Config changed callback event");
+ SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Speech rate change(%d)", *params);
+
+ g_slist_foreach(g_config_client_list, invoke_speech_rate_changed_cb, params);
+ free(params);
+ }
+
+ g_speech_rate_changed_event_idler = NULL;
+ return EINA_FALSE;
+}
+
+static inline void delete_speech_rate_changed_event_invoker()
+{
+ if (NULL != g_speech_rate_changed_event_idler) {
+ int *params = (int *)ecore_idler_del(g_speech_rate_changed_event_idler);
+ g_speech_rate_changed_event_idler = NULL;
+ free(params);
+ }
+}
+
+static void invoke_speech_rate_changed_event(int speech_rate)
+{
+ delete_speech_rate_changed_event_invoker();
+
+ int *params = (int *)calloc(1, sizeof(int));
+ if (NULL == params) {
+ SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to allocate the memory for parameter");
+ return;
+ }
+
+ *params = speech_rate;
+ g_speech_rate_changed_event_idler = ecore_idler_add(invoke_speech_rate_changed_event_by_idler, params);
+}
+
+static void invoke_pitch_changed_cb(gpointer data, gpointer user_data)
+{
+ tts_config_client_s* client = (tts_config_client_s*)data;
+ int* params = (int*)user_data;
+
+ if (NULL == client || NULL == params) {
+ SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] parmeter is NULL. client(%p), params(%p)", client, params);
+ return;
+ }
+
+ if (NULL != client->pitch_cb) {
+ SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Pitch changed callback : uid(%u)", client->uid);
+ client->pitch_cb(*params, client->user_data);
+ }
+}
+
+static Eina_Bool invoke_pitch_changed_event_by_idler(void *data)
+{
+ int *params = (int *)data;
+ if (NULL == params) {
+ SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Parameter is null. Invalid invocation");
+ g_pitch_changed_event_idler = NULL;
+ return EINA_FALSE;
+ }
+
+ SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@ Config changed callback event");
+ SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Pitch change(%d)", *params);
+ g_slist_foreach(g_config_client_list, invoke_pitch_changed_cb, params);
+
+ free(params);
+ g_pitch_changed_event_idler = NULL;
+ return EINA_FALSE;
+}
+
+static inline void delete_pitch_changed_event_invoker()
+{
+ if (NULL != g_pitch_changed_event_idler) {
+ int *params = (int *)ecore_idler_del(g_pitch_changed_event_idler);
+ g_pitch_changed_event_idler = NULL;
+ free(params);
+ }
+}
+
+static void invoke_pitch_changed_event(int pitch)
+{
+ delete_pitch_changed_event_invoker();
+
+ int *params = (int *)calloc(1, sizeof(int));
+ if (NULL != params) {
+ SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to allocate the memory for parameter");
+ return;
+ }
+
+ *params = pitch;
+ g_pitch_changed_event_idler = ecore_idler_add(invoke_pitch_changed_event_by_idler, params);
+}
+
+static void invoke_bg_volume_ratio_changed_cb(gpointer data, gpointer user_data)
+{
+ tts_config_client_s* client = (tts_config_client_s*)data;
+ double* params = (double*)user_data;
+
+ if (NULL == client || NULL == params) {
+ SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] parmeter is NULL. client(%p), params(%p)", client, params);
+ return;
+ }
+
+ if (NULL != client->bg_volume_ratio_cb) {
+ SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Background volume ratio changed callback : uid(%u)", client->uid);
+ client->bg_volume_ratio_cb(*params, client->user_data);
+ }
+}
+
+static Eina_Bool invoke_bg_volume_ratio_changed_event_by_idler(void *data)
+{
+ double *params = (double *)data;
+ if (NULL == params) {
+ SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Parameter is null. Invalid invocation");
+ g_bg_volume_ratio_changed_event_idler = NULL;
+ return EINA_FALSE;
+ }
+
+ SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@ Config changed callback event");
+ SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "background volume ratio change(%lf)", *params);
+ g_slist_foreach(g_config_client_list, invoke_bg_volume_ratio_changed_cb, params);
+
+ free(params);
+ g_bg_volume_ratio_changed_event_idler = NULL;
+ return EINA_FALSE;
+}
+
+static inline void delete_bg_volume_ratio_changed_event_invoker()
+{
+ if (NULL != g_bg_volume_ratio_changed_event_idler) {
+ double *params = (double *)ecore_idler_del(g_bg_volume_ratio_changed_event_idler);
+ g_bg_volume_ratio_changed_event_idler = NULL;
+ free(params);
+ }
+}
+
+static void invoke_bg_volume_ratio_changed_event(double bg_volume_ratio)
+{
+ delete_bg_volume_ratio_changed_event_invoker();
+
+ double *params = (double *)calloc(1, sizeof(double));
+ if (NULL == params) {
+ SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to allocate the memory for parameter");
+ return;
+ }
+
+ *params = bg_volume_ratio;
+ g_bg_volume_ratio_changed_event_idler = ecore_idler_add(invoke_bg_volume_ratio_changed_event_by_idler, params);
+}
+
+static void delete_all_event_invokers()
+{
+ delete_engine_changed_event_invoker();
+ delete_voice_changed_event_invoker();
+ delete_speech_rate_changed_event_invoker();
+ delete_pitch_changed_event_invoker();
+ delete_bg_volume_ratio_changed_event_invoker();
+}
+
+static Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler)
{
SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@ Config changed callback event");
int pitch = -1;
double bg_volume_ratio = -1;
- GSList *iter = NULL;
- tts_config_client_s* temp_client = NULL;
-
if (0 != tts_parser_find_config_changed(&engine, &setting, &auto_voice, &lang, &voice_type, &speech_rate, &pitch, &bg_volume_ratio))
return ECORE_CALLBACK_PASS_ON;
memset(g_engine_id, '\0', sizeof(g_engine_id));
config_info.engine_id = g_engine_id;
strncpy(config_info.engine_id, engine, sizeof(g_engine_id) - 1);
+ free(engine);
}
+
if (NULL != setting) {
memset(g_setting, '\0', sizeof(g_setting));
config_info.setting = g_setting;
strncpy(config_info.setting, setting, sizeof(g_setting) - 1);
+ free(setting);
}
SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Engine change(%s)", config_info.engine_id);
/* Call all callbacks of client*/
- engine_changed_cb_parameter_s params = {config_info.engine_id, config_info.setting,config_info.language,
- config_info.type, config_info.auto_voice, config_info.credential};
- g_slist_foreach(g_config_client_list, __invoke_engine_changed_cb, ¶ms);
+ invoke_engine_changed_event(config_info.engine_id, config_info.setting, config_info.language, config_info.type, config_info.auto_voice, config_info.credential);
}
if (auto_voice != config_info.auto_voice) {
SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Voice change(%s, %d)", config_info.language, config_info.type);
/* Call all callbacks of client*/
- voice_changed_cb_parameter_s params = {before_lang, before_type, config_info.language,
- config_info.type, config_info.auto_voice};
- g_slist_foreach(g_config_client_list, __invoke_voice_changed_cb, ¶ms);
+ invoke_voice_changed_event(before_lang, before_type, config_info.language, config_info.type, config_info.auto_voice);
+ free(lang);
free(before_lang);
}
if (-1 != speech_rate) {
config_info.speech_rate = speech_rate;
-
SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Speech rate change(%d)", config_info.speech_rate);
/* Call all callbacks of client*/
- iter = g_slist_nth(g_config_client_list, 0);
-
- while (NULL != iter) {
- temp_client = iter->data;
-
- if (NULL != temp_client) {
- if (NULL != temp_client->speech_cb) {
- SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Speech rate changed callback : uid(%u)", temp_client->uid);
- temp_client->speech_cb(config_info.speech_rate, temp_client->user_data);
- }
- }
-
- iter = g_slist_next(iter);
- }
+ invoke_speech_rate_changed_event(config_info.speech_rate);
}
if (-1 != pitch) {
config_info.pitch = pitch;
-
SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "pitch change(%d)", config_info.pitch);
/* Call all callbacks of client*/
- iter = g_slist_nth(g_config_client_list, 0);
-
- while (NULL != iter) {
- temp_client = iter->data;
-
- if (NULL != temp_client) {
- if (NULL != temp_client->pitch_cb) {
- SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Pitch changed callback : uid(%u)", temp_client->uid);
- temp_client->pitch_cb(config_info.pitch, temp_client->user_data);
- }
- }
-
- iter = g_slist_next(iter);
- }
+ invoke_pitch_changed_event(config_info.pitch);
}
if (0.0 <= bg_volume_ratio) {
config_info.bg_volume_ratio = bg_volume_ratio;
-
SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "background volume ratio change(%lf)", config_info.bg_volume_ratio);
/* Call all callbacks of client*/
- iter = g_slist_nth(g_config_client_list, 0);
-
- while (NULL != iter) {
- temp_client = iter->data;
-
- if (NULL != temp_client) {
- if (NULL != temp_client->bg_volume_ratio_cb) {
- SECURE_SLOG(LOG_DEBUG, TAG_TTSCONFIG, "background volume ratio changed callback : uid(%u)", temp_client->uid);
- temp_client->bg_volume_ratio_cb(config_info.bg_volume_ratio, temp_client->user_data);
- }
- }
-
- iter = g_slist_next(iter);
- }
- }
-
- if (NULL != engine) {
- free(engine);
- engine = NULL;
- }
- if (NULL != setting) {
- free(setting);
- setting = NULL;
- }
- if (NULL != lang) {
- free(lang);
- lang = NULL;
+ invoke_bg_volume_ratio_changed_event(config_info.bg_volume_ratio);
}
if (0 != tts_parser_set_config_info(&config_info)){
SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to save config");
return TTS_CONFIG_ERROR_OPERATION_FAILED;
}
+
+ invoke_voice_changed_event(config_info.language, config_info.type, selected_language, selected_type, config_info.auto_voice);
} else {
SLOG(LOG_INFO, TAG_TTSCONFIG, "Client is not allowed to save configuration. Skip saving configuration file.");
}
- char *before_lang = (NULL != config_info.language ? strdup(config_info.language) : NULL);
- int before_type = config_info.type;
-
set_voice_into_config(&config_info, selected_language, selected_type);
if (0 != tts_parser_set_config_info(&config_info)){
SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to set configure information");
- free(before_lang);
return TTS_CONFIG_ERROR_OPERATION_FAILED;
}
- /* Call all callbacks of client*/
- voice_changed_cb_parameter_s params = {before_lang, before_type, config_info.language,
- config_info.type, config_info.auto_voice};
- g_slist_foreach(g_config_client_list, __invoke_voice_changed_cb, ¶ms);
- free(before_lang);
-
return TTS_CONFIG_ERROR_NONE;
}
}
/* Call all callbacks of client*/
- engine_changed_cb_parameter_s params = {config_info.engine_id, config_info.setting,config_info.language,
- config_info.type, config_info.auto_voice, config_info.credential};
- g_slist_foreach(g_config_client_list, __invoke_engine_changed_cb, ¶ms);
+ invoke_engine_changed_event(config_info.engine_id, config_info.setting, config_info.language, config_info.type, config_info.auto_voice, config_info.credential);
} else {
SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Undefined event");
}
SLOG(LOG_INFO, TAG_TTSCONFIG, "Client type : %d", client_type);
g_client_type &= ~client_type;
+ delete_all_event_invokers();
+
__tts_config_release_engine();
tts_parser_unload_config();
SLOG(LOG_ERROR, TAG_TTSCONFIG, " Fail to save config");
return TTS_CONFIG_ERROR_OPERATION_FAILED;
}
+
+ invoke_engine_changed_event(config_info.engine_id, config_info.setting, config_info.language, config_info.type, config_info.auto_voice, config_info.credential);
} else {
SLOG(LOG_INFO, TAG_TTSCONFIG, "Client type is default. Skip saving configuration file.");
}
SLOG(LOG_ERROR, TAG_TTSCONFIG, "Fail to save default voice");
return TTS_CONFIG_ERROR_OPERATION_FAILED;
}
+
+ invoke_voice_changed_event(config_info.language, config_info.type, language, type, config_info.auto_voice);
} else {
SLOG(LOG_INFO, TAG_TTSCONFIG, "Client type is default. Skip saving configuration file.");
}
SLOG(LOG_ERROR, TAG_TTSCONFIG, "Fail to save speech rate");
return TTS_CONFIG_ERROR_OPERATION_FAILED;
}
+
+ invoke_speech_rate_changed_event(value);
} else {
SLOG(LOG_INFO, TAG_TTSCONFIG, "Client type is default. Skip saving configuration file.");
}
SLOG(LOG_ERROR, TAG_TTSCONFIG, "Fail to save pitch");
return TTS_CONFIG_ERROR_OPERATION_FAILED;
}
+
+ invoke_pitch_changed_event(value);
} else {
SLOG(LOG_INFO, TAG_TTSCONFIG, "Client type is default. Skip saving configuration file.");
}
SLOG(LOG_ERROR, TAG_TTSCONFIG, "Fail to save bg volume ratio");
return TTS_CONFIG_ERROR_OPERATION_FAILED;
}
+
+ invoke_bg_volume_ratio_changed_event(value);
} else {
SLOG(LOG_INFO, TAG_TTSCONFIG, "Client type is default. Skip saving configuration file.");
}
SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to set configure information");
return TTS_CONFIG_ERROR_OPERATION_FAILED;
}
-
return TTS_CONFIG_ERROR_NONE;
}