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;
73 static bool g_agent_init;
75 /** TTS engine list */
76 static GList *g_engine_list;
78 /** Current engine information */
79 static ttsengine_s g_cur_engine;
81 /** Current voice information */
82 static GSList* g_cur_voices;
84 /** Result callback function */
85 static synth_result_callback g_result_cb;
88 /** Set current engine */
89 int __internal_set_current_engine(const char* engine_uuid);
91 /** Check engine id */
92 int __internal_check_engine_id(const char* engine_uuid);
94 /** Update engine list */
95 int __internal_update_engine_list();
97 /** Get engine info */
98 int __internal_get_engine_info(const char* filepath, ttsengine_info_s** info);
100 /** Callback function for result */
101 bool __result_cb(ttsp_result_event_e event, const void* data, unsigned int data_size,
102 ttsp_audio_type_e audio_type, int rate, void *user_data);
104 /** Callback function for voice list */
105 bool __supported_voice_cb(const char* language, int type, void* user_data);
107 /** Free voice list */
108 void __free_voice_list(GList* voice_list);
110 /** Callback function for engine info */
111 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* setting_ug_name,
112 bool use_network, void* user_data);
114 /** Callback fucntion for engine setting */
115 bool __engine_setting_cb(const char* key, const char* value, void* user_data);
119 int ttsd_print_enginelist();
121 int ttsd_print_voicelist();
123 static const char* __ttsd_get_engine_error_code(ttsp_error_e err)
126 case TTSP_ERROR_NONE: return "TTSP_ERROR_NONE";
127 case TTSP_ERROR_OUT_OF_MEMORY: return "TTSP_ERROR_OUT_OF_MEMORY";
128 case TTSP_ERROR_IO_ERROR: return "TTSP_ERROR_IO_ERROR";
129 case TTSP_ERROR_INVALID_PARAMETER: return "TTSP_ERROR_INVALID_PARAMETER";
130 case TTSP_ERROR_OUT_OF_NETWORK: return "TTSP_ERROR_OUT_OF_NETWORK";
131 case TTSP_ERROR_INVALID_STATE: return "TTSP_ERROR_INVALID_STATE";
132 case TTSP_ERROR_INVALID_VOICE: return "TTSP_ERROR_INVALID_VOICE";
133 case TTSP_ERROR_OPERATION_FAILED: return "TTSP_ERROR_OPERATION_FAILED";
135 return "Invalid error code";
139 int ttsd_engine_agent_init(synth_result_callback result_cb)
141 /* initialize static data */
142 if (result_cb == NULL) {
143 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] invalid parameter");
144 return TTSD_ERROR_INVALID_PARAMETER;
147 g_result_cb = result_cb;
149 g_cur_engine.engine_uuid = NULL;
150 g_cur_engine.engine_name = NULL;
151 g_cur_engine.engine_path = NULL;
153 g_cur_engine.is_set = false;
154 g_cur_engine.handle = NULL;
155 g_cur_engine.pefuncs = (ttspe_funcs_s*)calloc(1, sizeof(ttspe_funcs_s));
156 g_cur_engine.pdfuncs = (ttspd_funcs_s*)calloc(1, sizeof(ttspd_funcs_s));
160 if (0 != ttsd_config_get_default_voice(&(g_cur_engine.default_lang), &(g_cur_engine.default_vctype))) {
161 SLOG(LOG_WARN, get_tag(), "[Server WARNING] There is No default voice in config");
162 /* Set default voice */
163 g_cur_engine.default_lang = strdup(TTS_BASE_LANGUAGE);
164 g_cur_engine.default_vctype = TTSP_VOICE_TYPE_FEMALE;
167 if (0 != ttsd_config_get_default_speed(&(g_cur_engine.default_speed))) {
168 SLOG(LOG_WARN, get_tag(), "[Server WARNING] There is No default speed in config");
169 g_cur_engine.default_speed = TTS_SPEED_NORMAL;
172 if (0 != ttsd_config_get_default_pitch(&(g_cur_engine.default_pitch))) {
173 SLOG(LOG_WARN, get_tag(), "[Server WARNING] There is No default pitch in config");
174 g_cur_engine.default_pitch = TTS_PITCH_NORMAL;
177 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Initialize Engine Agent");
182 int ttsd_engine_agent_release()
184 if (false == g_agent_init) {
185 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
186 return TTSD_ERROR_OPERATION_FAILED;
189 /* unload current engine */
190 ttsd_engine_agent_unload_current_engine();
192 /* release engine list */
194 ttsengine_info_s *data = NULL;
196 if (g_list_length(g_engine_list) > 0) {
197 /* Get a first item */
198 iter = g_list_first(g_engine_list);
199 while (NULL != iter) {
200 /* Get data from item */
202 iter = g_list_remove(iter, data);
205 if (NULL != data->engine_uuid) free(data->engine_uuid);
206 if (NULL != data->engine_name) free(data->engine_name);
207 if (NULL != data->setting_ug_path) free(data->setting_ug_path);
208 if (NULL != data->engine_path) free(data->engine_path);
215 /* release current engine data */
216 if (g_cur_engine.engine_uuid != NULL) free(g_cur_engine.engine_uuid);
217 if (g_cur_engine.engine_name != NULL) free(g_cur_engine.engine_name);
218 if (g_cur_engine.engine_path != NULL) free(g_cur_engine.engine_path);
220 if (g_cur_engine.pefuncs != NULL) free(g_cur_engine.pefuncs);
221 if (g_cur_engine.pdfuncs != NULL) free(g_cur_engine.pdfuncs);
222 if (g_cur_engine.default_lang != NULL) free(g_cur_engine.default_lang);
224 g_agent_init = false;
226 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Release Engine Agent");
231 int ttsd_engine_agent_initialize_current_engine()
233 if (false == g_agent_init) {
234 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized" );
235 return TTSD_ERROR_OPERATION_FAILED;
238 /* update engine list */
239 if (0 != __internal_update_engine_list()) {
240 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] No engine error");
241 return TTSD_ERROR_OPERATION_FAILED;
244 /* 2. get current engine from config */
245 char* cur_engine_uuid = NULL;
246 bool is_get_engineid_from_config = false;
248 if (0 != ttsd_config_get_default_engine(&cur_engine_uuid)) {
249 /*not set current engine */
250 /*set system default engine*/
252 ttsengine_info_s *data = NULL;
254 if (g_list_length(g_engine_list) > 0) {
255 iter = g_list_first(g_engine_list);
259 if (NULL != data->engine_uuid) {
260 cur_engine_uuid = strdup(data->engine_uuid);
261 ttsd_config_set_default_engine(cur_engine_uuid);
263 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Data of current engine is corrupt");
264 return TTSD_ERROR_OPERATION_FAILED;
268 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] Fail to set a engine of engine list");
269 return TTSD_ERROR_OPERATION_FAILED;
272 is_get_engineid_from_config = false;
274 is_get_engineid_from_config = true;
277 if (NULL == cur_engine_uuid) {
278 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Current engine id is NULL");
279 return TTSD_ERROR_OPERATION_FAILED;
282 /* check whether cur engine uuid is valid or not. */
283 if (0 != __internal_check_engine_id(cur_engine_uuid)) {
284 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] It is not valid engine id from config");
288 if (g_list_length(g_engine_list) > 0)
289 iter = g_list_first(g_engine_list);
291 SLOG(LOG_WARN, get_tag(), "[Engine Agent ERROR] NO TTS Engine !!");
292 if (NULL != cur_engine_uuid) free(cur_engine_uuid);
293 return TTSD_ERROR_OPERATION_FAILED;
296 if (cur_engine_uuid != NULL) free(cur_engine_uuid);
297 ttsengine_info_s *data = NULL;
300 cur_engine_uuid = strdup(data->engine_uuid);
302 is_get_engineid_from_config = false;
305 if (NULL != cur_engine_uuid)
306 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Current Engine Id : %s", cur_engine_uuid);
308 return TTSD_ERROR_OPERATION_FAILED;
310 /* set current engine */
311 if (0 != __internal_set_current_engine(cur_engine_uuid)) {
312 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to set current engine ");
313 if (NULL != cur_engine_uuid) free(cur_engine_uuid);
314 return TTSD_ERROR_OPERATION_FAILED;
317 if (false == is_get_engineid_from_config) {
318 if (0 != ttsd_config_set_default_engine(cur_engine_uuid)) {
319 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to set id to config");
323 if (NULL != cur_engine_uuid) free(cur_engine_uuid);
325 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set current engine");
330 int __internal_check_engine_id(const char* engine_uuid)
333 ttsengine_s *data = NULL;
335 if (g_list_length(g_engine_list) > 0) {
336 iter = g_list_first(g_engine_list);
338 while (NULL != iter) {
341 if (0 == strncmp(engine_uuid, data->engine_uuid, strlen(data->engine_uuid)))
344 iter = g_list_next(iter);
351 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* setting_ug_name,
352 bool use_network, void* user_data)
354 ttsengine_info_s* temp = (ttsengine_info_s*)user_data;
356 if (NULL != engine_uuid)
357 temp->engine_uuid = strdup(engine_uuid);
359 if (NULL != engine_name)
360 temp->engine_name = strdup(engine_name);
362 if (NULL != setting_ug_name)
363 temp->setting_ug_path = strdup(setting_ug_name);
365 temp->use_network = use_network;
369 int __internal_get_engine_info(const char* filepath, ttsengine_info_s** info)
374 handle = dlopen(filepath, RTLD_LAZY);
377 SECURE_SLOG(LOG_WARN, get_tag(), "[Engine Agent] Invalid engine : %s", filepath);
378 return TTSD_ERROR_OPERATION_FAILED;
381 /* link engine to daemon */
382 dlsym(handle, "ttsp_load_engine");
383 if ((error = dlerror()) != NULL) {
384 SECURE_SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to open ttsp_load_engine : path(%s) message(%s)", filepath, error);
386 return TTSD_ERROR_OPERATION_FAILED;
389 dlsym(handle, "ttsp_unload_engine");
390 if ((error = dlerror()) != NULL) {
391 SECURE_SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to open ttsp_unload_engine : path(%s) message(%s)", filepath, error);
393 return TTSD_ERROR_OPERATION_FAILED;
396 int (*get_engine_info)(ttsp_engine_info_cb callback, void* user_data);
398 get_engine_info = (int (*)(ttsp_engine_info_cb, void*))dlsym(handle, "ttsp_get_engine_info");
399 if (NULL != (error = dlerror()) || NULL == get_engine_info) {
400 SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to open ttsp_get_engine_info() :path(%s) message(%s)", filepath, error);
402 return TTSD_ERROR_OPERATION_FAILED;
405 ttsengine_info_s* temp;
406 temp = (ttsengine_info_s*)calloc(1, sizeof(ttsengine_info_s));
408 SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to alloc memory");
410 return TTSD_ERROR_OUT_OF_MEMORY;
413 /* get engine info */
414 if (0 != get_engine_info(&__engine_info_cb, (void*)temp)) {
415 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to get engine info");
418 return TTSD_ERROR_OPERATION_FAILED;
424 if (TTSD_MODE_SCREEN_READER == ttsd_get_mode() && true == temp->use_network) {
425 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent WARNING] %s is invalid because of network based", temp->engine_name);
426 if (NULL != temp->engine_uuid) free(temp->engine_uuid);
427 if (NULL != temp->engine_name) free(temp->engine_name);
428 if (NULL != temp->setting_ug_path) free(temp->setting_ug_path);
430 return TTSD_ERROR_OPERATION_FAILED;
433 temp->engine_path = strdup(filepath);
435 SLOG(LOG_DEBUG, get_tag(), "----- Valid engine");
436 SECURE_SLOG(LOG_DEBUG, get_tag(), "Engine uuid : %s", temp->engine_uuid);
437 SECURE_SLOG(LOG_DEBUG, get_tag(), "Engine name : %s", temp->engine_name);
438 SECURE_SLOG(LOG_DEBUG, get_tag(), "Setting path : %s", temp->setting_ug_path);
439 SECURE_SLOG(LOG_DEBUG, get_tag(), "Engine path : %s", temp->engine_path);
440 SECURE_SLOG(LOG_DEBUG, get_tag(), "Use network : %s", temp->use_network ? "true":"false");
441 SLOG(LOG_DEBUG, get_tag(), "-----");
442 SLOG(LOG_DEBUG, get_tag(), " ");
449 int __internal_update_engine_list()
451 /* relsease engine list */
453 ttsengine_info_s *data = NULL;
455 if (g_list_length(g_engine_list) > 0) {
456 iter = g_list_first(g_engine_list);
458 while (NULL != iter) {
461 if (data != NULL) free(data);
462 g_engine_list = g_list_remove_link(g_engine_list, iter);
463 iter = g_list_first(g_engine_list);
467 /* get file name from engine directory and get engine information from each filename */
470 dp = opendir(TTS_DEFAULT_ENGINE);
473 while ((dirp = readdir(dp)) != NULL) {
474 ttsengine_info_s* info;
475 char* filepath = NULL;
478 file_size = strlen(TTS_DEFAULT_ENGINE) + strlen(dirp->d_name) + 5;
479 filepath = (char*)calloc(file_size, sizeof(char));
481 if (NULL != filepath) {
482 snprintf(filepath, file_size, "%s/%s", TTS_DEFAULT_ENGINE, dirp->d_name);
484 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not enough memory!!" );
488 /* get its info and update engine list */
489 if (0 == __internal_get_engine_info(filepath, &info)) {
490 /* add engine info to g_engine_list */
491 g_engine_list = g_list_append(g_engine_list, info);
494 if (NULL != filepath) free(filepath);
500 dp = opendir(TTS_DOWNLOAD_ENGINE);
503 while ((dirp = readdir(dp)) != NULL) {
504 ttsengine_info_s* info;
505 char* filepath = NULL;
508 file_size = strlen(TTS_DOWNLOAD_ENGINE) + strlen(dirp->d_name) + 5;
509 filepath = (char*)calloc(file_size, sizeof(char));
511 if (NULL != filepath) {
512 snprintf(filepath, file_size, "%s/%s", TTS_DOWNLOAD_ENGINE, dirp->d_name);
514 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not enough memory!!" );
518 /* get its info and update engine list */
519 if (0 == __internal_get_engine_info(filepath, &info)) {
520 /* add engine info to g_engine_list */
521 g_engine_list = g_list_append(g_engine_list, info);
524 if (NULL != filepath) free(filepath);
530 if (g_list_length(g_engine_list) <= 0) {
531 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No Engine");
532 return TTSD_ERROR_OPERATION_FAILED;
535 #ifdef ENGINE_AGENT_DEBUG
536 ttsd_print_enginelist();
541 int __internal_set_current_engine(const char* engine_uuid)
543 /* check whether engine id is valid or not. */
545 ttsengine_info_s *data = NULL;
548 if (g_list_length(g_engine_list) > 0) {
549 iter = g_list_first(g_engine_list);
551 while (NULL != iter) {
554 if (0 == strncmp(data->engine_uuid, engine_uuid, strlen(engine_uuid))) {
560 iter = g_list_next(iter);
564 /* If current engine does not exist, return error */
566 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Cannot find engine id");
567 return TTSD_ERROR_OPERATION_FAILED;
569 if (g_cur_engine.engine_uuid != NULL) {
570 /*compare current engine uuid */
571 if (0 == strncmp(g_cur_engine.engine_uuid, data->engine_uuid, strlen(engine_uuid))) {
572 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] tts engine has already been set");
578 /* set data from g_engine_list */
579 if (g_cur_engine.engine_uuid != NULL) free(g_cur_engine.engine_uuid);
580 if (g_cur_engine.engine_name != NULL) free(g_cur_engine.engine_name);
581 if (g_cur_engine.engine_path != NULL) free(g_cur_engine.engine_path);
583 if (NULL == data->engine_uuid || NULL == data->engine_name || NULL == data->engine_path) {
584 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Engine data is NULL");
585 return TTSD_ERROR_OPERATION_FAILED;
588 g_cur_engine.engine_uuid = strdup(data->engine_uuid);
589 g_cur_engine.engine_name = strdup(data->engine_name);
590 g_cur_engine.engine_path = strdup(data->engine_path);
592 g_cur_engine.handle = NULL;
593 g_cur_engine.is_loaded = false;
594 g_cur_engine.is_set = true;
595 g_cur_engine.need_network = data->use_network;
597 SLOG(LOG_DEBUG, get_tag(), "-----");
598 SECURE_SLOG(LOG_DEBUG, get_tag(), "Current engine uuid : %s", g_cur_engine.engine_uuid);
599 SECURE_SLOG(LOG_DEBUG, get_tag(), "Current engine name : %s", g_cur_engine.engine_name);
600 SECURE_SLOG(LOG_DEBUG, get_tag(), "Current engine path : %s", g_cur_engine.engine_path);
601 SLOG(LOG_DEBUG, get_tag(), "-----");
606 bool __set_voice_info_cb(const char* language, int type, void* user_data)
608 if (NULL == language) {
609 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
613 ttsvoice_s* voice = calloc(1, sizeof(ttsvoice_s));
614 voice->lang = strdup(language);
617 voice->client_ref_count = 0;
618 voice->is_loaded = false;
620 if (0 == strcmp(g_cur_engine.default_lang, language) && g_cur_engine.default_vctype == type) {
621 voice->is_default = true;
622 voice->is_loaded = true;
624 voice->is_default = false;
627 g_cur_voices = g_slist_append(g_cur_voices, voice);
632 int __update_voice_list()
638 ret = g_cur_engine.pefuncs->foreach_voices(__set_voice_info_cb, NULL);
639 if (0 != ret || 0 >= g_slist_length(g_cur_voices)) {
640 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
644 #ifdef ENGINE_AGENT_DEBUG
645 ttsd_print_voicelist();
650 int ttsd_engine_agent_load_current_engine()
652 if (false == g_agent_init) {
653 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized" );
654 return TTSD_ERROR_OPERATION_FAILED;
657 if (false == g_cur_engine.is_set) {
658 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No Current Engine ");
659 return TTSD_ERROR_OPERATION_FAILED;
662 /* check whether current engine is loaded or not */
663 if (true == g_cur_engine.is_loaded ) {
664 SLOG(LOG_ERROR, get_tag(), "[Engine Agent] Engine has already been loaded " );
670 g_cur_engine.handle = dlopen(g_cur_engine.engine_path, RTLD_LAZY); /* RTLD_LAZY RTLD_NOW*/
672 if (NULL != (error = dlerror()) || NULL == g_cur_engine.handle) {
673 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to get current engine handle : %s", error);
677 g_cur_engine.ttsp_unload_engine = (int (*)())dlsym(g_cur_engine.handle, "ttsp_unload_engine");
678 if (NULL != (error = dlerror()) || NULL == g_cur_engine.ttsp_unload_engine) {
679 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to link daemon to ttsp_unload_engine() : %s", error);
683 g_cur_engine.ttsp_load_engine = (int (*)(const ttspd_funcs_s* , ttspe_funcs_s*) )dlsym(g_cur_engine.handle, "ttsp_load_engine");
684 if (NULL != (error = dlerror()) || NULL == g_cur_engine.ttsp_load_engine) {
685 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to link daemon to ttsp_load_engine() : %s", error);
690 g_cur_engine.pdfuncs->version = 1;
691 g_cur_engine.pdfuncs->size = sizeof(ttspd_funcs_s);
694 ret = g_cur_engine.ttsp_load_engine(g_cur_engine.pdfuncs, g_cur_engine.pefuncs);
696 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to load engine - %s : result(%s)",
697 g_cur_engine.engine_path, __ttsd_get_engine_error_code(ret));
698 return TTSD_ERROR_OPERATION_FAILED;
701 /* engine error check */
702 if (g_cur_engine.pefuncs->size != sizeof(ttspe_funcs_s)) {
703 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] The size of engine function is not valid");
706 if (NULL == g_cur_engine.pefuncs->initialize ||
707 NULL == g_cur_engine.pefuncs->deinitialize ||
708 NULL == g_cur_engine.pefuncs->foreach_voices ||
709 NULL == g_cur_engine.pefuncs->is_valid_voice ||
710 NULL == g_cur_engine.pefuncs->start_synth ||
711 NULL == g_cur_engine.pefuncs->cancel_synth) {
712 SLOG(LOG_ERROR, get_tag(), "[Engine ERROR] The engine functions are NOT valid");
713 return TTSD_ERROR_OPERATION_FAILED;
716 ret = g_cur_engine.pefuncs->initialize(__result_cb);
718 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to initialize current engine : %s", __ttsd_get_engine_error_code(ret));
719 return TTSD_ERROR_OPERATION_FAILED;
722 /* Get voice info of current engine */
723 ret = __update_voice_list();
725 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set voice info : result(%d)", ret);
726 return TTSD_ERROR_OPERATION_FAILED;
729 /* Select default voice */
730 if (NULL != g_cur_engine.default_lang) {
731 if (true == g_cur_engine.pefuncs->is_valid_voice(g_cur_engine.default_lang, g_cur_engine.default_vctype)) {
732 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set origin default voice to current engine : lang(%s), type(%d)",
733 g_cur_engine.default_lang, g_cur_engine.default_vctype);
735 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] Fail set origin default voice : lang(%s), type(%d)",
736 g_cur_engine.default_lang, g_cur_engine.default_vctype);
738 return TTSD_ERROR_OPERATION_FAILED;
742 /* load default voice */
743 if (NULL != g_cur_engine.pefuncs->load_voice) {
744 ret = g_cur_engine.pefuncs->load_voice(g_cur_engine.default_lang, g_cur_engine.default_vctype);
746 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Load default voice : lang(%s), type(%d)",
747 g_cur_engine.default_lang, g_cur_engine.default_vctype);
749 SLOG(LOG_WARN, get_tag(), "[Engine Agent ERROR] Fail to load default voice : lang(%s), type(%d) result(%s)",
750 g_cur_engine.default_lang, g_cur_engine.default_vctype, __ttsd_get_engine_error_code(ret));
752 return TTSD_ERROR_OPERATION_FAILED;
757 if (false == set_voice) {
758 /* get language list */
760 GList* voice_list = NULL;
762 ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, &voice_list);
764 if (0 == ret && 0 < g_list_length(voice_list)) {
766 voice_s* voice = NULL;
768 iter = g_list_first(voice_list);
771 while (NULL != iter) {
775 if (0 == strcmp("en_US", voice->language))
779 iter = g_list_next(iter);
782 SLOG(LOG_ERROR, get_tag(), "[Engine ERROR] Fail to find voice in list");
783 return TTSD_ERROR_OPERATION_FAILED;
786 /* Set selected language and type */
787 if (true != g_cur_engine.pefuncs->is_valid_voice(voice->language, voice->type)) {
788 SLOG(LOG_ERROR, get_tag(), "[Engine ERROR] Fail voice is NOT valid");
789 return TTSD_ERROR_OPERATION_FAILED;
792 ttsd_config_set_default_voice(voice->language, (int)voice->type);
794 g_cur_engine.default_lang = strdup(voice->language);
795 g_cur_engine.default_vctype = voice->type;
797 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Select default voice : lang(%s), type(%d)",
798 voice->language, voice->type);
800 __free_voice_list(voice_list);
802 SLOG(LOG_ERROR, get_tag(), "[Engine ERROR] Fail to get language list : result(%d)", ret);
803 return TTSD_ERROR_OPERATION_FAILED;
807 g_cur_engine.is_loaded = true;
812 int ttsd_engine_agent_unload_current_engine()
814 if (false == g_agent_init) {
815 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized" );
816 return TTSD_ERROR_OPERATION_FAILED;
819 if (false == g_cur_engine.is_set) {
820 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No Current Engine ");
821 return TTSD_ERROR_OPERATION_FAILED;
824 if (false == g_cur_engine.is_loaded) {
825 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Engine has already been unloaded " );
829 /* shutdown engine */
831 ret = g_cur_engine.pefuncs->deinitialize();
833 SLOG(LOG_ERROR, get_tag(), "[Engine Agent] Fail deinitialize() : %s", __ttsd_get_engine_error_code(ret));
837 g_cur_engine.ttsp_unload_engine();
839 dlclose(g_cur_engine.handle);
841 /* reset current engine data */
842 g_cur_engine.handle = NULL;
843 g_cur_engine.is_loaded = false;
846 ttsvoice_s* data = NULL;
848 iter = g_slist_nth(g_cur_voices, 0);
849 while (NULL != iter) {
853 if (NULL != data->lang) free(data->lang);
854 g_cur_voices = g_slist_remove(g_cur_voices, data);
859 iter = g_slist_nth(g_cur_voices, 0);
865 bool ttsd_engine_agent_need_network()
867 if (false == g_agent_init) {
868 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized" );
869 return TTSD_ERROR_OPERATION_FAILED;
872 if (false == g_cur_engine.is_loaded) {
873 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
874 return TTSD_ERROR_OPERATION_FAILED;
877 return g_cur_engine.need_network;
880 bool ttsd_engine_select_valid_voice(const char* lang, int type, char** out_lang, int* out_type)
882 if (NULL == lang || NULL == out_lang || NULL == out_type) {
886 if (false == g_cur_engine.is_loaded) {
887 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] Not loaded engine");
891 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Select voice : input lang(%s), input type(%d), default lang(%s), default type(%d)",
892 lang, type, g_cur_engine.default_lang, g_cur_engine.default_vctype);
895 /* case 1 : Both are default */
896 if (0 == strncmp(lang, "default", strlen("default")) && 0 == type) {
897 *out_lang = strdup(g_cur_engine.default_lang);
898 *out_type = g_cur_engine.default_vctype;
903 GList* voice_list = NULL;
906 ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, &voice_list);
907 if (0 != ret || 0 >= g_list_length(voice_list)) {
908 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
918 /* lang and type are not default type */
919 if (0 != strncmp(lang, "default", strlen("default")) && 0 != type) {
920 iter = g_list_first(voice_list);
922 while (NULL != iter) {
923 /* Get handle data from list */
926 if (0 == strncmp(voice->language, lang, strlen(lang)) && voice->type == type) {
927 *out_lang = strdup(voice->language);
928 *out_type = voice->type;
933 iter = g_list_next(iter);
936 } else if (0 != strncmp(lang, "default", strlen("default")) && 0 == type) {
937 /* Only type is default */
938 if (0 == strncmp(lang, g_cur_engine.default_lang, strlen(g_cur_engine.default_lang))) {
939 *out_lang = strdup(g_cur_engine.default_lang);
940 *out_type = g_cur_engine.default_vctype;
943 voice_s* voice_selected = NULL;
944 iter = g_list_first(voice_list);
945 while (NULL != iter) {
946 /* Get handle data from list */
949 if (0 == strncmp(voice->language, lang, strlen(lang))) {
950 voice_selected = voice;
951 if (voice->type == g_cur_engine.default_vctype) {
952 voice_selected = voice;
956 iter = g_list_next(iter);
959 if (NULL != voice_selected) {
960 *out_lang = strdup(voice_selected->language);
961 *out_type = voice_selected->type;
965 } else if (0 == strncmp(lang, "default", strlen("default")) && 0 != type) {
966 /* Only lang is default */
967 if (type == g_cur_engine.default_vctype) {
968 *out_lang = strdup(g_cur_engine.default_lang);
969 *out_type = g_cur_engine.default_vctype;
972 voice_s* voice_selected = NULL;
973 iter = g_list_first(voice_list);
974 while (NULL != iter) {
975 /* Get handle data from list */
978 if (0 == strncmp(voice->language, g_cur_engine.default_lang, strlen(g_cur_engine.default_lang)) ) {
979 voice_selected = voice;
980 if (voice->type == type) {
981 voice_selected = voice;
985 iter = g_list_next(iter);
988 if (NULL != voice_selected) {
989 *out_lang = strdup(voice->language);
990 *out_type = voice_selected->type;
996 if (true == result) {
997 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Selected voice : lang(%s), type(%d)", *out_lang, *out_type);
1000 __free_voice_list(voice_list);
1005 bool ttsd_engine_agent_is_same_engine(const char* engine_id)
1007 if (false == g_agent_init) {
1008 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized" );
1012 if (false == g_cur_engine.is_loaded) {
1013 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1017 /* compare current engine and engine id.*/
1018 if (0 == strncmp(g_cur_engine.engine_uuid, engine_id, strlen(engine_id))) {
1025 int ttsd_engine_agent_set_default_engine(const char* engine_id)
1027 if (false == g_agent_init) {
1028 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized" );
1029 return TTSD_ERROR_OPERATION_FAILED;
1032 /* compare current engine and new engine.*/
1033 if (0 == strncmp(g_cur_engine.engine_uuid, engine_id, strlen(engine_id))) {
1034 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] new engine(%s) is the same as current engine", engine_id);
1038 bool is_engine_loaded = false;
1039 char* tmp_uuid = NULL;
1040 tmp_uuid = strdup(g_cur_engine.engine_uuid);
1041 if (NULL == tmp_uuid) {
1042 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Current engine id is NULL");
1043 return TTSD_ERROR_OPERATION_FAILED;
1046 is_engine_loaded = g_cur_engine.is_loaded;
1048 if (true == is_engine_loaded) {
1050 if (0 != ttsd_engine_agent_unload_current_engine()) {
1051 SLOG(LOG_ERROR, get_tag(), "[Engine Agent Error] fail to unload current engine");
1055 /* change current engine */
1056 if (0 != __internal_set_current_engine(engine_id)) {
1057 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set current engine. Recovery origin engine");
1059 /* roll back to old current engine. */
1060 __internal_set_current_engine(tmp_uuid);
1061 if (true == is_engine_loaded) {
1062 ttsd_engine_agent_load_current_engine();
1065 if (tmp_uuid != NULL) free(tmp_uuid);
1066 return TTSD_ERROR_OPERATION_FAILED;
1069 if (true == is_engine_loaded) {
1071 if (0 != ttsd_engine_agent_load_current_engine()) {
1072 SLOG(LOG_ERROR, get_tag(), "[Engine Agent Error] Fail to load new engine. Recovery origin engine");
1074 /* roll back to old current engine. */
1075 __internal_set_current_engine(tmp_uuid);
1076 if (true == is_engine_loaded) {
1077 ttsd_engine_agent_load_current_engine();
1080 if (tmp_uuid != NULL) free(tmp_uuid);
1081 return TTSD_ERROR_OPERATION_FAILED;
1083 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] load new engine : %s", engine_id);
1087 if (tmp_uuid != NULL) free(tmp_uuid);
1091 int ttsd_engine_agent_set_default_voice(const char* language, int vctype)
1093 if (false == g_agent_init) {
1094 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized" );
1095 return TTSD_ERROR_OPERATION_FAILED;
1098 if (false == g_cur_engine.is_loaded) {
1099 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1100 return TTSD_ERROR_OPERATION_FAILED;
1103 if (false == g_cur_engine.pefuncs->is_valid_voice(language, vctype)) {
1104 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Voice is NOT valid !!");
1105 return TTSD_ERROR_INVALID_VOICE;
1109 GSList *iter = NULL;
1110 ttsvoice_s* data = NULL;
1112 /* Update new default voice info */
1113 iter = g_slist_nth(g_cur_voices, 0);
1114 while (NULL != iter) {
1115 /* Get handle data from list */
1119 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Voice data is NULL");
1120 return TTSD_ERROR_OPERATION_FAILED;
1123 if (0 == strcmp(data->lang, language) && data->type == vctype) {
1124 data->is_default = true;
1125 if (0 == data->client_ref_count) {
1127 if (NULL != g_cur_engine.pefuncs->load_voice) {
1128 ret = g_cur_engine.pefuncs->load_voice(data->lang, data->type);
1130 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] load voice : lang(%s), type(%d)",
1131 data->lang, data->type);
1132 data->is_loaded = true;
1134 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
1135 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1138 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Load voice of engine function is NULL");
1145 iter = g_slist_next(iter);
1148 #ifdef ENGINE_AGENT_DEBUG
1149 ttsd_print_voicelist();
1152 /* Update old default voice info */
1153 iter = g_slist_nth(g_cur_voices, 0);
1154 while (NULL != iter) {
1155 /*Get handle data from list*/
1159 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Voice data is NULL");
1160 return TTSD_ERROR_OPERATION_FAILED;
1163 if (0 == strcmp(data->lang, g_cur_engine.default_lang) && data->type == g_cur_engine.default_vctype) {
1164 data->is_default = false;
1165 if (0 == data->client_ref_count) {
1167 if (NULL != g_cur_engine.pefuncs->unload_voice) {
1168 ret = g_cur_engine.pefuncs->unload_voice(data->lang, data->type);
1170 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
1171 data->lang, data->type);
1172 data->is_loaded = false;
1174 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
1175 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1178 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Unload voice of engine function is NULL");
1185 iter = g_slist_next(iter);
1188 if (NULL != g_cur_engine.default_lang) free(g_cur_engine.default_lang);
1190 g_cur_engine.default_lang = strdup(language);
1191 g_cur_engine.default_vctype = vctype;
1193 #ifdef ENGINE_AGENT_DEBUG
1194 ttsd_print_voicelist();
1197 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set default voice : lang(%s), type(%d)",
1198 g_cur_engine.default_lang, g_cur_engine.default_vctype);
1203 int ttsd_engine_agent_set_default_speed(int speed)
1205 if (false == g_agent_init) {
1206 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized" );
1207 return TTSD_ERROR_OPERATION_FAILED;
1210 g_cur_engine.default_speed = speed;
1215 int ttsd_engine_agent_set_default_pitch(int pitch)
1217 if (false == g_agent_init) {
1218 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized" );
1219 return TTSD_ERROR_OPERATION_FAILED;
1222 if (false == g_cur_engine.is_loaded) {
1223 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1224 return TTSD_ERROR_OPERATION_FAILED;
1227 if (NULL == g_cur_engine.pefuncs->set_pitch) {
1228 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not support pitch");
1229 return TTSD_ERROR_OPERATION_FAILED;
1232 int ret = g_cur_engine.pefuncs->set_pitch(pitch);
1234 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)",
1235 pitch, __ttsd_get_engine_error_code(ret));
1236 return TTSD_ERROR_OPERATION_FAILED;
1239 g_cur_engine.default_pitch = pitch;
1244 /******************************************************************************************
1245 * TTS Engine Interfaces for client
1246 *******************************************************************************************/
1248 int ttsd_engine_load_voice(const char* lang, const int vctype)
1250 /* 1. Find voice info */
1252 GSList *iter = NULL;
1253 ttsvoice_s* data = NULL;
1255 iter = g_slist_nth(g_cur_voices, 0);
1256 while (NULL != iter) {
1257 /*Get handle data from list*/
1261 if (0 == strcmp(data->lang, lang) && data->type == vctype) {
1262 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1263 data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1269 iter = g_slist_next(iter);
1274 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
1275 return TTSD_ERROR_OPERATION_FAILED;
1278 /* 2. increse ref count */
1279 data->client_ref_count++;
1281 /* 3. if ref count change 0 to 1 and not default, load voice */
1282 if (1 == data->client_ref_count && false == data->is_default) {
1284 if (NULL != g_cur_engine.pefuncs->load_voice) {
1285 ret = g_cur_engine.pefuncs->load_voice(data->lang, data->type);
1287 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Load voice : lang(%s), type(%d)",
1288 data->lang, data->type);
1289 data->is_loaded = true;
1291 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
1292 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1294 return TTSD_ERROR_OPERATION_FAILED;
1297 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Load voice of engine function is NULL");
1300 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Not load voice : default voice(%d) or ref count(%d)",
1301 data->is_default, data->client_ref_count);
1304 #ifdef ENGINE_AGENT_DEBUG
1305 ttsd_print_voicelist();
1311 int ttsd_engine_unload_voice(const char* lang, const int vctype)
1313 /* 1. Find voice info */
1315 GSList *iter = NULL;
1316 ttsvoice_s* data = NULL;
1318 iter = g_slist_nth(g_cur_voices, 0);
1319 while (NULL != iter) {
1320 /*Get handle data from list*/
1324 if (0 == strcmp(data->lang, lang) && data->type == vctype) {
1325 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1326 data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1332 iter = g_slist_next(iter);
1337 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
1338 return TTSD_ERROR_OPERATION_FAILED;
1341 /* 2. Decrese ref count */
1342 data->client_ref_count--;
1344 /* 3. if ref count change 0 and not default, load voice */
1345 if (0 == data->client_ref_count && false == data->is_default) {
1347 if (NULL != g_cur_engine.pefuncs->unload_voice) {
1348 ret = g_cur_engine.pefuncs->unload_voice(data->lang, data->type);
1350 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
1351 data->lang, data->type);
1352 data->is_loaded = false;
1354 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
1355 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1357 return TTSD_ERROR_OPERATION_FAILED;
1360 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Unload voice of engine function is NULL");
1363 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Not unload voice : default voice(%d) or ref count(%d)",
1364 data->is_default, data->client_ref_count);
1367 #ifdef ENGINE_AGENT_DEBUG
1368 ttsd_print_voicelist();
1373 int ttsd_engine_start_synthesis(const char* lang, int vctype, const char* text, int speed, void* user_param)
1375 if (false == g_agent_init) {
1376 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized" );
1377 return TTSD_ERROR_OPERATION_FAILED;
1380 if (false == g_cur_engine.is_loaded) {
1381 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1382 return TTSD_ERROR_OPERATION_FAILED;
1385 /* select voice for default */
1386 char* temp_lang = NULL;
1388 if (true != ttsd_engine_select_valid_voice(lang, vctype, &temp_lang, &temp_type)) {
1389 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to select default voice");
1390 if (NULL != temp_lang) free(temp_lang);
1391 return TTSD_ERROR_INVALID_VOICE;
1393 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Start synthesis : language(%s), type(%d), speed(%d), text(%s)",
1394 temp_lang, temp_type, speed, text);
1397 if (NULL == g_cur_engine.pefuncs->start_synth) {
1398 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] start_synth() of engine is NULL!!");
1399 if (NULL != temp_lang) free(temp_lang);
1400 return TTSD_ERROR_OPERATION_FAILED;
1406 temp_speed = g_cur_engine.default_speed;
1411 /* synthesize text */
1413 ret = g_cur_engine.pefuncs->start_synth(temp_lang, temp_type, text, temp_speed, user_param);
1415 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] ***************************************");
1416 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] * synthesize error : %s *", __ttsd_get_engine_error_code(ret));
1417 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] ***************************************");
1418 if (NULL != temp_lang) free(temp_lang);
1419 return TTSD_ERROR_OPERATION_FAILED;
1422 if (NULL != temp_lang) free(temp_lang);
1426 int ttsd_engine_cancel_synthesis()
1428 if (false == g_agent_init) {
1429 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized" );
1430 return TTSD_ERROR_OPERATION_FAILED;
1433 if (false == g_cur_engine.is_loaded) {
1434 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1435 return TTSD_ERROR_OPERATION_FAILED;
1438 if (NULL == g_cur_engine.pefuncs->cancel_synth) {
1439 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] cancel_synth() of engine is NULL!!");
1440 return TTSD_ERROR_OPERATION_FAILED;
1443 /* stop synthesis */
1445 ret = g_cur_engine.pefuncs->cancel_synth();
1447 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail cancel synthesis : %s", __ttsd_get_engine_error_code(ret));
1448 return TTSD_ERROR_OPERATION_FAILED;
1454 bool __supported_voice_cb(const char* language, int type, void* user_data)
1456 GList** voice_list = (GList**)user_data;
1458 if (NULL == language || NULL == voice_list) {
1459 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
1463 voice_s* voice = calloc(1, sizeof(voice_s));
1464 voice->language = strdup(language);
1467 *voice_list = g_list_append(*voice_list, voice);
1472 int ttsd_engine_get_voice_list(GList** voice_list)
1474 if (false == g_agent_init) {
1475 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized" );
1476 return TTSD_ERROR_OPERATION_FAILED;
1479 if (false == g_cur_engine.is_loaded) {
1480 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1481 return TTSD_ERROR_OPERATION_FAILED;
1485 ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, (void*)voice_list);
1487 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to get voice list : %s", __ttsd_get_engine_error_code(ret));
1488 return TTSD_ERROR_OPERATION_FAILED;
1494 int ttsd_engine_get_default_voice(char** lang, int* vctype)
1496 if (false == g_agent_init) {
1497 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized" );
1498 return TTSD_ERROR_OPERATION_FAILED;
1501 if (false == g_cur_engine.is_loaded) {
1502 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1503 return TTSD_ERROR_OPERATION_FAILED;
1506 if (NULL == lang || NULL == vctype) {
1507 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] BAD Parameter");
1508 return TTSD_ERROR_INVALID_PARAMETER;
1511 if (NULL != g_cur_engine.default_lang) {
1512 *lang = strdup(g_cur_engine.default_lang);
1513 *vctype = g_cur_engine.default_vctype;
1515 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine] Get default voice : language(%s), type(%d)", *lang, *vctype);
1517 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Default voice is NULL");
1518 return TTSD_ERROR_OPERATION_FAILED;
1524 void __free_voice_list(GList* voice_list)
1527 voice_s* data = NULL;
1529 /* if list have item */
1530 if (g_list_length(voice_list) > 0) {
1531 /* Get a first item */
1532 iter = g_list_first(voice_list);
1534 while (NULL != iter) {
1538 if (NULL != data->language) free(data->language);
1542 voice_list = g_list_remove_link(voice_list, iter);
1544 iter = g_list_first(voice_list);
1550 * TTS Engine Callback Functions ` *
1552 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)
1554 g_result_cb(event, data, data_size, audio_type, rate, user_data);
1558 /* function for debugging */
1559 int ttsd_print_enginelist()
1562 ttsengine_info_s *data = NULL;
1564 if (g_list_length(g_engine_list) > 0) {
1565 iter = g_list_first(g_engine_list);
1567 SLOG(LOG_DEBUG, get_tag(), "----- engine list -----");
1570 while (NULL != iter) {
1573 SECURE_SLOG(LOG_DEBUG, get_tag(), "[%dth]", i);
1574 SECURE_SLOG(LOG_DEBUG, get_tag(), "engine uuid : %s", data->engine_uuid);
1575 SECURE_SLOG(LOG_DEBUG, get_tag(), "engine name : %s", data->engine_name);
1576 SECURE_SLOG(LOG_DEBUG, get_tag(), "engine path : %s", data->engine_path);
1577 SECURE_SLOG(LOG_DEBUG, get_tag(), "setting ug path : %s", data->setting_ug_path);
1579 iter = g_list_next(iter);
1582 SLOG(LOG_DEBUG, get_tag(), "-----------------------");
1583 SLOG(LOG_DEBUG, get_tag(), " ");
1585 SLOG(LOG_DEBUG, get_tag(), "----- engine list -----");
1586 SLOG(LOG_DEBUG, get_tag(), "No Engine in directory");
1587 SLOG(LOG_DEBUG, get_tag(), "-----------------------");
1593 int ttsd_print_voicelist()
1596 GSList *iter = NULL;
1597 ttsvoice_s* data = NULL;
1599 SLOG(LOG_DEBUG, get_tag(), "=== Voice list ===");
1601 if (g_slist_length(g_cur_voices) > 0) {
1602 /* Get a first item */
1603 iter = g_slist_nth(g_cur_voices, 0);
1606 while (NULL != iter) {
1607 /*Get handle data from list*/
1610 if (NULL == data || NULL == data->lang) {
1611 SLOG(LOG_ERROR, get_tag(), "[ERROR] Data is invalid");
1615 SLOG(LOG_DEBUG, get_tag(), "[%dth] default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1616 i, data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1619 iter = g_slist_next(iter);
1624 SLOG(LOG_DEBUG, get_tag(), "==================");