2 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd All Rights Reserved
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 * http://www.apache.org/licenses/LICENSE-2.0
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS,
9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and
11 * limitations under the License.
19 #include "ttsd_main.h"
20 #include "ttsd_engine_agent.h"
21 #include "ttsd_config.h"
23 #define ENGINE_PATH_SIZE 256
26 * Internal data structure
34 /* info for using engine load */
40 /* engine base setting */
46 ttspe_funcs_s* pefuncs;
47 ttspd_funcs_s* pdfuncs;
49 int (*ttsp_load_engine)(const ttspd_funcs_s* pdfuncs, ttspe_funcs_s* pefuncs);
50 int (*ttsp_unload_engine)();
57 char* setting_ug_path;
72 static bool g_agent_init;
74 /** TTS engine list */
75 static GList *g_engine_list;
77 /** Current engine information */
78 static ttsengine_s g_cur_engine;
80 /** Current voice information */
81 static GSList* g_cur_voices;
83 /** Result callback function */
84 static synth_result_callback g_result_cb;
87 /** Set current engine */
88 int __internal_set_current_engine(const char* engine_uuid);
90 /** Check engine id */
91 int __internal_check_engine_id(const char* engine_uuid);
93 /** Update engine list */
94 int __internal_update_engine_list();
96 /** Get engine info */
97 int __internal_get_engine_info(const char* filepath, ttsengine_info_s** info);
99 /** Callback function for result */
100 bool __result_cb(ttsp_result_event_e event, const void* data, unsigned int data_size,
101 ttsp_audio_type_e audio_type, int rate, void *user_data);
103 /** Callback function for voice list */
104 bool __supported_voice_cb(const char* language, int type, void* user_data);
106 /** Free voice list */
107 void __free_voice_list(GList* voice_list);
109 /** Callback function for engine info */
110 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* setting_ug_name,
111 bool use_network, void* user_data);
113 /** Callback fucntion for engine setting */
114 bool __engine_setting_cb(const char* key, const char* value, void* user_data);
118 int ttsd_print_enginelist();
120 int ttsd_print_voicelist();
122 static const char* __ttsd_get_engine_error_code(ttsp_error_e err)
125 case TTSP_ERROR_NONE: return "TTSP_ERROR_NONE";
126 case TTSP_ERROR_OUT_OF_MEMORY: return "TTSP_ERROR_OUT_OF_MEMORY";
127 case TTSP_ERROR_IO_ERROR: return "TTSP_ERROR_IO_ERROR";
128 case TTSP_ERROR_INVALID_PARAMETER: return "TTSP_ERROR_INVALID_PARAMETER";
129 case TTSP_ERROR_OUT_OF_NETWORK: return "TTSP_ERROR_OUT_OF_NETWORK";
130 case TTSP_ERROR_INVALID_STATE: return "TTSP_ERROR_INVALID_STATE";
131 case TTSP_ERROR_INVALID_VOICE: return "TTSP_ERROR_INVALID_VOICE";
132 case TTSP_ERROR_OPERATION_FAILED: return "TTSP_ERROR_OPERATION_FAILED";
134 return "Invalid error code";
138 int ttsd_engine_agent_init(synth_result_callback result_cb)
140 /* initialize static data */
141 if (result_cb == NULL) {
142 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] invalid parameter");
143 return TTSD_ERROR_INVALID_PARAMETER;
146 g_result_cb = result_cb;
148 g_cur_engine.engine_uuid = NULL;
149 g_cur_engine.engine_name = NULL;
150 g_cur_engine.engine_path = NULL;
152 g_cur_engine.is_set = false;
153 g_cur_engine.handle = NULL;
154 g_cur_engine.pefuncs = (ttspe_funcs_s*)calloc(1, sizeof(ttspe_funcs_s));
155 g_cur_engine.pdfuncs = (ttspd_funcs_s*)calloc(1, sizeof(ttspd_funcs_s));
159 if (0 != ttsd_config_get_default_voice(&(g_cur_engine.default_lang), &(g_cur_engine.default_vctype))) {
160 SLOG(LOG_WARN, get_tag(), "[Server WARNING] There is No default voice in config");
161 /* Set default voice */
162 g_cur_engine.default_lang = strdup(TTS_BASE_LANGUAGE);
163 g_cur_engine.default_vctype = TTSP_VOICE_TYPE_FEMALE;
166 if (0 != ttsd_config_get_default_speed(&(g_cur_engine.default_speed))) {
167 SLOG(LOG_WARN, get_tag(), "[Server WARNING] There is No default speed in config");
168 g_cur_engine.default_speed = TTS_SPEED_NORMAL;
171 if (0 != ttsd_config_get_default_pitch(&(g_cur_engine.default_pitch))) {
172 SLOG(LOG_WARN, get_tag(), "[Server WARNING] There is No default pitch in config");
173 g_cur_engine.default_pitch = TTS_PITCH_NORMAL;
176 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Initialize Engine Agent");
181 int ttsd_engine_agent_release()
183 if (false == g_agent_init) {
184 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
185 return TTSD_ERROR_OPERATION_FAILED;
188 /* unload current engine */
189 ttsd_engine_agent_unload_current_engine();
191 /* release engine list */
193 ttsengine_info_s *data = NULL;
195 if (g_list_length(g_engine_list) > 0) {
196 /* Get a first item */
197 iter = g_list_first(g_engine_list);
198 while (NULL != iter) {
199 /* Get data from item */
201 iter = g_list_remove(iter, data);
204 if (NULL != data->engine_uuid) free(data->engine_uuid);
205 if (NULL != data->engine_name) free(data->engine_name);
206 if (NULL != data->setting_ug_path) free(data->setting_ug_path);
207 if (NULL != data->engine_path) free(data->engine_path);
214 /* release current engine data */
215 if (g_cur_engine.engine_uuid != NULL) free(g_cur_engine.engine_uuid);
216 if (g_cur_engine.engine_name != NULL) free(g_cur_engine.engine_name);
217 if (g_cur_engine.engine_path != NULL) free(g_cur_engine.engine_path);
219 if (g_cur_engine.pefuncs != NULL) free(g_cur_engine.pefuncs);
220 if (g_cur_engine.pdfuncs != NULL) free(g_cur_engine.pdfuncs);
221 if (g_cur_engine.default_lang != NULL) free(g_cur_engine.default_lang);
223 g_agent_init = false;
225 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Release Engine Agent");
230 int ttsd_engine_agent_initialize_current_engine()
232 if (false == g_agent_init) {
233 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
234 return TTSD_ERROR_OPERATION_FAILED;
237 /* update engine list */
238 if (0 != __internal_update_engine_list()) {
239 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] No engine error");
240 return TTSD_ERROR_OPERATION_FAILED;
243 /* 2. get current engine from config */
244 char* cur_engine_uuid = NULL;
245 bool is_get_engineid_from_config = false;
247 if (0 != ttsd_config_get_default_engine(&cur_engine_uuid)) {
248 /*not set current engine */
249 /*set system default engine*/
251 ttsengine_info_s *data = NULL;
253 if (g_list_length(g_engine_list) > 0) {
254 iter = g_list_first(g_engine_list);
258 if (NULL != data->engine_uuid) {
259 cur_engine_uuid = strdup(data->engine_uuid);
260 ttsd_config_set_default_engine(cur_engine_uuid);
262 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Data of current engine is corrupt");
263 return TTSD_ERROR_OPERATION_FAILED;
267 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] Fail to set a engine of engine list");
268 return TTSD_ERROR_OPERATION_FAILED;
271 is_get_engineid_from_config = false;
273 is_get_engineid_from_config = true;
276 if (NULL == cur_engine_uuid) {
277 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Current engine id is NULL");
278 return TTSD_ERROR_OPERATION_FAILED;
281 /* check whether cur engine uuid is valid or not. */
282 if (0 != __internal_check_engine_id(cur_engine_uuid)) {
283 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] It is not valid engine id from config");
287 if (g_list_length(g_engine_list) > 0)
288 iter = g_list_first(g_engine_list);
290 SLOG(LOG_WARN, get_tag(), "[Engine Agent ERROR] NO TTS Engine !!");
291 if (NULL != cur_engine_uuid) free(cur_engine_uuid);
292 return TTSD_ERROR_OPERATION_FAILED;
295 if (cur_engine_uuid != NULL) free(cur_engine_uuid);
296 ttsengine_info_s *data = NULL;
299 cur_engine_uuid = strdup(data->engine_uuid);
301 is_get_engineid_from_config = false;
304 if (NULL != cur_engine_uuid)
305 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Current Engine Id : %s", cur_engine_uuid);
307 return TTSD_ERROR_OPERATION_FAILED;
309 /* set current engine */
310 if (0 != __internal_set_current_engine(cur_engine_uuid)) {
311 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to set current engine ");
312 if (NULL != cur_engine_uuid) free(cur_engine_uuid);
313 return TTSD_ERROR_OPERATION_FAILED;
316 if (false == is_get_engineid_from_config) {
317 if (0 != ttsd_config_set_default_engine(cur_engine_uuid)) {
318 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to set id to config");
322 if (NULL != cur_engine_uuid) free(cur_engine_uuid);
324 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set current engine");
329 int __internal_check_engine_id(const char* engine_uuid)
332 ttsengine_s *data = NULL;
334 if (g_list_length(g_engine_list) > 0) {
335 iter = g_list_first(g_engine_list);
337 while (NULL != iter) {
340 if (0 == strncmp(engine_uuid, data->engine_uuid, strlen(data->engine_uuid)))
343 iter = g_list_next(iter);
350 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* setting_ug_name,
351 bool use_network, void* user_data)
353 ttsengine_info_s* temp = (ttsengine_info_s*)user_data;
355 if (NULL != engine_uuid)
356 temp->engine_uuid = strdup(engine_uuid);
358 if (NULL != engine_name)
359 temp->engine_name = strdup(engine_name);
361 if (NULL != setting_ug_name)
362 temp->setting_ug_path = strdup(setting_ug_name);
364 temp->use_network = use_network;
368 int __internal_get_engine_info(const char* filepath, ttsengine_info_s** info)
373 handle = dlopen(filepath, RTLD_LAZY);
376 SECURE_SLOG(LOG_WARN, get_tag(), "[Engine Agent] Invalid engine : %s", filepath);
377 return TTSD_ERROR_OPERATION_FAILED;
380 /* link engine to daemon */
381 dlsym(handle, "ttsp_load_engine");
382 if ((error = dlerror()) != NULL) {
383 SECURE_SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to open ttsp_load_engine : path(%s) message(%s)", filepath, error);
385 return TTSD_ERROR_OPERATION_FAILED;
388 dlsym(handle, "ttsp_unload_engine");
389 if ((error = dlerror()) != NULL) {
390 SECURE_SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to open ttsp_unload_engine : path(%s) message(%s)", filepath, error);
392 return TTSD_ERROR_OPERATION_FAILED;
395 int (*get_engine_info)(ttsp_engine_info_cb callback, void* user_data);
397 get_engine_info = (int (*)(ttsp_engine_info_cb, void*))dlsym(handle, "ttsp_get_engine_info");
398 if (NULL != (error = dlerror()) || NULL == get_engine_info) {
399 SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to open ttsp_get_engine_info() :path(%s) message(%s)", filepath, error);
401 return TTSD_ERROR_OPERATION_FAILED;
404 ttsengine_info_s* temp;
405 temp = (ttsengine_info_s*)calloc(1, sizeof(ttsengine_info_s));
407 SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to alloc memory");
409 return TTSD_ERROR_OUT_OF_MEMORY;
412 /* get engine info */
413 if (0 != get_engine_info(&__engine_info_cb, (void*)temp)) {
414 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to get engine info");
417 return TTSD_ERROR_OPERATION_FAILED;
423 if (TTSD_MODE_SCREEN_READER == ttsd_get_mode() && true == temp->use_network) {
424 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent WARNING] %s is invalid because of network based", temp->engine_name);
425 if (NULL != temp->engine_uuid) free(temp->engine_uuid);
426 if (NULL != temp->engine_name) free(temp->engine_name);
427 if (NULL != temp->setting_ug_path) free(temp->setting_ug_path);
429 return TTSD_ERROR_OPERATION_FAILED;
432 temp->engine_path = strdup(filepath);
434 SLOG(LOG_DEBUG, get_tag(), "----- Valid engine");
435 SECURE_SLOG(LOG_DEBUG, get_tag(), "Engine uuid : %s", temp->engine_uuid);
436 SECURE_SLOG(LOG_DEBUG, get_tag(), "Engine name : %s", temp->engine_name);
437 SECURE_SLOG(LOG_DEBUG, get_tag(), "Setting path : %s", temp->setting_ug_path);
438 SECURE_SLOG(LOG_DEBUG, get_tag(), "Engine path : %s", temp->engine_path);
439 SECURE_SLOG(LOG_DEBUG, get_tag(), "Use network : %s", temp->use_network ? "true" : "false");
440 SLOG(LOG_DEBUG, get_tag(), "-----");
441 SLOG(LOG_DEBUG, get_tag(), " ");
448 int __internal_update_engine_list()
450 /* relsease engine list */
452 ttsengine_info_s *data = NULL;
454 if (g_list_length(g_engine_list) > 0) {
455 iter = g_list_first(g_engine_list);
457 while (NULL != iter) {
460 if (data != NULL) free(data);
461 g_engine_list = g_list_remove_link(g_engine_list, iter);
462 iter = g_list_first(g_engine_list);
466 /* get file name from engine directory and get engine information from each filename */
470 struct dirent *dirp = NULL;
471 dp = opendir(TTS_DEFAULT_ENGINE);
475 ret = readdir_r(dp, &entry, &dirp);
477 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to read directory");
482 ttsengine_info_s* info;
483 char* filepath = NULL;
486 file_size = strlen(TTS_DEFAULT_ENGINE) + strlen(dirp->d_name) + 5;
487 filepath = (char*)calloc(file_size, sizeof(char));
489 if (NULL != filepath) {
490 snprintf(filepath, file_size, "%s/%s", TTS_DEFAULT_ENGINE, dirp->d_name);
492 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not enough memory!!" );
496 /* get its info and update engine list */
497 if (0 == __internal_get_engine_info(filepath, &info)) {
498 /* add engine info to g_engine_list */
499 g_engine_list = g_list_append(g_engine_list, info);
502 if (NULL != filepath) free(filepath);
504 } while (NULL != dirp);
509 dp = opendir(TTS_DOWNLOAD_ENGINE);
513 ret = readdir_r(dp, &entry, &dirp);
515 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to read directory");
520 ttsengine_info_s* info;
521 char* filepath = NULL;
524 file_size = strlen(TTS_DOWNLOAD_ENGINE) + strlen(dirp->d_name) + 5;
525 filepath = (char*)calloc(file_size, sizeof(char));
527 if (NULL != filepath) {
528 snprintf(filepath, file_size, "%s/%s", TTS_DOWNLOAD_ENGINE, dirp->d_name);
530 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not enough memory!!" );
534 /* get its info and update engine list */
535 if (0 == __internal_get_engine_info(filepath, &info)) {
536 /* add engine info to g_engine_list */
537 g_engine_list = g_list_append(g_engine_list, info);
540 if (NULL != filepath) free(filepath);
542 } while (NULL != dirp);
547 if (g_list_length(g_engine_list) <= 0) {
548 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No Engine");
549 return TTSD_ERROR_OPERATION_FAILED;
552 #ifdef ENGINE_AGENT_DEBUG
553 ttsd_print_enginelist();
558 int __internal_set_current_engine(const char* engine_uuid)
560 /* check whether engine id is valid or not. */
562 ttsengine_info_s *data = NULL;
565 if (g_list_length(g_engine_list) > 0) {
566 iter = g_list_first(g_engine_list);
568 while (NULL != iter) {
571 if (0 == strncmp(data->engine_uuid, engine_uuid, strlen(engine_uuid))) {
577 iter = g_list_next(iter);
581 /* If current engine does not exist, return error */
583 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Cannot find engine id");
584 return TTSD_ERROR_OPERATION_FAILED;
586 if (g_cur_engine.engine_uuid != NULL) {
587 /*compare current engine uuid */
588 if (0 == strncmp(g_cur_engine.engine_uuid, data->engine_uuid, strlen(engine_uuid))) {
589 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] tts engine has already been set");
595 /* set data from g_engine_list */
596 if (g_cur_engine.engine_uuid != NULL) free(g_cur_engine.engine_uuid);
597 if (g_cur_engine.engine_name != NULL) free(g_cur_engine.engine_name);
598 if (g_cur_engine.engine_path != NULL) free(g_cur_engine.engine_path);
600 if (NULL == data->engine_uuid || NULL == data->engine_name || NULL == data->engine_path) {
601 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Engine data is NULL");
602 return TTSD_ERROR_OPERATION_FAILED;
605 g_cur_engine.engine_uuid = strdup(data->engine_uuid);
606 g_cur_engine.engine_name = strdup(data->engine_name);
607 g_cur_engine.engine_path = strdup(data->engine_path);
609 g_cur_engine.handle = NULL;
610 g_cur_engine.is_loaded = false;
611 g_cur_engine.is_set = true;
612 g_cur_engine.need_network = data->use_network;
614 SLOG(LOG_DEBUG, get_tag(), "-----");
615 SECURE_SLOG(LOG_DEBUG, get_tag(), "Current engine uuid : %s", g_cur_engine.engine_uuid);
616 SECURE_SLOG(LOG_DEBUG, get_tag(), "Current engine name : %s", g_cur_engine.engine_name);
617 SECURE_SLOG(LOG_DEBUG, get_tag(), "Current engine path : %s", g_cur_engine.engine_path);
618 SLOG(LOG_DEBUG, get_tag(), "-----");
623 bool __set_voice_info_cb(const char* language, int type, void* user_data)
625 if (NULL == language) {
626 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
630 ttsvoice_s* voice = calloc(1, sizeof(ttsvoice_s));
631 voice->lang = strdup(language);
634 voice->client_ref_count = 0;
635 voice->is_loaded = false;
637 if (0 == strcmp(g_cur_engine.default_lang, language) && g_cur_engine.default_vctype == type) {
638 voice->is_default = true;
639 voice->is_loaded = true;
641 voice->is_default = false;
644 g_cur_voices = g_slist_append(g_cur_voices, voice);
649 int __update_voice_list()
655 ret = g_cur_engine.pefuncs->foreach_voices(__set_voice_info_cb, NULL);
656 if (0 != ret || 0 >= g_slist_length(g_cur_voices)) {
657 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
661 #ifdef ENGINE_AGENT_DEBUG
662 ttsd_print_voicelist();
667 int ttsd_engine_agent_load_current_engine()
669 if (false == g_agent_init) {
670 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
671 return TTSD_ERROR_OPERATION_FAILED;
674 if (false == g_cur_engine.is_set) {
675 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No Current Engine ");
676 return TTSD_ERROR_OPERATION_FAILED;
679 /* check whether current engine is loaded or not */
680 if (true == g_cur_engine.is_loaded) {
681 SLOG(LOG_ERROR, get_tag(), "[Engine Agent] Engine has already been loaded ");
687 g_cur_engine.handle = dlopen(g_cur_engine.engine_path, RTLD_LAZY); /* RTLD_LAZY RTLD_NOW*/
689 if (NULL != (error = dlerror()) || NULL == g_cur_engine.handle) {
690 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to get current engine handle : %s", error);
694 g_cur_engine.ttsp_unload_engine = (int (*)())dlsym(g_cur_engine.handle, "ttsp_unload_engine");
695 if (NULL != (error = dlerror()) || NULL == g_cur_engine.ttsp_unload_engine) {
696 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to link daemon to ttsp_unload_engine() : %s", error);
700 g_cur_engine.ttsp_load_engine = (int (*)(const ttspd_funcs_s* , ttspe_funcs_s*))dlsym(g_cur_engine.handle, "ttsp_load_engine");
701 if (NULL != (error = dlerror()) || NULL == g_cur_engine.ttsp_load_engine) {
702 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to link daemon to ttsp_load_engine() : %s", error);
707 g_cur_engine.pdfuncs->version = 1;
708 g_cur_engine.pdfuncs->size = sizeof(ttspd_funcs_s);
711 ret = g_cur_engine.ttsp_load_engine(g_cur_engine.pdfuncs, g_cur_engine.pefuncs);
713 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to load engine - %s : result(%s)",
714 g_cur_engine.engine_path, __ttsd_get_engine_error_code(ret));
715 return TTSD_ERROR_OPERATION_FAILED;
718 /* engine error check */
719 if (g_cur_engine.pefuncs->size != sizeof(ttspe_funcs_s)) {
720 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] The size of engine function is not valid");
723 if (NULL == g_cur_engine.pefuncs->initialize ||
724 NULL == g_cur_engine.pefuncs->deinitialize ||
725 NULL == g_cur_engine.pefuncs->foreach_voices ||
726 NULL == g_cur_engine.pefuncs->is_valid_voice ||
727 NULL == g_cur_engine.pefuncs->start_synth ||
728 NULL == g_cur_engine.pefuncs->cancel_synth) {
729 SLOG(LOG_ERROR, get_tag(), "[Engine ERROR] The engine functions are NOT valid");
730 return TTSD_ERROR_OPERATION_FAILED;
733 ret = g_cur_engine.pefuncs->initialize(__result_cb);
735 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to initialize current engine : %s", __ttsd_get_engine_error_code(ret));
736 return TTSD_ERROR_OPERATION_FAILED;
739 /* Get voice info of current engine */
740 ret = __update_voice_list();
742 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set voice info : result(%d)", ret);
743 return TTSD_ERROR_OPERATION_FAILED;
746 /* Select default voice */
747 if (NULL != g_cur_engine.default_lang) {
748 if (true == g_cur_engine.pefuncs->is_valid_voice(g_cur_engine.default_lang, g_cur_engine.default_vctype)) {
749 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set origin default voice to current engine : lang(%s), type(%d)",
750 g_cur_engine.default_lang, g_cur_engine.default_vctype);
752 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] Fail set origin default voice : lang(%s), type(%d)",
753 g_cur_engine.default_lang, g_cur_engine.default_vctype);
755 return TTSD_ERROR_OPERATION_FAILED;
759 /* load default voice */
760 if (NULL != g_cur_engine.pefuncs->load_voice) {
761 ret = g_cur_engine.pefuncs->load_voice(g_cur_engine.default_lang, g_cur_engine.default_vctype);
763 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Load default voice : lang(%s), type(%d)",
764 g_cur_engine.default_lang, g_cur_engine.default_vctype);
766 SLOG(LOG_WARN, get_tag(), "[Engine Agent ERROR] Fail to load default voice : lang(%s), type(%d) result(%s)",
767 g_cur_engine.default_lang, g_cur_engine.default_vctype, __ttsd_get_engine_error_code(ret));
769 return TTSD_ERROR_OPERATION_FAILED;
774 if (false == set_voice) {
775 /* get language list */
777 GList* voice_list = NULL;
779 ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, &voice_list);
781 if (0 == ret && 0 < g_list_length(voice_list)) {
783 voice_s* voice = NULL;
785 iter = g_list_first(voice_list);
788 while (NULL != iter) {
792 if (0 == strcmp("en_US", voice->language))
796 iter = g_list_next(iter);
799 SLOG(LOG_ERROR, get_tag(), "[Engine ERROR] Fail to find voice in list");
800 return TTSD_ERROR_OPERATION_FAILED;
803 /* Set selected language and type */
804 if (true != g_cur_engine.pefuncs->is_valid_voice(voice->language, voice->type)) {
805 SLOG(LOG_ERROR, get_tag(), "[Engine ERROR] Fail voice is NOT valid");
806 return TTSD_ERROR_OPERATION_FAILED;
809 ttsd_config_set_default_voice(voice->language, (int)voice->type);
811 g_cur_engine.default_lang = strdup(voice->language);
812 g_cur_engine.default_vctype = voice->type;
814 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Select default voice : lang(%s), type(%d)",
815 voice->language, voice->type);
817 __free_voice_list(voice_list);
819 SLOG(LOG_ERROR, get_tag(), "[Engine ERROR] Fail to get language list : result(%d)", ret);
820 return TTSD_ERROR_OPERATION_FAILED;
824 g_cur_engine.is_loaded = true;
829 int ttsd_engine_agent_unload_current_engine()
831 if (false == g_agent_init) {
832 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
833 return TTSD_ERROR_OPERATION_FAILED;
836 if (false == g_cur_engine.is_set) {
837 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No Current Engine ");
838 return TTSD_ERROR_OPERATION_FAILED;
841 if (false == g_cur_engine.is_loaded) {
842 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Engine has already been unloaded ");
846 /* shutdown engine */
848 ret = g_cur_engine.pefuncs->deinitialize();
850 SLOG(LOG_ERROR, get_tag(), "[Engine Agent] Fail deinitialize() : %s", __ttsd_get_engine_error_code(ret));
854 g_cur_engine.ttsp_unload_engine();
856 dlclose(g_cur_engine.handle);
858 /* reset current engine data */
859 g_cur_engine.handle = NULL;
860 g_cur_engine.is_loaded = false;
863 ttsvoice_s* data = NULL;
865 iter = g_slist_nth(g_cur_voices, 0);
866 while (NULL != iter) {
870 if (NULL != data->lang) free(data->lang);
871 g_cur_voices = g_slist_remove(g_cur_voices, data);
876 iter = g_slist_nth(g_cur_voices, 0);
882 bool ttsd_engine_agent_need_network()
884 if (false == g_agent_init) {
885 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
886 return TTSD_ERROR_OPERATION_FAILED;
889 if (false == g_cur_engine.is_loaded) {
890 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
891 return TTSD_ERROR_OPERATION_FAILED;
894 return g_cur_engine.need_network;
897 bool ttsd_engine_select_valid_voice(const char* lang, int type, char** out_lang, int* out_type)
899 if (NULL == lang || NULL == out_lang || NULL == out_type) {
903 if (false == g_cur_engine.is_loaded) {
904 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] Not loaded engine");
908 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Select voice : input lang(%s), input type(%d), default lang(%s), default type(%d)",
909 lang, type, g_cur_engine.default_lang, g_cur_engine.default_vctype);
911 /* case 1 : Both are default */
912 if (0 == strncmp(lang, "default", strlen("default")) && 0 == type) {
913 *out_lang = strdup(g_cur_engine.default_lang);
914 *out_type = g_cur_engine.default_vctype;
919 GList* voice_list = NULL;
922 ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, &voice_list);
923 if (0 != ret || 0 >= g_list_length(voice_list)) {
924 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
934 /* lang and type are not default type */
935 if (0 != strncmp(lang, "default", strlen("default")) && 0 != type) {
936 iter = g_list_first(voice_list);
938 while (NULL != iter) {
939 /* Get handle data from list */
942 if (0 == strncmp(voice->language, lang, strlen(lang)) && voice->type == type) {
943 *out_lang = strdup(voice->language);
944 *out_type = voice->type;
949 iter = g_list_next(iter);
952 } else if (0 != strncmp(lang, "default", strlen("default")) && 0 == type) {
953 /* Only type is default */
954 if (0 == strncmp(lang, g_cur_engine.default_lang, strlen(g_cur_engine.default_lang))) {
955 *out_lang = strdup(g_cur_engine.default_lang);
956 *out_type = g_cur_engine.default_vctype;
959 voice_s* voice_selected = NULL;
960 iter = g_list_first(voice_list);
961 while (NULL != iter) {
962 /* Get handle data from list */
965 if (0 == strncmp(voice->language, lang, strlen(lang))) {
966 voice_selected = voice;
967 if (voice->type == g_cur_engine.default_vctype) {
968 voice_selected = voice;
972 iter = g_list_next(iter);
975 if (NULL != voice_selected) {
976 *out_lang = strdup(voice_selected->language);
977 *out_type = voice_selected->type;
981 } else if (0 == strncmp(lang, "default", strlen("default")) && 0 != type) {
982 /* Only lang is default */
983 if (type == g_cur_engine.default_vctype) {
984 *out_lang = strdup(g_cur_engine.default_lang);
985 *out_type = g_cur_engine.default_vctype;
988 voice_s* voice_selected = NULL;
989 iter = g_list_first(voice_list);
990 while (NULL != iter) {
991 /* Get handle data from list */
994 if (0 == strncmp(voice->language, g_cur_engine.default_lang, strlen(g_cur_engine.default_lang))) {
995 voice_selected = voice;
996 if (voice->type == type) {
997 voice_selected = voice;
1001 iter = g_list_next(iter);
1004 if (NULL != voice_selected) {
1005 *out_lang = strdup(voice->language);
1006 *out_type = voice_selected->type;
1012 if (true == result) {
1013 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Selected voice : lang(%s), type(%d)", *out_lang, *out_type);
1016 __free_voice_list(voice_list);
1021 bool ttsd_engine_agent_is_same_engine(const char* engine_id)
1023 if (false == g_agent_init) {
1024 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1028 if (false == g_cur_engine.is_loaded) {
1029 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1033 /* compare current engine and engine id.*/
1034 if (0 == strncmp(g_cur_engine.engine_uuid, engine_id, strlen(engine_id))) {
1041 int ttsd_engine_agent_set_default_engine(const char* engine_id)
1043 if (false == g_agent_init) {
1044 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1045 return TTSD_ERROR_OPERATION_FAILED;
1048 /* compare current engine and new engine.*/
1049 if (0 == strncmp(g_cur_engine.engine_uuid, engine_id, strlen(engine_id))) {
1050 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] new engine(%s) is the same as current engine", engine_id);
1054 bool is_engine_loaded = false;
1055 char* tmp_uuid = NULL;
1056 tmp_uuid = strdup(g_cur_engine.engine_uuid);
1057 if (NULL == tmp_uuid) {
1058 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Current engine id is NULL");
1059 return TTSD_ERROR_OPERATION_FAILED;
1062 is_engine_loaded = g_cur_engine.is_loaded;
1064 if (true == is_engine_loaded) {
1066 if (0 != ttsd_engine_agent_unload_current_engine()) {
1067 SLOG(LOG_ERROR, get_tag(), "[Engine Agent Error] fail to unload current engine");
1071 /* change current engine */
1072 if (0 != __internal_set_current_engine(engine_id)) {
1073 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set current engine. Recovery origin engine");
1075 /* roll back to old current engine. */
1076 __internal_set_current_engine(tmp_uuid);
1077 if (true == is_engine_loaded) {
1078 ttsd_engine_agent_load_current_engine();
1081 if (tmp_uuid != NULL) free(tmp_uuid);
1082 return TTSD_ERROR_OPERATION_FAILED;
1085 if (true == is_engine_loaded) {
1087 if (0 != ttsd_engine_agent_load_current_engine()) {
1088 SLOG(LOG_ERROR, get_tag(), "[Engine Agent Error] Fail to load new engine. Recovery origin engine");
1090 /* roll back to old current engine. */
1091 __internal_set_current_engine(tmp_uuid);
1092 if (true == is_engine_loaded) {
1093 ttsd_engine_agent_load_current_engine();
1096 if (tmp_uuid != NULL) free(tmp_uuid);
1097 return TTSD_ERROR_OPERATION_FAILED;
1099 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] load new engine : %s", engine_id);
1103 if (tmp_uuid != NULL) free(tmp_uuid);
1107 int ttsd_engine_agent_set_default_voice(const char* language, int vctype)
1109 if (false == g_agent_init) {
1110 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1111 return TTSD_ERROR_OPERATION_FAILED;
1114 if (false == g_cur_engine.is_loaded) {
1115 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1116 return TTSD_ERROR_OPERATION_FAILED;
1119 if (false == g_cur_engine.pefuncs->is_valid_voice(language, vctype)) {
1120 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Voice is NOT valid !!");
1121 return TTSD_ERROR_INVALID_VOICE;
1125 GSList *iter = NULL;
1126 ttsvoice_s* data = NULL;
1128 /* Update new default voice info */
1129 iter = g_slist_nth(g_cur_voices, 0);
1130 while (NULL != iter) {
1131 /* Get handle data from list */
1135 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Voice data is NULL");
1136 return TTSD_ERROR_OPERATION_FAILED;
1139 if (0 == strcmp(data->lang, language) && data->type == vctype) {
1140 data->is_default = true;
1141 if (0 == data->client_ref_count) {
1143 if (NULL != g_cur_engine.pefuncs->load_voice) {
1144 ret = g_cur_engine.pefuncs->load_voice(data->lang, data->type);
1146 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] load voice : lang(%s), type(%d)",
1147 data->lang, data->type);
1148 data->is_loaded = true;
1150 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
1151 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1154 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Load voice of engine function is NULL");
1161 iter = g_slist_next(iter);
1164 #ifdef ENGINE_AGENT_DEBUG
1165 ttsd_print_voicelist();
1168 /* Update old default voice info */
1169 iter = g_slist_nth(g_cur_voices, 0);
1170 while (NULL != iter) {
1171 /*Get handle data from list*/
1175 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Voice data is NULL");
1176 return TTSD_ERROR_OPERATION_FAILED;
1179 if (0 == strcmp(data->lang, g_cur_engine.default_lang) && data->type == g_cur_engine.default_vctype) {
1180 data->is_default = false;
1181 if (0 == data->client_ref_count) {
1183 if (NULL != g_cur_engine.pefuncs->unload_voice) {
1184 ret = g_cur_engine.pefuncs->unload_voice(data->lang, data->type);
1186 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
1187 data->lang, data->type);
1188 data->is_loaded = false;
1190 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
1191 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1194 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Unload voice of engine function is NULL");
1201 iter = g_slist_next(iter);
1204 if (NULL != g_cur_engine.default_lang) free(g_cur_engine.default_lang);
1206 g_cur_engine.default_lang = strdup(language);
1207 g_cur_engine.default_vctype = vctype;
1209 #ifdef ENGINE_AGENT_DEBUG
1210 ttsd_print_voicelist();
1213 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set default voice : lang(%s), type(%d)",
1214 g_cur_engine.default_lang, g_cur_engine.default_vctype);
1219 int ttsd_engine_agent_set_default_speed(int speed)
1221 if (false == g_agent_init) {
1222 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1223 return TTSD_ERROR_OPERATION_FAILED;
1226 g_cur_engine.default_speed = speed;
1231 int ttsd_engine_agent_set_default_pitch(int pitch)
1233 if (false == g_agent_init) {
1234 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1235 return TTSD_ERROR_OPERATION_FAILED;
1238 if (false == g_cur_engine.is_loaded) {
1239 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1240 return TTSD_ERROR_OPERATION_FAILED;
1243 if (NULL == g_cur_engine.pefuncs->set_pitch) {
1244 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not support pitch");
1245 return TTSD_ERROR_OPERATION_FAILED;
1248 int ret = g_cur_engine.pefuncs->set_pitch(pitch);
1250 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)",
1251 pitch, __ttsd_get_engine_error_code(ret));
1252 return TTSD_ERROR_OPERATION_FAILED;
1255 g_cur_engine.default_pitch = pitch;
1260 /******************************************************************************************
1261 * TTS Engine Interfaces for client
1262 *******************************************************************************************/
1264 int ttsd_engine_load_voice(const char* lang, const int vctype)
1266 /* 1. Find voice info */
1268 GSList *iter = NULL;
1269 ttsvoice_s* data = NULL;
1271 iter = g_slist_nth(g_cur_voices, 0);
1272 while (NULL != iter) {
1273 /*Get handle data from list*/
1277 if (0 == strcmp(data->lang, lang) && data->type == vctype) {
1278 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1279 data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1285 iter = g_slist_next(iter);
1290 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
1291 return TTSD_ERROR_OPERATION_FAILED;
1294 /* 2. increse ref count */
1295 data->client_ref_count++;
1297 /* 3. if ref count change 0 to 1 and not default, load voice */
1298 if (1 == data->client_ref_count && false == data->is_default) {
1300 if (NULL != g_cur_engine.pefuncs->load_voice) {
1301 ret = g_cur_engine.pefuncs->load_voice(data->lang, data->type);
1303 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Load voice : lang(%s), type(%d)",
1304 data->lang, data->type);
1305 data->is_loaded = true;
1307 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
1308 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1310 return TTSD_ERROR_OPERATION_FAILED;
1313 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Load voice of engine function is NULL");
1316 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Not load voice : default voice(%d) or ref count(%d)",
1317 data->is_default, data->client_ref_count);
1320 #ifdef ENGINE_AGENT_DEBUG
1321 ttsd_print_voicelist();
1327 int ttsd_engine_unload_voice(const char* lang, const int vctype)
1329 /* 1. Find voice info */
1331 GSList *iter = NULL;
1332 ttsvoice_s* data = NULL;
1334 iter = g_slist_nth(g_cur_voices, 0);
1335 while (NULL != iter) {
1336 /*Get handle data from list*/
1340 if (0 == strcmp(data->lang, lang) && data->type == vctype) {
1341 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1342 data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1348 iter = g_slist_next(iter);
1353 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
1354 return TTSD_ERROR_OPERATION_FAILED;
1357 /* 2. Decrese ref count */
1358 data->client_ref_count--;
1360 /* 3. if ref count change 0 and not default, load voice */
1361 if (0 == data->client_ref_count && false == data->is_default) {
1363 if (NULL != g_cur_engine.pefuncs->unload_voice) {
1364 ret = g_cur_engine.pefuncs->unload_voice(data->lang, data->type);
1366 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
1367 data->lang, data->type);
1368 data->is_loaded = false;
1370 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
1371 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1373 return TTSD_ERROR_OPERATION_FAILED;
1376 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Unload voice of engine function is NULL");
1379 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Not unload voice : default voice(%d) or ref count(%d)",
1380 data->is_default, data->client_ref_count);
1383 #ifdef ENGINE_AGENT_DEBUG
1384 ttsd_print_voicelist();
1389 int ttsd_engine_start_synthesis(const char* lang, int vctype, const char* text, int speed, void* user_param)
1391 if (false == g_agent_init) {
1392 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1393 return TTSD_ERROR_OPERATION_FAILED;
1396 if (false == g_cur_engine.is_loaded) {
1397 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1398 return TTSD_ERROR_OPERATION_FAILED;
1401 /* select voice for default */
1402 char* temp_lang = NULL;
1404 if (true != ttsd_engine_select_valid_voice(lang, vctype, &temp_lang, &temp_type)) {
1405 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to select default voice");
1406 if (NULL != temp_lang) free(temp_lang);
1407 return TTSD_ERROR_INVALID_VOICE;
1409 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Start synthesis : language(%s), type(%d), speed(%d), text(%s)",
1410 temp_lang, temp_type, speed, text);
1413 if (NULL == g_cur_engine.pefuncs->start_synth) {
1414 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] start_synth() of engine is NULL!!");
1415 if (NULL != temp_lang) free(temp_lang);
1416 return TTSD_ERROR_OPERATION_FAILED;
1422 temp_speed = g_cur_engine.default_speed;
1427 /* synthesize text */
1429 ret = g_cur_engine.pefuncs->start_synth(temp_lang, temp_type, text, temp_speed, user_param);
1431 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] ***************************************");
1432 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] * synthesize error : %s *", __ttsd_get_engine_error_code(ret));
1433 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] ***************************************");
1434 if (NULL != temp_lang) free(temp_lang);
1435 return TTSD_ERROR_OPERATION_FAILED;
1438 if (NULL != temp_lang) free(temp_lang);
1442 int ttsd_engine_cancel_synthesis()
1444 if (false == g_agent_init) {
1445 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1446 return TTSD_ERROR_OPERATION_FAILED;
1449 if (false == g_cur_engine.is_loaded) {
1450 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1451 return TTSD_ERROR_OPERATION_FAILED;
1454 if (NULL == g_cur_engine.pefuncs->cancel_synth) {
1455 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] cancel_synth() of engine is NULL!!");
1456 return TTSD_ERROR_OPERATION_FAILED;
1459 /* stop synthesis */
1461 ret = g_cur_engine.pefuncs->cancel_synth();
1463 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail cancel synthesis : %s", __ttsd_get_engine_error_code(ret));
1464 return TTSD_ERROR_OPERATION_FAILED;
1470 bool __supported_voice_cb(const char* language, int type, void* user_data)
1472 GList** voice_list = (GList**)user_data;
1474 if (NULL == language || NULL == voice_list) {
1475 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
1479 voice_s* voice = calloc(1, sizeof(voice_s));
1480 voice->language = strdup(language);
1483 *voice_list = g_list_append(*voice_list, voice);
1488 int ttsd_engine_get_voice_list(GList** voice_list)
1490 if (false == g_agent_init) {
1491 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1492 return TTSD_ERROR_OPERATION_FAILED;
1495 if (false == g_cur_engine.is_loaded) {
1496 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1497 return TTSD_ERROR_OPERATION_FAILED;
1501 ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, (void*)voice_list);
1503 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to get voice list : %s", __ttsd_get_engine_error_code(ret));
1504 return TTSD_ERROR_OPERATION_FAILED;
1510 int ttsd_engine_get_default_voice(char** lang, int* vctype)
1512 if (false == g_agent_init) {
1513 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1514 return TTSD_ERROR_OPERATION_FAILED;
1517 if (false == g_cur_engine.is_loaded) {
1518 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1519 return TTSD_ERROR_OPERATION_FAILED;
1522 if (NULL == lang || NULL == vctype) {
1523 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] BAD Parameter");
1524 return TTSD_ERROR_INVALID_PARAMETER;
1527 if (NULL != g_cur_engine.default_lang) {
1528 *lang = strdup(g_cur_engine.default_lang);
1529 *vctype = g_cur_engine.default_vctype;
1531 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine] Get default voice : language(%s), type(%d)", *lang, *vctype);
1533 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Default voice is NULL");
1534 return TTSD_ERROR_OPERATION_FAILED;
1540 void __free_voice_list(GList* voice_list)
1543 voice_s* data = NULL;
1545 /* if list have item */
1546 if (g_list_length(voice_list) > 0) {
1547 /* Get a first item */
1548 iter = g_list_first(voice_list);
1550 while (NULL != iter) {
1554 if (NULL != data->language) free(data->language);
1558 voice_list = g_list_remove_link(voice_list, iter);
1560 iter = g_list_first(voice_list);
1566 * TTS Engine Callback Functions ` *
1568 bool __result_cb(ttsp_result_event_e event, const void* data, unsigned int data_size, ttsp_audio_type_e audio_type, int rate, void *user_data)
1570 g_result_cb(event, data, data_size, audio_type, rate, user_data);
1574 /* function for debugging */
1575 int ttsd_print_enginelist()
1578 ttsengine_info_s *data = NULL;
1580 if (g_list_length(g_engine_list) > 0) {
1581 iter = g_list_first(g_engine_list);
1583 SLOG(LOG_DEBUG, get_tag(), "----- engine list -----");
1586 while (NULL != iter) {
1589 SECURE_SLOG(LOG_DEBUG, get_tag(), "[%dth]", i);
1590 SECURE_SLOG(LOG_DEBUG, get_tag(), "engine uuid : %s", data->engine_uuid);
1591 SECURE_SLOG(LOG_DEBUG, get_tag(), "engine name : %s", data->engine_name);
1592 SECURE_SLOG(LOG_DEBUG, get_tag(), "engine path : %s", data->engine_path);
1593 SECURE_SLOG(LOG_DEBUG, get_tag(), "setting ug path : %s", data->setting_ug_path);
1595 iter = g_list_next(iter);
1598 SLOG(LOG_DEBUG, get_tag(), "-----------------------");
1599 SLOG(LOG_DEBUG, get_tag(), " ");
1601 SLOG(LOG_DEBUG, get_tag(), "----- engine list -----");
1602 SLOG(LOG_DEBUG, get_tag(), "No Engine in directory");
1603 SLOG(LOG_DEBUG, get_tag(), "-----------------------");
1609 int ttsd_print_voicelist()
1612 GSList *iter = NULL;
1613 ttsvoice_s* data = NULL;
1615 SLOG(LOG_DEBUG, get_tag(), "=== Voice list ===");
1617 if (g_slist_length(g_cur_voices) > 0) {
1618 /* Get a first item */
1619 iter = g_slist_nth(g_cur_voices, 0);
1622 while (NULL != iter) {
1623 /*Get handle data from list*/
1626 if (NULL == data || NULL == data->lang) {
1627 SLOG(LOG_ERROR, get_tag(), "[ERROR] Data is invalid");
1631 SLOG(LOG_DEBUG, get_tag(), "[%dth] default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1632 i, data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1635 iter = g_slist_next(iter);
1640 SLOG(LOG_DEBUG, get_tag(), "==================");