2 * Copyright (c) 2011-2016 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 static int __internal_set_current_engine(const char* engine_uuid);
90 /** Check engine id */
91 static int __internal_check_engine_id(const char* engine_uuid);
93 /** Update engine list */
94 static int __internal_update_engine_list();
96 /** Get engine info */
97 static 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 static bool __supported_voice_cb(const char* language, int type, void* user_data);
106 /** Free voice list */
107 static void __free_voice_list(GList* voice_list);
109 /** Callback function for engine info */
110 static void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* setting_ug_name,
111 bool use_network, void* user_data);
115 static int ttsd_print_enginelist();
117 static int ttsd_print_voicelist();
119 static const char* __ttsd_get_engine_error_code(ttsp_error_e err)
122 case TTSP_ERROR_NONE: return "TTSP_ERROR_NONE";
123 case TTSP_ERROR_OUT_OF_MEMORY: return "TTSP_ERROR_OUT_OF_MEMORY";
124 case TTSP_ERROR_IO_ERROR: return "TTSP_ERROR_IO_ERROR";
125 case TTSP_ERROR_INVALID_PARAMETER: return "TTSP_ERROR_INVALID_PARAMETER";
126 case TTSP_ERROR_OUT_OF_NETWORK: return "TTSP_ERROR_OUT_OF_NETWORK";
127 case TTSP_ERROR_INVALID_STATE: return "TTSP_ERROR_INVALID_STATE";
128 case TTSP_ERROR_INVALID_VOICE: return "TTSP_ERROR_INVALID_VOICE";
129 case TTSP_ERROR_OPERATION_FAILED: return "TTSP_ERROR_OPERATION_FAILED";
131 return "Invalid error code";
135 int ttsd_engine_agent_init(synth_result_callback result_cb)
137 /* initialize static data */
138 if (result_cb == NULL) {
139 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] invalid parameter");
140 return TTSD_ERROR_INVALID_PARAMETER;
143 g_result_cb = result_cb;
145 g_cur_engine.engine_uuid = NULL;
146 g_cur_engine.engine_name = NULL;
147 g_cur_engine.engine_path = NULL;
149 g_cur_engine.is_set = false;
150 g_cur_engine.handle = NULL;
151 g_cur_engine.pefuncs = (ttspe_funcs_s*)calloc(1, sizeof(ttspe_funcs_s));
152 if (NULL == g_cur_engine.pefuncs) {
153 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to allocate memory");
154 return TTSP_ERROR_OUT_OF_MEMORY;
157 g_cur_engine.pdfuncs = (ttspd_funcs_s*)calloc(1, sizeof(ttspd_funcs_s));
158 if (NULL == g_cur_engine.pdfuncs) {
159 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to allocate memory");
160 free(g_cur_engine.pefuncs);
161 g_cur_engine.pefuncs = NULL;
162 return TTSP_ERROR_OUT_OF_MEMORY;
167 if (0 != ttsd_config_get_default_voice(&(g_cur_engine.default_lang), &(g_cur_engine.default_vctype))) {
168 SLOG(LOG_WARN, get_tag(), "[Server WARNING] There is No default voice in config");
169 /* Set default voice */
170 g_cur_engine.default_lang = strdup(TTS_BASE_LANGUAGE);
171 g_cur_engine.default_vctype = TTSP_VOICE_TYPE_FEMALE;
174 if (0 != ttsd_config_get_default_speed(&(g_cur_engine.default_speed))) {
175 SLOG(LOG_WARN, get_tag(), "[Server WARNING] There is No default speed in config");
176 g_cur_engine.default_speed = TTS_SPEED_NORMAL;
179 if (0 != ttsd_config_get_default_pitch(&(g_cur_engine.default_pitch))) {
180 SLOG(LOG_WARN, get_tag(), "[Server WARNING] There is No default pitch in config");
181 g_cur_engine.default_pitch = TTS_PITCH_NORMAL;
184 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Initialize Engine Agent");
189 int ttsd_engine_agent_release()
191 if (false == g_agent_init) {
192 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
193 return TTSD_ERROR_OPERATION_FAILED;
196 /* unload current engine */
197 ttsd_engine_agent_unload_current_engine();
199 /* release engine list */
201 ttsengine_info_s *data = NULL;
203 if (g_list_length(g_engine_list) > 0) {
204 /* Get a first item */
205 iter = g_list_first(g_engine_list);
206 while (NULL != iter) {
207 /* Get data from item */
209 iter = g_list_remove(iter, data);
212 if (NULL != data->engine_uuid) free(data->engine_uuid);
213 if (NULL != data->engine_name) free(data->engine_name);
214 if (NULL != data->setting_ug_path) free(data->setting_ug_path);
215 if (NULL != data->engine_path) free(data->engine_path);
222 /* release current engine data */
223 if (g_cur_engine.engine_uuid != NULL) free(g_cur_engine.engine_uuid);
224 if (g_cur_engine.engine_name != NULL) free(g_cur_engine.engine_name);
225 if (g_cur_engine.engine_path != NULL) free(g_cur_engine.engine_path);
227 if (g_cur_engine.pefuncs != NULL) free(g_cur_engine.pefuncs);
228 if (g_cur_engine.pdfuncs != NULL) free(g_cur_engine.pdfuncs);
229 if (g_cur_engine.default_lang != NULL) free(g_cur_engine.default_lang);
231 g_agent_init = false;
233 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Release Engine Agent");
238 int ttsd_engine_agent_initialize_current_engine()
240 if (false == g_agent_init) {
241 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
242 return TTSD_ERROR_OPERATION_FAILED;
245 /* update engine list */
246 if (0 != __internal_update_engine_list()) {
247 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] No engine error");
248 return TTSD_ERROR_OPERATION_FAILED;
251 /* 2. get current engine from config */
252 char* cur_engine_uuid = NULL;
253 bool is_get_engineid_from_config = false;
255 if (0 != ttsd_config_get_default_engine(&cur_engine_uuid)) {
256 /*not set current engine */
257 /*set system default engine*/
259 ttsengine_info_s *data = NULL;
261 if (g_list_length(g_engine_list) > 0) {
262 iter = g_list_first(g_engine_list);
264 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] Fail to get a engine of engine list");
265 return TTSD_ERROR_OPERATION_FAILED;
270 if (NULL != data->engine_uuid) {
271 cur_engine_uuid = strdup(data->engine_uuid);
272 ttsd_config_set_default_engine(cur_engine_uuid);
274 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Data of current engine is corrupt");
275 return TTSD_ERROR_OPERATION_FAILED;
279 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] Fail to get a engine of engine list");
280 return TTSD_ERROR_OPERATION_FAILED;
283 is_get_engineid_from_config = false;
285 is_get_engineid_from_config = true;
288 if (NULL == cur_engine_uuid) {
289 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Current engine id is NULL");
290 return TTSD_ERROR_OPERATION_FAILED;
293 /* check whether cur engine uuid is valid or not. */
294 if (0 != __internal_check_engine_id(cur_engine_uuid)) {
295 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] It is not valid engine id from config");
299 if (g_list_length(g_engine_list) > 0)
300 iter = g_list_first(g_engine_list);
302 SLOG(LOG_WARN, get_tag(), "[Engine Agent ERROR] NO TTS Engine !!");
303 if (NULL != cur_engine_uuid) {
304 free(cur_engine_uuid);
305 cur_engine_uuid = NULL;
307 return TTSD_ERROR_OPERATION_FAILED;
311 SLOG(LOG_WARN, get_tag(), "[Engine Agent ERROR] No valid TTS Engine");
312 if (NULL != cur_engine_uuid) {
313 free(cur_engine_uuid);
314 cur_engine_uuid = NULL;
316 return TTSD_ERROR_OPERATION_FAILED;
319 if (cur_engine_uuid != NULL) {
320 free(cur_engine_uuid);
321 cur_engine_uuid = NULL;
323 ttsengine_info_s *data = NULL;
326 if (NULL == data || NULL == data->engine_uuid) {
327 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No valid TTS Engine");
328 return TTSD_ERROR_OPERATION_FAILED;
331 cur_engine_uuid = strdup(data->engine_uuid);
333 is_get_engineid_from_config = false;
336 if (NULL != cur_engine_uuid)
337 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Current Engine Id : %s", cur_engine_uuid);
339 return TTSD_ERROR_OPERATION_FAILED;
341 /* set current engine */
342 if (0 != __internal_set_current_engine(cur_engine_uuid)) {
343 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to set current engine ");
344 if (NULL != cur_engine_uuid) free(cur_engine_uuid);
345 return TTSD_ERROR_OPERATION_FAILED;
348 if (false == is_get_engineid_from_config) {
349 if (0 != ttsd_config_set_default_engine(cur_engine_uuid)) {
350 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to set id to config");
354 if (NULL != cur_engine_uuid) free(cur_engine_uuid);
356 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set current engine");
361 static int __internal_check_engine_id(const char* engine_uuid)
364 ttsengine_s *data = NULL;
366 if (g_list_length(g_engine_list) > 0) {
367 iter = g_list_first(g_engine_list);
369 while (NULL != iter) {
372 if (0 == strncmp(engine_uuid, data->engine_uuid, strlen(data->engine_uuid)))
375 iter = g_list_next(iter);
382 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* setting_ug_name,
383 bool use_network, void* user_data)
385 ttsengine_info_s* temp = (ttsengine_info_s*)user_data;
387 if (NULL != engine_uuid)
388 temp->engine_uuid = strdup(engine_uuid);
390 if (NULL != engine_name)
391 temp->engine_name = strdup(engine_name);
393 if (NULL != setting_ug_name)
394 temp->setting_ug_path = strdup(setting_ug_name);
396 temp->use_network = use_network;
400 static int __internal_get_engine_info(const char* filepath, ttsengine_info_s** info)
405 handle = dlopen(filepath, RTLD_LAZY);
408 SECURE_SLOG(LOG_WARN, get_tag(), "[Engine Agent] Invalid engine : %s", filepath);
409 return TTSD_ERROR_OPERATION_FAILED;
412 /* link engine to daemon */
413 dlsym(handle, "ttsp_load_engine");
414 if ((error = dlerror()) != NULL) {
415 SECURE_SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to open ttsp_load_engine : path(%s) message(%s)", filepath, error);
417 return TTSD_ERROR_OPERATION_FAILED;
420 dlsym(handle, "ttsp_unload_engine");
421 if ((error = dlerror()) != NULL) {
422 SECURE_SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to open ttsp_unload_engine : path(%s) message(%s)", filepath, error);
424 return TTSD_ERROR_OPERATION_FAILED;
427 int (*get_engine_info)(ttsp_engine_info_cb callback, void* user_data);
429 get_engine_info = (int (*)(ttsp_engine_info_cb, void*))dlsym(handle, "ttsp_get_engine_info");
430 if (NULL != (error = dlerror()) || NULL == get_engine_info) {
431 SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to open ttsp_get_engine_info() :path(%s) message(%s)", filepath, error);
433 return TTSD_ERROR_OPERATION_FAILED;
436 ttsengine_info_s* temp;
437 temp = (ttsengine_info_s*)calloc(1, sizeof(ttsengine_info_s));
439 SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to alloc memory");
441 return TTSD_ERROR_OUT_OF_MEMORY;
444 /* get engine info */
445 if (0 != get_engine_info(&__engine_info_cb, (void*)temp)) {
446 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to get engine info");
449 return TTSD_ERROR_OPERATION_FAILED;
455 if (TTSD_MODE_SCREEN_READER == ttsd_get_mode() && true == temp->use_network) {
456 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent WARNING] %s is invalid because of network based", temp->engine_name);
457 if (NULL != temp->engine_uuid) free(temp->engine_uuid);
458 if (NULL != temp->engine_name) free(temp->engine_name);
459 if (NULL != temp->setting_ug_path) free(temp->setting_ug_path);
461 return TTSD_ERROR_OPERATION_FAILED;
464 temp->engine_path = strdup(filepath);
466 SLOG(LOG_DEBUG, get_tag(), "----- Valid engine");
467 SECURE_SLOG(LOG_DEBUG, get_tag(), "Engine uuid : %s", temp->engine_uuid);
468 SECURE_SLOG(LOG_DEBUG, get_tag(), "Engine name : %s", temp->engine_name);
469 SECURE_SLOG(LOG_DEBUG, get_tag(), "Setting path : %s", temp->setting_ug_path);
470 SECURE_SLOG(LOG_DEBUG, get_tag(), "Engine path : %s", temp->engine_path);
471 SECURE_SLOG(LOG_DEBUG, get_tag(), "Use network : %s", temp->use_network ? "true" : "false");
472 SLOG(LOG_DEBUG, get_tag(), "-----");
473 SLOG(LOG_DEBUG, get_tag(), " ");
480 static int __internal_update_engine_list()
482 /* relsease engine list */
484 ttsengine_info_s *data = NULL;
486 if (g_list_length(g_engine_list) > 0) {
487 iter = g_list_first(g_engine_list);
489 while (NULL != iter) {
492 if (data != NULL) free(data);
493 g_engine_list = g_list_remove_link(g_engine_list, iter);
495 iter = g_list_first(g_engine_list);
499 /* get file name from engine directory and get engine information from each filename */
503 struct dirent *dirp = NULL;
504 dp = opendir(TTS_DEFAULT_ENGINE);
508 ret = readdir_r(dp, &entry, &dirp);
510 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to read directory");
515 ttsengine_info_s* info;
516 char* filepath = NULL;
519 file_size = strlen(TTS_DEFAULT_ENGINE) + strlen(dirp->d_name) + 5;
520 filepath = (char*)calloc(file_size, sizeof(char));
522 if (NULL != filepath) {
523 snprintf(filepath, file_size, "%s/%s", TTS_DEFAULT_ENGINE, dirp->d_name);
525 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not enough memory!!");
529 /* get its info and update engine list */
530 if (0 == __internal_get_engine_info(filepath, &info)) {
531 /* add engine info to g_engine_list */
532 g_engine_list = g_list_append(g_engine_list, info);
535 if (NULL != filepath) free(filepath);
537 } while (NULL != dirp);
542 if (g_list_length(g_engine_list) <= 0) {
543 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No Engine");
544 return TTSD_ERROR_OPERATION_FAILED;
547 #ifdef ENGINE_AGENT_DEBUG
548 ttsd_print_enginelist();
553 static int __internal_set_current_engine(const char* engine_uuid)
555 /* check whether engine id is valid or not. */
557 ttsengine_info_s *data = NULL;
560 if (g_list_length(g_engine_list) > 0) {
561 iter = g_list_first(g_engine_list);
563 while (NULL != iter) {
566 if (0 == strncmp(data->engine_uuid, engine_uuid, strlen(engine_uuid))) {
572 iter = g_list_next(iter);
576 /* If current engine does not exist, return error */
578 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Cannot find engine id");
579 return TTSD_ERROR_OPERATION_FAILED;
581 if (g_cur_engine.engine_uuid != NULL) {
582 /*compare current engine uuid */
583 if (0 == strncmp(g_cur_engine.engine_uuid, data->engine_uuid, strlen(engine_uuid))) {
584 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] tts engine has already been set");
590 /* set data from g_engine_list */
591 if (g_cur_engine.engine_uuid != NULL) free(g_cur_engine.engine_uuid);
592 if (g_cur_engine.engine_name != NULL) free(g_cur_engine.engine_name);
593 if (g_cur_engine.engine_path != NULL) free(g_cur_engine.engine_path);
595 if (NULL == data->engine_uuid || NULL == data->engine_name || NULL == data->engine_path) {
596 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Engine data is NULL");
597 return TTSD_ERROR_OPERATION_FAILED;
600 g_cur_engine.engine_uuid = strdup(data->engine_uuid);
601 g_cur_engine.engine_name = strdup(data->engine_name);
602 g_cur_engine.engine_path = strdup(data->engine_path);
604 g_cur_engine.handle = NULL;
605 g_cur_engine.is_loaded = false;
606 g_cur_engine.is_set = true;
607 g_cur_engine.need_network = data->use_network;
609 SLOG(LOG_DEBUG, get_tag(), "-----");
610 SECURE_SLOG(LOG_DEBUG, get_tag(), "Current engine uuid : %s", g_cur_engine.engine_uuid);
611 SECURE_SLOG(LOG_DEBUG, get_tag(), "Current engine name : %s", g_cur_engine.engine_name);
612 SECURE_SLOG(LOG_DEBUG, get_tag(), "Current engine path : %s", g_cur_engine.engine_path);
613 SLOG(LOG_DEBUG, get_tag(), "-----");
618 int __ttsd_get_mode(ttsp_mode_e* mode)
621 SLOG(LOG_ERROR, get_tag(), "[ERROR] Input parameter is null");
622 return TTSP_ERROR_INVALID_PARAMETER;
625 switch (ttsd_get_mode()) {
626 case TTSD_MODE_DEFAULT: *mode = TTSP_MODE_DEFAULT; break;
627 case TTSD_MODE_NOTIFICATION: *mode = TTSP_MODE_NOTIFICATION; break;
628 case TTSD_MODE_SCREEN_READER: *mode = TTSP_MODE_SCREEN_READER; break;
630 SLOG(LOG_ERROR, get_tag(), "[ERROR] tts mode is NOT valid");
636 int __ttsd_engine_agent_get_speed_range(int* min, int* normal, int* max)
638 if (NULL == min || NULL == normal || NULL == max) {
639 SLOG(LOG_ERROR, get_tag(), "[ERROR] Input parameter is null");
640 return TTSP_ERROR_INVALID_PARAMETER;
643 *min = TTS_SPEED_MIN;
644 *normal = TTS_SPEED_NORMAL;
645 *max = TTS_SPEED_MAX;
650 int __ttsd_engine_agent_get_pitch_range(int* min, int* normal, int* max)
652 if (NULL == min || NULL == normal || NULL == max) {
653 SLOG(LOG_ERROR, get_tag(), "[ERROR] Input parameter is null");
654 return TTSP_ERROR_INVALID_PARAMETER;
657 *min = TTS_PITCH_MIN;
658 *normal = TTS_PITCH_NORMAL;
659 *max = TTS_PITCH_MAX;
664 static bool __set_voice_info_cb(const char* language, int type, void* user_data)
666 if (NULL == language) {
667 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
671 ttsvoice_s* voice = calloc(1, sizeof(ttsvoice_s));
673 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to allocate memory");
676 voice->lang = strdup(language);
679 voice->client_ref_count = 0;
680 voice->is_loaded = false;
682 if (0 == strcmp(g_cur_engine.default_lang, language) && g_cur_engine.default_vctype == type) {
683 voice->is_default = true;
684 voice->is_loaded = true;
686 voice->is_default = false;
689 g_cur_voices = g_slist_append(g_cur_voices, voice);
694 static int __update_voice_list()
700 ret = g_cur_engine.pefuncs->foreach_voices(__set_voice_info_cb, NULL);
701 if (0 != ret || 0 >= g_slist_length(g_cur_voices)) {
702 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
706 #ifdef ENGINE_AGENT_DEBUG
707 ttsd_print_voicelist();
712 int ttsd_engine_agent_load_current_engine()
714 if (false == g_agent_init) {
715 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
716 return TTSD_ERROR_OPERATION_FAILED;
719 if (false == g_cur_engine.is_set) {
720 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No Current Engine ");
721 return TTSD_ERROR_OPERATION_FAILED;
724 /* check whether current engine is loaded or not */
725 if (true == g_cur_engine.is_loaded) {
726 SLOG(LOG_ERROR, get_tag(), "[Engine Agent] Engine has already been loaded ");
732 g_cur_engine.handle = dlopen(g_cur_engine.engine_path, RTLD_LAZY); /* RTLD_LAZY RTLD_NOW*/
734 if (NULL != (error = dlerror()) || NULL == g_cur_engine.handle) {
735 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to get current engine handle : %s", error);
739 g_cur_engine.ttsp_unload_engine = (int (*)())dlsym(g_cur_engine.handle, "ttsp_unload_engine");
740 if (NULL != (error = dlerror()) || NULL == g_cur_engine.ttsp_unload_engine) {
741 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to link daemon to ttsp_unload_engine() : %s", error);
745 g_cur_engine.ttsp_load_engine = (int (*)(const ttspd_funcs_s* , ttspe_funcs_s*))dlsym(g_cur_engine.handle, "ttsp_load_engine");
746 if (NULL != (error = dlerror()) || NULL == g_cur_engine.ttsp_load_engine) {
747 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to link daemon to ttsp_load_engine() : %s", error);
752 g_cur_engine.pdfuncs->version = 1;
753 g_cur_engine.pdfuncs->size = sizeof(ttspd_funcs_s);
754 g_cur_engine.pdfuncs->get_mode = __ttsd_get_mode;
755 g_cur_engine.pdfuncs->get_speed_range = __ttsd_engine_agent_get_speed_range;
756 g_cur_engine.pdfuncs->get_pitch_range = __ttsd_engine_agent_get_pitch_range;
759 ret = g_cur_engine.ttsp_load_engine(g_cur_engine.pdfuncs, g_cur_engine.pefuncs);
761 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to load engine - %s : result(%s)",
762 g_cur_engine.engine_path, __ttsd_get_engine_error_code(ret));
763 return TTSD_ERROR_OPERATION_FAILED;
766 /* engine error check */
767 if (g_cur_engine.pefuncs->size != sizeof(ttspe_funcs_s)) {
768 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] The size of engine function is not valid");
771 if (NULL == g_cur_engine.pefuncs->initialize ||
772 NULL == g_cur_engine.pefuncs->deinitialize ||
773 NULL == g_cur_engine.pefuncs->foreach_voices ||
774 NULL == g_cur_engine.pefuncs->is_valid_voice ||
775 NULL == g_cur_engine.pefuncs->start_synth ||
776 NULL == g_cur_engine.pefuncs->cancel_synth) {
777 SLOG(LOG_ERROR, get_tag(), "[Engine ERROR] The engine functions are NOT valid");
778 return TTSD_ERROR_OPERATION_FAILED;
781 ret = g_cur_engine.pefuncs->initialize(__result_cb);
783 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to initialize current engine : %s", __ttsd_get_engine_error_code(ret));
784 return TTSD_ERROR_OPERATION_FAILED;
787 /* Get voice info of current engine */
788 ret = __update_voice_list();
790 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set voice info : result(%d)", ret);
791 return TTSD_ERROR_OPERATION_FAILED;
794 /* Select default voice */
795 if (NULL != g_cur_engine.default_lang) {
796 if (true == g_cur_engine.pefuncs->is_valid_voice(g_cur_engine.default_lang, g_cur_engine.default_vctype)) {
797 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set origin default voice to current engine : lang(%s), type(%d)",
798 g_cur_engine.default_lang, g_cur_engine.default_vctype);
800 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] Fail set origin default voice : lang(%s), type(%d)",
801 g_cur_engine.default_lang, g_cur_engine.default_vctype);
803 return TTSD_ERROR_OPERATION_FAILED;
807 /* load default voice */
808 if (NULL != g_cur_engine.pefuncs->load_voice) {
809 ret = g_cur_engine.pefuncs->load_voice(g_cur_engine.default_lang, g_cur_engine.default_vctype);
811 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Load default voice : lang(%s), type(%d)",
812 g_cur_engine.default_lang, g_cur_engine.default_vctype);
814 SLOG(LOG_WARN, get_tag(), "[Engine Agent ERROR] Fail to load default voice : lang(%s), type(%d) result(%s)",
815 g_cur_engine.default_lang, g_cur_engine.default_vctype, __ttsd_get_engine_error_code(ret));
817 return TTSD_ERROR_OPERATION_FAILED;
821 /* set default pitch */
822 if (NULL != g_cur_engine.pefuncs->set_pitch) {
823 ret = g_cur_engine.pefuncs->set_pitch(g_cur_engine.default_pitch);
825 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)",
826 g_cur_engine.default_pitch, __ttsd_get_engine_error_code(ret));
827 return TTSD_ERROR_OPERATION_FAILED;
829 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set default pitch : pitch(%d)", g_cur_engine.default_pitch);
832 g_cur_engine.is_loaded = true;
837 int ttsd_engine_agent_unload_current_engine()
839 if (false == g_agent_init) {
840 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
841 return TTSD_ERROR_OPERATION_FAILED;
844 if (false == g_cur_engine.is_set) {
845 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No Current Engine ");
846 return TTSD_ERROR_OPERATION_FAILED;
849 if (false == g_cur_engine.is_loaded) {
850 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Engine has already been unloaded ");
854 /* shutdown engine */
856 ret = g_cur_engine.pefuncs->deinitialize();
858 SLOG(LOG_ERROR, get_tag(), "[Engine Agent] Fail deinitialize() : %s", __ttsd_get_engine_error_code(ret));
862 g_cur_engine.ttsp_unload_engine();
864 dlclose(g_cur_engine.handle);
866 /* reset current engine data */
867 g_cur_engine.handle = NULL;
868 g_cur_engine.is_loaded = false;
871 ttsvoice_s* data = NULL;
873 iter = g_slist_nth(g_cur_voices, 0);
874 while (NULL != iter) {
878 if (NULL != data->lang) free(data->lang);
879 g_cur_voices = g_slist_remove(g_cur_voices, data);
884 iter = g_slist_nth(g_cur_voices, 0);
890 bool ttsd_engine_agent_need_network()
892 if (false == g_agent_init) {
893 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
894 return TTSD_ERROR_OPERATION_FAILED;
897 if (false == g_cur_engine.is_loaded) {
898 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
899 return TTSD_ERROR_OPERATION_FAILED;
902 return g_cur_engine.need_network;
905 bool ttsd_engine_select_valid_voice(const char* lang, int type, char** out_lang, int* out_type)
907 if (NULL == lang || NULL == out_lang || NULL == out_type) {
911 if (false == g_cur_engine.is_loaded) {
912 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] Not loaded engine");
916 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Select voice : input lang(%s), input type(%d), default lang(%s), default type(%d)",
917 lang, type, g_cur_engine.default_lang, g_cur_engine.default_vctype);
919 /* case 1 : Both are default */
920 if (0 == strncmp(lang, "default", strlen("default")) && 0 == type) {
921 *out_lang = strdup(g_cur_engine.default_lang);
922 *out_type = g_cur_engine.default_vctype;
927 GList* voice_list = NULL;
930 ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, &voice_list);
931 if (0 != ret || 0 >= g_list_length(voice_list)) {
932 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
942 /* lang and type are not default type */
943 if (0 != strncmp(lang, "default", strlen("default")) && 0 != type) {
944 iter = g_list_first(voice_list);
946 while (NULL != iter) {
947 /* Get handle data from list */
950 if (0 == strncmp(voice->language, lang, strlen(lang)) && voice->type == type) {
951 *out_lang = strdup(voice->language);
952 *out_type = voice->type;
957 iter = g_list_next(iter);
960 } else if (0 != strncmp(lang, "default", strlen("default")) && 0 == type) {
961 /* Only type is default */
962 if (0 == strncmp(lang, g_cur_engine.default_lang, strlen(g_cur_engine.default_lang))) {
963 *out_lang = strdup(g_cur_engine.default_lang);
964 *out_type = g_cur_engine.default_vctype;
967 voice_s* voice_selected = NULL;
968 iter = g_list_first(voice_list);
969 while (NULL != iter) {
970 /* Get handle data from list */
973 if (0 == strncmp(voice->language, lang, strlen(lang))) {
974 voice_selected = voice;
975 if (voice->type == g_cur_engine.default_vctype) {
976 voice_selected = voice;
980 iter = g_list_next(iter);
983 if (NULL != voice_selected) {
984 *out_lang = strdup(voice_selected->language);
985 *out_type = voice_selected->type;
989 } else if (0 == strncmp(lang, "default", strlen("default")) && 0 != type) {
990 /* Only lang is default */
991 if (type == g_cur_engine.default_vctype) {
992 *out_lang = strdup(g_cur_engine.default_lang);
993 *out_type = g_cur_engine.default_vctype;
996 voice_s* voice_selected = NULL;
997 iter = g_list_first(voice_list);
998 while (NULL != iter) {
999 /* Get handle data from list */
1002 if (0 == strncmp(voice->language, g_cur_engine.default_lang, strlen(g_cur_engine.default_lang))) {
1003 voice_selected = voice;
1004 if (voice->type == type) {
1005 voice_selected = voice;
1009 iter = g_list_next(iter);
1012 if (NULL != voice_selected) {
1013 *out_lang = strdup(voice->language);
1014 *out_type = voice_selected->type;
1020 if (true == result) {
1021 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Selected voice : lang(%s), type(%d)", *out_lang, *out_type);
1024 __free_voice_list(voice_list);
1029 bool ttsd_engine_agent_is_same_engine(const char* engine_id)
1031 if (false == g_agent_init) {
1032 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1036 if (false == g_cur_engine.is_loaded) {
1037 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1041 /* compare current engine and engine id.*/
1042 if (0 == strncmp(g_cur_engine.engine_uuid, engine_id, strlen(engine_id))) {
1049 int ttsd_engine_agent_set_default_engine(const char* engine_id)
1051 if (false == g_agent_init) {
1052 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1053 return TTSD_ERROR_OPERATION_FAILED;
1056 /* compare current engine and new engine.*/
1057 if (0 == strncmp(g_cur_engine.engine_uuid, engine_id, strlen(engine_id))) {
1058 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] new engine(%s) is the same as current engine", engine_id);
1062 bool is_engine_loaded = false;
1063 char* tmp_uuid = NULL;
1064 tmp_uuid = strdup(g_cur_engine.engine_uuid);
1065 if (NULL == tmp_uuid) {
1066 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Current engine id is NULL");
1067 return TTSD_ERROR_OPERATION_FAILED;
1070 is_engine_loaded = g_cur_engine.is_loaded;
1072 if (true == is_engine_loaded) {
1074 if (0 != ttsd_engine_agent_unload_current_engine()) {
1075 SLOG(LOG_ERROR, get_tag(), "[Engine Agent Error] fail to unload current engine");
1079 /* change current engine */
1080 if (0 != __internal_set_current_engine(engine_id)) {
1081 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set current engine. Recovery origin engine");
1083 /* roll back to old current engine. */
1084 __internal_set_current_engine(tmp_uuid);
1085 if (true == is_engine_loaded) {
1086 ttsd_engine_agent_load_current_engine();
1089 if (tmp_uuid != NULL) free(tmp_uuid);
1090 return TTSD_ERROR_OPERATION_FAILED;
1093 if (true == is_engine_loaded) {
1095 if (0 != ttsd_engine_agent_load_current_engine()) {
1096 SLOG(LOG_ERROR, get_tag(), "[Engine Agent Error] Fail to load new engine. Recovery origin engine");
1098 /* roll back to old current engine. */
1099 __internal_set_current_engine(tmp_uuid);
1100 if (true == is_engine_loaded) {
1101 ttsd_engine_agent_load_current_engine();
1104 if (tmp_uuid != NULL) free(tmp_uuid);
1105 return TTSD_ERROR_OPERATION_FAILED;
1107 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] load new engine : %s", engine_id);
1111 if (tmp_uuid != NULL) free(tmp_uuid);
1115 int ttsd_engine_agent_set_default_voice(const char* language, int vctype)
1117 if (false == g_agent_init) {
1118 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1119 return TTSD_ERROR_OPERATION_FAILED;
1122 if (false == g_cur_engine.is_loaded) {
1123 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1124 return TTSD_ERROR_OPERATION_FAILED;
1127 if (false == g_cur_engine.pefuncs->is_valid_voice(language, vctype)) {
1128 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Voice is NOT valid !!");
1129 return TTSD_ERROR_INVALID_VOICE;
1133 GSList *iter = NULL;
1134 ttsvoice_s* data = NULL;
1136 /* Update new default voice info */
1137 iter = g_slist_nth(g_cur_voices, 0);
1138 while (NULL != iter) {
1139 /* Get handle data from list */
1143 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Voice data is NULL");
1144 return TTSD_ERROR_OPERATION_FAILED;
1147 if (0 == strcmp(data->lang, language) && data->type == vctype) {
1148 data->is_default = true;
1149 if (0 == data->client_ref_count) {
1151 if (NULL != g_cur_engine.pefuncs->load_voice) {
1152 ret = g_cur_engine.pefuncs->load_voice(data->lang, data->type);
1154 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] load voice : lang(%s), type(%d)",
1155 data->lang, data->type);
1156 data->is_loaded = true;
1158 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
1159 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1162 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Load voice of engine function is NULL");
1169 iter = g_slist_next(iter);
1172 #ifdef ENGINE_AGENT_DEBUG
1173 ttsd_print_voicelist();
1176 /* Update old default voice info */
1177 iter = g_slist_nth(g_cur_voices, 0);
1178 while (NULL != iter) {
1179 /*Get handle data from list*/
1183 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Voice data is NULL");
1184 return TTSD_ERROR_OPERATION_FAILED;
1187 if (0 == strcmp(data->lang, g_cur_engine.default_lang) && data->type == g_cur_engine.default_vctype) {
1188 data->is_default = false;
1189 if (0 == data->client_ref_count) {
1191 if (NULL != g_cur_engine.pefuncs->unload_voice) {
1192 ret = g_cur_engine.pefuncs->unload_voice(data->lang, data->type);
1194 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
1195 data->lang, data->type);
1196 data->is_loaded = false;
1198 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
1199 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1202 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Unload voice of engine function is NULL");
1209 iter = g_slist_next(iter);
1212 if (NULL != g_cur_engine.default_lang) free(g_cur_engine.default_lang);
1214 g_cur_engine.default_lang = strdup(language);
1215 g_cur_engine.default_vctype = vctype;
1217 #ifdef ENGINE_AGENT_DEBUG
1218 ttsd_print_voicelist();
1221 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set default voice : lang(%s), type(%d)",
1222 g_cur_engine.default_lang, g_cur_engine.default_vctype);
1227 int ttsd_engine_agent_set_default_speed(int speed)
1229 if (false == g_agent_init) {
1230 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1231 return TTSD_ERROR_OPERATION_FAILED;
1234 g_cur_engine.default_speed = speed;
1239 int ttsd_engine_agent_set_default_pitch(int pitch)
1241 if (false == g_agent_init) {
1242 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1243 return TTSD_ERROR_OPERATION_FAILED;
1246 if (false == g_cur_engine.is_loaded) {
1247 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1248 return TTSD_ERROR_OPERATION_FAILED;
1251 if (NULL == g_cur_engine.pefuncs->set_pitch) {
1252 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not support pitch");
1253 return TTSD_ERROR_OPERATION_FAILED;
1256 int ret = g_cur_engine.pefuncs->set_pitch(pitch);
1258 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)",
1259 pitch, __ttsd_get_engine_error_code(ret));
1260 return TTSD_ERROR_OPERATION_FAILED;
1263 g_cur_engine.default_pitch = pitch;
1268 int ttsd_engine_agent_is_credential_needed(int uid, bool* credential_needed)
1270 if (NULL == credential_needed) {
1271 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Invalid Parameter");
1272 return TTSP_ERROR_INVALID_PARAMETER;
1275 if (false == g_agent_init) {
1276 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1277 return TTSD_ERROR_OPERATION_FAILED;
1280 if (false == g_cur_engine.is_loaded) {
1281 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1282 return TTSD_ERROR_OPERATION_FAILED;
1285 if (NULL == g_cur_engine.pefuncs->need_app_credential) {
1286 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not support to check app credential");
1287 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1290 bool result = false;
1291 result = g_cur_engine.pefuncs->need_app_credential();
1292 *credential_needed = result;
1294 return TTSP_ERROR_NONE;
1297 /******************************************************************************************
1298 * TTS Engine Interfaces for client
1299 *******************************************************************************************/
1301 int ttsd_engine_load_voice(const char* lang, const int vctype)
1303 /* 1. Find voice info */
1305 GSList *iter = NULL;
1306 ttsvoice_s* data = NULL;
1308 iter = g_slist_nth(g_cur_voices, 0);
1309 while (NULL != iter) {
1310 /*Get handle data from list*/
1314 if (0 == strcmp(data->lang, lang) && data->type == vctype) {
1315 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1316 data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1322 iter = g_slist_next(iter);
1327 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
1328 return TTSD_ERROR_OPERATION_FAILED;
1331 /* 2. increse ref count */
1332 data->client_ref_count++;
1334 /* 3. if ref count change 0 to 1 and not default, load voice */
1335 if (1 == data->client_ref_count && false == data->is_default) {
1337 if (NULL != g_cur_engine.pefuncs->load_voice) {
1338 ret = g_cur_engine.pefuncs->load_voice(data->lang, data->type);
1340 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Load voice : lang(%s), type(%d)",
1341 data->lang, data->type);
1342 data->is_loaded = true;
1344 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
1345 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1347 return TTSD_ERROR_OPERATION_FAILED;
1350 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Load voice of engine function is NULL");
1353 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Not load voice : default voice(%d) or ref count(%d)",
1354 data->is_default, data->client_ref_count);
1357 #ifdef ENGINE_AGENT_DEBUG
1358 ttsd_print_voicelist();
1364 int ttsd_engine_unload_voice(const char* lang, const int vctype)
1366 /* 1. Find voice info */
1368 GSList *iter = NULL;
1369 ttsvoice_s* data = NULL;
1371 iter = g_slist_nth(g_cur_voices, 0);
1372 while (NULL != iter) {
1373 /*Get handle data from list*/
1377 if (0 == strcmp(data->lang, lang) && data->type == vctype) {
1378 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1379 data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1385 iter = g_slist_next(iter);
1390 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
1391 return TTSD_ERROR_OPERATION_FAILED;
1394 /* 2. Decrese ref count */
1395 data->client_ref_count--;
1397 /* 3. if ref count change 0 and not default, load voice */
1398 if (0 == data->client_ref_count && false == data->is_default) {
1400 if (NULL != g_cur_engine.pefuncs->unload_voice) {
1401 ret = g_cur_engine.pefuncs->unload_voice(data->lang, data->type);
1403 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
1404 data->lang, data->type);
1405 data->is_loaded = false;
1407 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
1408 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1410 return TTSD_ERROR_OPERATION_FAILED;
1413 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Unload voice of engine function is NULL");
1416 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Not unload voice : default voice(%d) or ref count(%d)",
1417 data->is_default, data->client_ref_count);
1420 #ifdef ENGINE_AGENT_DEBUG
1421 ttsd_print_voicelist();
1426 int ttsd_engine_start_synthesis(const char* lang, int vctype, const char* text, int speed, const char* credential, void* user_param)
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 /* select voice for default */
1439 char* temp_lang = NULL;
1441 if (true != ttsd_engine_select_valid_voice(lang, vctype, &temp_lang, &temp_type)) {
1442 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to select default voice");
1443 if (NULL != temp_lang) free(temp_lang);
1444 return TTSD_ERROR_INVALID_VOICE;
1446 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Start synthesis : language(%s), type(%d), speed(%d), text(%s), credential(%s)",
1447 temp_lang, temp_type, speed, text, credential);
1450 if (NULL == g_cur_engine.pefuncs->start_synth) {
1451 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] start_synth() of engine is NULL!!");
1452 if (NULL != temp_lang) free(temp_lang);
1453 return TTSD_ERROR_OPERATION_FAILED;
1459 temp_speed = g_cur_engine.default_speed;
1464 /* synthesize text */
1466 ret = g_cur_engine.pefuncs->start_synth(temp_lang, temp_type, text, temp_speed, credential, user_param);
1468 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] ***************************************");
1469 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] * synthesize error : %s *", __ttsd_get_engine_error_code(ret));
1470 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] ***************************************");
1471 if (NULL != temp_lang) free(temp_lang);
1475 if (NULL != temp_lang) free(temp_lang);
1479 int ttsd_engine_cancel_synthesis()
1481 if (false == g_agent_init) {
1482 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1483 return TTSD_ERROR_OPERATION_FAILED;
1486 if (false == g_cur_engine.is_loaded) {
1487 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1488 return TTSD_ERROR_OPERATION_FAILED;
1491 if (NULL == g_cur_engine.pefuncs->cancel_synth) {
1492 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] cancel_synth() of engine is NULL!!");
1493 return TTSD_ERROR_OPERATION_FAILED;
1496 /* stop synthesis */
1498 ret = g_cur_engine.pefuncs->cancel_synth();
1500 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail cancel synthesis : %s", __ttsd_get_engine_error_code(ret));
1501 return TTSD_ERROR_OPERATION_FAILED;
1507 bool __supported_voice_cb(const char* language, int type, void* user_data)
1509 GList** voice_list = (GList**)user_data;
1511 if (NULL == language || NULL == voice_list) {
1512 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
1516 voice_s* voice = calloc(1, sizeof(voice_s));
1517 if (NULL == voice) {
1518 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to allocate memory");
1521 voice->language = strdup(language);
1524 *voice_list = g_list_append(*voice_list, voice);
1529 int ttsd_engine_get_voice_list(GList** voice_list)
1531 if (false == g_agent_init) {
1532 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1533 return TTSD_ERROR_OPERATION_FAILED;
1536 if (false == g_cur_engine.is_loaded) {
1537 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1538 return TTSD_ERROR_OPERATION_FAILED;
1542 ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, (void*)voice_list);
1544 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to get voice list : %s", __ttsd_get_engine_error_code(ret));
1545 return TTSD_ERROR_OPERATION_FAILED;
1551 int ttsd_engine_get_default_voice(char** lang, int* vctype)
1553 if (false == g_agent_init) {
1554 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1555 return TTSD_ERROR_OPERATION_FAILED;
1558 if (false == g_cur_engine.is_loaded) {
1559 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1560 return TTSD_ERROR_OPERATION_FAILED;
1563 if (NULL == lang || NULL == vctype) {
1564 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] BAD Parameter");
1565 return TTSD_ERROR_INVALID_PARAMETER;
1568 if (NULL != g_cur_engine.default_lang) {
1569 *lang = strdup(g_cur_engine.default_lang);
1570 *vctype = g_cur_engine.default_vctype;
1572 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine] Get default voice : language(%s), type(%d)", *lang, *vctype);
1574 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Default voice is NULL");
1575 return TTSD_ERROR_OPERATION_FAILED;
1581 int ttsd_engine_set_private_data(const char* key, const char* data)
1583 if (false == g_agent_init) {
1584 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1585 return TTSD_ERROR_OPERATION_FAILED;
1588 if (false == g_cur_engine.is_loaded) {
1589 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No loaded engine");
1590 return TTSD_ERROR_ENGINE_NOT_FOUND;
1594 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Invalid parameter");
1595 return TTSD_ERROR_INVALID_PARAMETER;
1598 if (NULL == g_cur_engine.pefuncs->set_private_data) {
1599 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not supported feature");
1600 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1604 ret = g_cur_engine.pefuncs->set_private_data(key, data);
1606 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set private data(%d)", ret);
1612 int ttsd_engine_get_private_data(const char* key, char** data)
1614 if (false == g_agent_init) {
1615 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1616 return TTSD_ERROR_OPERATION_FAILED;
1619 if (false == g_cur_engine.is_loaded) {
1620 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No loaded engine");
1621 return TTSD_ERROR_ENGINE_NOT_FOUND;
1624 if (NULL == key || NULL == data) {
1625 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Invalid parameter");
1626 return TTSD_ERROR_INVALID_PARAMETER;
1629 if (NULL == g_cur_engine.pefuncs->get_private_data) {
1630 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not supported feature");
1631 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1636 ret = g_cur_engine.pefuncs->get_private_data(key, &temp);
1638 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to get private data(%d)", ret);
1641 *data = strdup(temp);
1647 void __free_voice_list(GList* voice_list)
1650 voice_s* data = NULL;
1652 /* if list have item */
1653 if (g_list_length(voice_list) > 0) {
1654 /* Get a first item */
1655 iter = g_list_first(voice_list);
1657 while (NULL != iter) {
1661 if (NULL != data->language) free(data->language);
1665 voice_list = g_list_remove_link(voice_list, iter);
1667 iter = g_list_first(voice_list);
1673 * TTS Engine Callback Functions ` *
1675 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)
1677 g_result_cb(event, data, data_size, audio_type, rate, user_data);
1681 /* function for debugging */
1682 int ttsd_print_enginelist()
1685 ttsengine_info_s *data = NULL;
1687 if (g_list_length(g_engine_list) > 0) {
1688 iter = g_list_first(g_engine_list);
1690 SLOG(LOG_DEBUG, get_tag(), "----- engine list -----");
1693 while (NULL != iter) {
1696 SECURE_SLOG(LOG_DEBUG, get_tag(), "[%dth]", i);
1697 SECURE_SLOG(LOG_DEBUG, get_tag(), "engine uuid : %s", data->engine_uuid);
1698 SECURE_SLOG(LOG_DEBUG, get_tag(), "engine name : %s", data->engine_name);
1699 SECURE_SLOG(LOG_DEBUG, get_tag(), "engine path : %s", data->engine_path);
1700 SECURE_SLOG(LOG_DEBUG, get_tag(), "setting ug path : %s", data->setting_ug_path);
1702 iter = g_list_next(iter);
1705 SLOG(LOG_DEBUG, get_tag(), "-----------------------");
1706 SLOG(LOG_DEBUG, get_tag(), " ");
1708 SLOG(LOG_DEBUG, get_tag(), "----- engine list -----");
1709 SLOG(LOG_DEBUG, get_tag(), "No Engine in directory");
1710 SLOG(LOG_DEBUG, get_tag(), "-----------------------");
1716 int ttsd_print_voicelist()
1719 GSList *iter = NULL;
1720 ttsvoice_s* data = NULL;
1722 SLOG(LOG_DEBUG, get_tag(), "=== Voice list ===");
1724 if (g_slist_length(g_cur_voices) > 0) {
1725 /* Get a first item */
1726 iter = g_slist_nth(g_cur_voices, 0);
1729 while (NULL != iter) {
1730 /*Get handle data from list*/
1733 if (NULL == data || NULL == data->lang) {
1734 SLOG(LOG_ERROR, get_tag(), "[ERROR] Data is invalid");
1738 SLOG(LOG_DEBUG, get_tag(), "[%dth] default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1739 i, data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1742 iter = g_slist_next(iter);
1747 SLOG(LOG_DEBUG, get_tag(), "==================");