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 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 g_cur_engine.pdfuncs = (ttspd_funcs_s*)calloc(1, sizeof(ttspd_funcs_s));
156 if (0 != ttsd_config_get_default_voice(&(g_cur_engine.default_lang), &(g_cur_engine.default_vctype))) {
157 SLOG(LOG_WARN, get_tag(), "[Server WARNING] There is No default voice in config");
158 /* Set default voice */
159 g_cur_engine.default_lang = strdup(TTS_BASE_LANGUAGE);
160 g_cur_engine.default_vctype = TTSP_VOICE_TYPE_FEMALE;
163 if (0 != ttsd_config_get_default_speed(&(g_cur_engine.default_speed))) {
164 SLOG(LOG_WARN, get_tag(), "[Server WARNING] There is No default speed in config");
165 g_cur_engine.default_speed = TTS_SPEED_NORMAL;
168 if (0 != ttsd_config_get_default_pitch(&(g_cur_engine.default_pitch))) {
169 SLOG(LOG_WARN, get_tag(), "[Server WARNING] There is No default pitch in config");
170 g_cur_engine.default_pitch = TTS_PITCH_NORMAL;
173 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Initialize Engine Agent");
178 int ttsd_engine_agent_release()
180 if (false == g_agent_init) {
181 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
182 return TTSD_ERROR_OPERATION_FAILED;
185 /* unload current engine */
186 ttsd_engine_agent_unload_current_engine();
188 /* release engine list */
190 ttsengine_info_s *data = NULL;
192 if (g_list_length(g_engine_list) > 0) {
193 /* Get a first item */
194 iter = g_list_first(g_engine_list);
195 while (NULL != iter) {
196 /* Get data from item */
198 iter = g_list_remove(iter, data);
201 if (NULL != data->engine_uuid) free(data->engine_uuid);
202 if (NULL != data->engine_name) free(data->engine_name);
203 if (NULL != data->setting_ug_path) free(data->setting_ug_path);
204 if (NULL != data->engine_path) free(data->engine_path);
211 /* release current engine data */
212 if (g_cur_engine.engine_uuid != NULL) free(g_cur_engine.engine_uuid);
213 if (g_cur_engine.engine_name != NULL) free(g_cur_engine.engine_name);
214 if (g_cur_engine.engine_path != NULL) free(g_cur_engine.engine_path);
216 if (g_cur_engine.pefuncs != NULL) free(g_cur_engine.pefuncs);
217 if (g_cur_engine.pdfuncs != NULL) free(g_cur_engine.pdfuncs);
218 if (g_cur_engine.default_lang != NULL) free(g_cur_engine.default_lang);
220 g_agent_init = false;
222 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Release Engine Agent");
227 int ttsd_engine_agent_initialize_current_engine()
229 if (false == g_agent_init) {
230 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
231 return TTSD_ERROR_OPERATION_FAILED;
234 /* update engine list */
235 if (0 != __internal_update_engine_list()) {
236 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] No engine error");
237 return TTSD_ERROR_OPERATION_FAILED;
240 /* 2. get current engine from config */
241 char* cur_engine_uuid = NULL;
242 bool is_get_engineid_from_config = false;
244 if (0 != ttsd_config_get_default_engine(&cur_engine_uuid)) {
245 /*not set current engine */
246 /*set system default engine*/
248 ttsengine_info_s *data = NULL;
250 if (g_list_length(g_engine_list) > 0) {
251 iter = g_list_first(g_engine_list);
255 if (NULL != data->engine_uuid) {
256 cur_engine_uuid = strdup(data->engine_uuid);
257 ttsd_config_set_default_engine(cur_engine_uuid);
259 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Data of current engine is corrupt");
260 return TTSD_ERROR_OPERATION_FAILED;
264 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] Fail to set a engine of engine list");
265 return TTSD_ERROR_OPERATION_FAILED;
268 is_get_engineid_from_config = false;
270 is_get_engineid_from_config = true;
273 if (NULL == cur_engine_uuid) {
274 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Current engine id is NULL");
275 return TTSD_ERROR_OPERATION_FAILED;
278 /* check whether cur engine uuid is valid or not. */
279 if (0 != __internal_check_engine_id(cur_engine_uuid)) {
280 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] It is not valid engine id from config");
284 if (g_list_length(g_engine_list) > 0)
285 iter = g_list_first(g_engine_list);
287 SLOG(LOG_WARN, get_tag(), "[Engine Agent ERROR] NO TTS Engine !!");
288 if (NULL != cur_engine_uuid) free(cur_engine_uuid);
289 return TTSD_ERROR_OPERATION_FAILED;
292 if (cur_engine_uuid != NULL) free(cur_engine_uuid);
293 ttsengine_info_s *data = NULL;
296 cur_engine_uuid = strdup(data->engine_uuid);
298 is_get_engineid_from_config = false;
301 if (NULL != cur_engine_uuid)
302 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Current Engine Id : %s", cur_engine_uuid);
304 return TTSD_ERROR_OPERATION_FAILED;
306 /* set current engine */
307 if (0 != __internal_set_current_engine(cur_engine_uuid)) {
308 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to set current engine ");
309 if (NULL != cur_engine_uuid) free(cur_engine_uuid);
310 return TTSD_ERROR_OPERATION_FAILED;
313 if (false == is_get_engineid_from_config) {
314 if (0 != ttsd_config_set_default_engine(cur_engine_uuid)) {
315 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to set id to config");
319 if (NULL != cur_engine_uuid) free(cur_engine_uuid);
321 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set current engine");
326 static int __internal_check_engine_id(const char* engine_uuid)
329 ttsengine_s *data = NULL;
331 if (g_list_length(g_engine_list) > 0) {
332 iter = g_list_first(g_engine_list);
334 while (NULL != iter) {
337 if (0 == strncmp(engine_uuid, data->engine_uuid, strlen(data->engine_uuid)))
340 iter = g_list_next(iter);
347 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* setting_ug_name,
348 bool use_network, void* user_data)
350 ttsengine_info_s* temp = (ttsengine_info_s*)user_data;
352 if (NULL != engine_uuid)
353 temp->engine_uuid = strdup(engine_uuid);
355 if (NULL != engine_name)
356 temp->engine_name = strdup(engine_name);
358 if (NULL != setting_ug_name)
359 temp->setting_ug_path = strdup(setting_ug_name);
361 temp->use_network = use_network;
365 static int __internal_get_engine_info(const char* filepath, ttsengine_info_s** info)
370 handle = dlopen(filepath, RTLD_LAZY);
373 SECURE_SLOG(LOG_WARN, get_tag(), "[Engine Agent] Invalid engine : %s", filepath);
374 return TTSD_ERROR_OPERATION_FAILED;
377 /* link engine to daemon */
378 dlsym(handle, "ttsp_load_engine");
379 if ((error = dlerror()) != NULL) {
380 SECURE_SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to open ttsp_load_engine : path(%s) message(%s)", filepath, error);
382 return TTSD_ERROR_OPERATION_FAILED;
385 dlsym(handle, "ttsp_unload_engine");
386 if ((error = dlerror()) != NULL) {
387 SECURE_SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to open ttsp_unload_engine : path(%s) message(%s)", filepath, error);
389 return TTSD_ERROR_OPERATION_FAILED;
392 int (*get_engine_info)(ttsp_engine_info_cb callback, void* user_data);
394 get_engine_info = (int (*)(ttsp_engine_info_cb, void*))dlsym(handle, "ttsp_get_engine_info");
395 if (NULL != (error = dlerror()) || NULL == get_engine_info) {
396 SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to open ttsp_get_engine_info() :path(%s) message(%s)", filepath, error);
398 return TTSD_ERROR_OPERATION_FAILED;
401 ttsengine_info_s* temp;
402 temp = (ttsengine_info_s*)calloc(1, sizeof(ttsengine_info_s));
404 SLOG(LOG_WARN, get_tag(), "[Engine Agent] Fail to alloc memory");
406 return TTSD_ERROR_OUT_OF_MEMORY;
409 /* get engine info */
410 if (0 != get_engine_info(&__engine_info_cb, (void*)temp)) {
411 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to get engine info");
414 return TTSD_ERROR_OPERATION_FAILED;
420 if (TTSD_MODE_SCREEN_READER == ttsd_get_mode() && true == temp->use_network) {
421 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent WARNING] %s is invalid because of network based", temp->engine_name);
422 if (NULL != temp->engine_uuid) free(temp->engine_uuid);
423 if (NULL != temp->engine_name) free(temp->engine_name);
424 if (NULL != temp->setting_ug_path) free(temp->setting_ug_path);
426 return TTSD_ERROR_OPERATION_FAILED;
429 temp->engine_path = strdup(filepath);
431 SLOG(LOG_DEBUG, get_tag(), "----- Valid engine");
432 SECURE_SLOG(LOG_DEBUG, get_tag(), "Engine uuid : %s", temp->engine_uuid);
433 SECURE_SLOG(LOG_DEBUG, get_tag(), "Engine name : %s", temp->engine_name);
434 SECURE_SLOG(LOG_DEBUG, get_tag(), "Setting path : %s", temp->setting_ug_path);
435 SECURE_SLOG(LOG_DEBUG, get_tag(), "Engine path : %s", temp->engine_path);
436 SECURE_SLOG(LOG_DEBUG, get_tag(), "Use network : %s", temp->use_network ? "true" : "false");
437 SLOG(LOG_DEBUG, get_tag(), "-----");
438 SLOG(LOG_DEBUG, get_tag(), " ");
445 static int __internal_update_engine_list()
447 /* relsease engine list */
449 ttsengine_info_s *data = NULL;
451 if (g_list_length(g_engine_list) > 0) {
452 iter = g_list_first(g_engine_list);
454 while (NULL != iter) {
457 if (data != NULL) free(data);
458 g_engine_list = g_list_remove_link(g_engine_list, iter);
460 iter = g_list_first(g_engine_list);
464 /* get file name from engine directory and get engine information from each filename */
468 struct dirent *dirp = NULL;
469 dp = opendir(TTS_DEFAULT_ENGINE);
473 ret = readdir_r(dp, &entry, &dirp);
475 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to read directory");
480 ttsengine_info_s* info;
481 char* filepath = NULL;
484 file_size = strlen(TTS_DEFAULT_ENGINE) + strlen(dirp->d_name) + 5;
485 filepath = (char*)calloc(file_size, sizeof(char));
487 if (NULL != filepath) {
488 snprintf(filepath, file_size, "%s/%s", TTS_DEFAULT_ENGINE, dirp->d_name);
490 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not enough memory!!");
494 /* get its info and update engine list */
495 if (0 == __internal_get_engine_info(filepath, &info)) {
496 /* add engine info to g_engine_list */
497 g_engine_list = g_list_append(g_engine_list, info);
500 if (NULL != filepath) free(filepath);
502 } while (NULL != dirp);
507 if (g_list_length(g_engine_list) <= 0) {
508 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No Engine");
509 return TTSD_ERROR_OPERATION_FAILED;
512 #ifdef ENGINE_AGENT_DEBUG
513 ttsd_print_enginelist();
518 static int __internal_set_current_engine(const char* engine_uuid)
520 /* check whether engine id is valid or not. */
522 ttsengine_info_s *data = NULL;
525 if (g_list_length(g_engine_list) > 0) {
526 iter = g_list_first(g_engine_list);
528 while (NULL != iter) {
531 if (0 == strncmp(data->engine_uuid, engine_uuid, strlen(engine_uuid))) {
537 iter = g_list_next(iter);
541 /* If current engine does not exist, return error */
543 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Cannot find engine id");
544 return TTSD_ERROR_OPERATION_FAILED;
546 if (g_cur_engine.engine_uuid != NULL) {
547 /*compare current engine uuid */
548 if (0 == strncmp(g_cur_engine.engine_uuid, data->engine_uuid, strlen(engine_uuid))) {
549 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] tts engine has already been set");
555 /* set data from g_engine_list */
556 if (g_cur_engine.engine_uuid != NULL) free(g_cur_engine.engine_uuid);
557 if (g_cur_engine.engine_name != NULL) free(g_cur_engine.engine_name);
558 if (g_cur_engine.engine_path != NULL) free(g_cur_engine.engine_path);
560 if (NULL == data->engine_uuid || NULL == data->engine_name || NULL == data->engine_path) {
561 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Engine data is NULL");
562 return TTSD_ERROR_OPERATION_FAILED;
565 g_cur_engine.engine_uuid = strdup(data->engine_uuid);
566 g_cur_engine.engine_name = strdup(data->engine_name);
567 g_cur_engine.engine_path = strdup(data->engine_path);
569 g_cur_engine.handle = NULL;
570 g_cur_engine.is_loaded = false;
571 g_cur_engine.is_set = true;
572 g_cur_engine.need_network = data->use_network;
574 SLOG(LOG_DEBUG, get_tag(), "-----");
575 SECURE_SLOG(LOG_DEBUG, get_tag(), "Current engine uuid : %s", g_cur_engine.engine_uuid);
576 SECURE_SLOG(LOG_DEBUG, get_tag(), "Current engine name : %s", g_cur_engine.engine_name);
577 SECURE_SLOG(LOG_DEBUG, get_tag(), "Current engine path : %s", g_cur_engine.engine_path);
578 SLOG(LOG_DEBUG, get_tag(), "-----");
583 int __ttsd_get_mode(ttsp_mode_e* mode)
586 SLOG(LOG_ERROR, get_tag(), "[ERROR] Input parameter is null");
587 return TTSP_ERROR_INVALID_PARAMETER;
590 switch (ttsd_get_mode()) {
591 case TTSD_MODE_DEFAULT: *mode = TTSP_MODE_DEFAULT; break;
592 case TTSD_MODE_NOTIFICATION: *mode = TTSP_MODE_NOTIFICATION; break;
593 case TTSD_MODE_SCREEN_READER: *mode = TTSP_MODE_SCREEN_READER; break;
595 SLOG(LOG_ERROR, get_tag(), "[ERROR] tts mode is NOT valid");
601 int __ttsd_engine_agent_get_speed_range(int* min, int* normal, int* max)
603 if (NULL == min || NULL == normal || NULL == max) {
604 SLOG(LOG_ERROR, get_tag(), "[ERROR] Input parameter is null");
605 return TTSP_ERROR_INVALID_PARAMETER;
608 *min = TTS_SPEED_MIN;
609 *normal = TTS_SPEED_NORMAL;
610 *max = TTS_SPEED_MAX;
615 int __ttsd_engine_agent_get_pitch_range(int* min, int* normal, int* max)
617 if (NULL == min || NULL == normal || NULL == max) {
618 SLOG(LOG_ERROR, get_tag(), "[ERROR] Input parameter is null");
619 return TTSP_ERROR_INVALID_PARAMETER;
622 *min = TTS_PITCH_MIN;
623 *normal = TTS_PITCH_NORMAL;
624 *max = TTS_PITCH_MAX;
629 static bool __set_voice_info_cb(const char* language, int type, void* user_data)
631 if (NULL == language) {
632 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
636 ttsvoice_s* voice = calloc(1, sizeof(ttsvoice_s));
638 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to allocate memory");
641 voice->lang = strdup(language);
644 voice->client_ref_count = 0;
645 voice->is_loaded = false;
647 if (0 == strcmp(g_cur_engine.default_lang, language) && g_cur_engine.default_vctype == type) {
648 voice->is_default = true;
649 voice->is_loaded = true;
651 voice->is_default = false;
654 g_cur_voices = g_slist_append(g_cur_voices, voice);
659 static int __update_voice_list()
665 ret = g_cur_engine.pefuncs->foreach_voices(__set_voice_info_cb, NULL);
666 if (0 != ret || 0 >= g_slist_length(g_cur_voices)) {
667 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
671 #ifdef ENGINE_AGENT_DEBUG
672 ttsd_print_voicelist();
677 int ttsd_engine_agent_load_current_engine()
679 if (false == g_agent_init) {
680 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
681 return TTSD_ERROR_OPERATION_FAILED;
684 if (false == g_cur_engine.is_set) {
685 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No Current Engine ");
686 return TTSD_ERROR_OPERATION_FAILED;
689 /* check whether current engine is loaded or not */
690 if (true == g_cur_engine.is_loaded) {
691 SLOG(LOG_ERROR, get_tag(), "[Engine Agent] Engine has already been loaded ");
697 g_cur_engine.handle = dlopen(g_cur_engine.engine_path, RTLD_LAZY); /* RTLD_LAZY RTLD_NOW*/
699 if (NULL != (error = dlerror()) || NULL == g_cur_engine.handle) {
700 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to get current engine handle : %s", error);
704 g_cur_engine.ttsp_unload_engine = (int (*)())dlsym(g_cur_engine.handle, "ttsp_unload_engine");
705 if (NULL != (error = dlerror()) || NULL == g_cur_engine.ttsp_unload_engine) {
706 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to link daemon to ttsp_unload_engine() : %s", error);
710 g_cur_engine.ttsp_load_engine = (int (*)(const ttspd_funcs_s* , ttspe_funcs_s*))dlsym(g_cur_engine.handle, "ttsp_load_engine");
711 if (NULL != (error = dlerror()) || NULL == g_cur_engine.ttsp_load_engine) {
712 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to link daemon to ttsp_load_engine() : %s", error);
717 g_cur_engine.pdfuncs->version = 1;
718 g_cur_engine.pdfuncs->size = sizeof(ttspd_funcs_s);
719 g_cur_engine.pdfuncs->get_mode = __ttsd_get_mode;
720 g_cur_engine.pdfuncs->get_speed_range = __ttsd_engine_agent_get_speed_range;
721 g_cur_engine.pdfuncs->get_pitch_range = __ttsd_engine_agent_get_pitch_range;
724 ret = g_cur_engine.ttsp_load_engine(g_cur_engine.pdfuncs, g_cur_engine.pefuncs);
726 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to load engine - %s : result(%s)",
727 g_cur_engine.engine_path, __ttsd_get_engine_error_code(ret));
728 return TTSD_ERROR_OPERATION_FAILED;
731 /* engine error check */
732 if (g_cur_engine.pefuncs->size != sizeof(ttspe_funcs_s)) {
733 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] The size of engine function is not valid");
736 if (NULL == g_cur_engine.pefuncs->initialize ||
737 NULL == g_cur_engine.pefuncs->deinitialize ||
738 NULL == g_cur_engine.pefuncs->foreach_voices ||
739 NULL == g_cur_engine.pefuncs->is_valid_voice ||
740 NULL == g_cur_engine.pefuncs->start_synth ||
741 NULL == g_cur_engine.pefuncs->cancel_synth) {
742 SLOG(LOG_ERROR, get_tag(), "[Engine ERROR] The engine functions are NOT valid");
743 return TTSD_ERROR_OPERATION_FAILED;
746 ret = g_cur_engine.pefuncs->initialize(__result_cb);
748 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to initialize current engine : %s", __ttsd_get_engine_error_code(ret));
749 return TTSD_ERROR_OPERATION_FAILED;
752 /* Get voice info of current engine */
753 ret = __update_voice_list();
755 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set voice info : result(%d)", ret);
756 return TTSD_ERROR_OPERATION_FAILED;
759 /* Select default voice */
760 if (NULL != g_cur_engine.default_lang) {
761 if (true == g_cur_engine.pefuncs->is_valid_voice(g_cur_engine.default_lang, g_cur_engine.default_vctype)) {
762 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set origin default voice to current engine : lang(%s), type(%d)",
763 g_cur_engine.default_lang, g_cur_engine.default_vctype);
765 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] Fail set origin default voice : lang(%s), type(%d)",
766 g_cur_engine.default_lang, g_cur_engine.default_vctype);
768 return TTSD_ERROR_OPERATION_FAILED;
772 /* load default voice */
773 if (NULL != g_cur_engine.pefuncs->load_voice) {
774 ret = g_cur_engine.pefuncs->load_voice(g_cur_engine.default_lang, g_cur_engine.default_vctype);
776 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Load default voice : lang(%s), type(%d)",
777 g_cur_engine.default_lang, g_cur_engine.default_vctype);
779 SLOG(LOG_WARN, get_tag(), "[Engine Agent ERROR] Fail to load default voice : lang(%s), type(%d) result(%s)",
780 g_cur_engine.default_lang, g_cur_engine.default_vctype, __ttsd_get_engine_error_code(ret));
782 return TTSD_ERROR_OPERATION_FAILED;
786 /* set default pitch */
787 if (NULL != g_cur_engine.pefuncs->set_pitch) {
788 ret = g_cur_engine.pefuncs->set_pitch(g_cur_engine.default_pitch);
790 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)",
791 g_cur_engine.default_pitch, __ttsd_get_engine_error_code(ret));
792 return TTSD_ERROR_OPERATION_FAILED;
794 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set default pitch : pitch(%d)", g_cur_engine.default_pitch);
798 if (false == set_voice) {
799 /* get language list */
801 GList* voice_list = NULL;
803 ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, &voice_list);
805 if (0 == ret && 0 < g_list_length(voice_list)) {
807 voice_s* voice = NULL;
809 iter = g_list_first(voice_list);
812 while (NULL != iter) {
816 if (0 == strcmp("en_US", voice->language))
820 iter = g_list_next(iter);
823 SLOG(LOG_ERROR, get_tag(), "[Engine ERROR] Fail to find voice in list");
824 return TTSD_ERROR_OPERATION_FAILED;
827 /* Set selected language and type */
828 if (true != g_cur_engine.pefuncs->is_valid_voice(voice->language, voice->type)) {
829 SLOG(LOG_ERROR, get_tag(), "[Engine ERROR] Fail voice is NOT valid");
830 return TTSD_ERROR_OPERATION_FAILED;
833 ttsd_config_set_default_voice(voice->language, (int)voice->type);
835 g_cur_engine.default_lang = strdup(voice->language);
836 g_cur_engine.default_vctype = voice->type;
838 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Select default voice : lang(%s), type(%d)",
839 voice->language, voice->type);
841 __free_voice_list(voice_list);
843 SLOG(LOG_ERROR, get_tag(), "[Engine ERROR] Fail to get language list : result(%d)", ret);
844 return TTSD_ERROR_OPERATION_FAILED;
848 g_cur_engine.is_loaded = true;
853 int ttsd_engine_agent_unload_current_engine()
855 if (false == g_agent_init) {
856 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
857 return TTSD_ERROR_OPERATION_FAILED;
860 if (false == g_cur_engine.is_set) {
861 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No Current Engine ");
862 return TTSD_ERROR_OPERATION_FAILED;
865 if (false == g_cur_engine.is_loaded) {
866 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Engine has already been unloaded ");
870 /* shutdown engine */
872 ret = g_cur_engine.pefuncs->deinitialize();
874 SLOG(LOG_ERROR, get_tag(), "[Engine Agent] Fail deinitialize() : %s", __ttsd_get_engine_error_code(ret));
878 g_cur_engine.ttsp_unload_engine();
880 dlclose(g_cur_engine.handle);
882 /* reset current engine data */
883 g_cur_engine.handle = NULL;
884 g_cur_engine.is_loaded = false;
887 ttsvoice_s* data = NULL;
889 iter = g_slist_nth(g_cur_voices, 0);
890 while (NULL != iter) {
894 if (NULL != data->lang) free(data->lang);
895 g_cur_voices = g_slist_remove(g_cur_voices, data);
900 iter = g_slist_nth(g_cur_voices, 0);
906 bool ttsd_engine_agent_need_network()
908 if (false == g_agent_init) {
909 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
910 return TTSD_ERROR_OPERATION_FAILED;
913 if (false == g_cur_engine.is_loaded) {
914 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
915 return TTSD_ERROR_OPERATION_FAILED;
918 return g_cur_engine.need_network;
921 bool ttsd_engine_select_valid_voice(const char* lang, int type, char** out_lang, int* out_type)
923 if (NULL == lang || NULL == out_lang || NULL == out_type) {
927 if (false == g_cur_engine.is_loaded) {
928 SLOG(LOG_WARN, get_tag(), "[Engine Agent WARNING] Not loaded engine");
932 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Select voice : input lang(%s), input type(%d), default lang(%s), default type(%d)",
933 lang, type, g_cur_engine.default_lang, g_cur_engine.default_vctype);
935 /* case 1 : Both are default */
936 if (0 == strncmp(lang, "default", strlen("default")) && 0 == type) {
937 *out_lang = strdup(g_cur_engine.default_lang);
938 *out_type = g_cur_engine.default_vctype;
943 GList* voice_list = NULL;
946 ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, &voice_list);
947 if (0 != ret || 0 >= g_list_length(voice_list)) {
948 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
958 /* lang and type are not default type */
959 if (0 != strncmp(lang, "default", strlen("default")) && 0 != type) {
960 iter = g_list_first(voice_list);
962 while (NULL != iter) {
963 /* Get handle data from list */
966 if (0 == strncmp(voice->language, lang, strlen(lang)) && voice->type == type) {
967 *out_lang = strdup(voice->language);
968 *out_type = voice->type;
973 iter = g_list_next(iter);
976 } else if (0 != strncmp(lang, "default", strlen("default")) && 0 == type) {
977 /* Only type is default */
978 if (0 == strncmp(lang, g_cur_engine.default_lang, strlen(g_cur_engine.default_lang))) {
979 *out_lang = strdup(g_cur_engine.default_lang);
980 *out_type = g_cur_engine.default_vctype;
983 voice_s* voice_selected = NULL;
984 iter = g_list_first(voice_list);
985 while (NULL != iter) {
986 /* Get handle data from list */
989 if (0 == strncmp(voice->language, lang, strlen(lang))) {
990 voice_selected = voice;
991 if (voice->type == g_cur_engine.default_vctype) {
992 voice_selected = voice;
996 iter = g_list_next(iter);
999 if (NULL != voice_selected) {
1000 *out_lang = strdup(voice_selected->language);
1001 *out_type = voice_selected->type;
1005 } else if (0 == strncmp(lang, "default", strlen("default")) && 0 != type) {
1006 /* Only lang is default */
1007 if (type == g_cur_engine.default_vctype) {
1008 *out_lang = strdup(g_cur_engine.default_lang);
1009 *out_type = g_cur_engine.default_vctype;
1012 voice_s* voice_selected = NULL;
1013 iter = g_list_first(voice_list);
1014 while (NULL != iter) {
1015 /* Get handle data from list */
1018 if (0 == strncmp(voice->language, g_cur_engine.default_lang, strlen(g_cur_engine.default_lang))) {
1019 voice_selected = voice;
1020 if (voice->type == type) {
1021 voice_selected = voice;
1025 iter = g_list_next(iter);
1028 if (NULL != voice_selected) {
1029 *out_lang = strdup(voice->language);
1030 *out_type = voice_selected->type;
1036 if (true == result) {
1037 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Selected voice : lang(%s), type(%d)", *out_lang, *out_type);
1040 __free_voice_list(voice_list);
1045 bool ttsd_engine_agent_is_same_engine(const char* engine_id)
1047 if (false == g_agent_init) {
1048 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1052 if (false == g_cur_engine.is_loaded) {
1053 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1057 /* compare current engine and engine id.*/
1058 if (0 == strncmp(g_cur_engine.engine_uuid, engine_id, strlen(engine_id))) {
1065 int ttsd_engine_agent_set_default_engine(const char* engine_id)
1067 if (false == g_agent_init) {
1068 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1069 return TTSD_ERROR_OPERATION_FAILED;
1072 /* compare current engine and new engine.*/
1073 if (0 == strncmp(g_cur_engine.engine_uuid, engine_id, strlen(engine_id))) {
1074 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] new engine(%s) is the same as current engine", engine_id);
1078 bool is_engine_loaded = false;
1079 char* tmp_uuid = NULL;
1080 tmp_uuid = strdup(g_cur_engine.engine_uuid);
1081 if (NULL == tmp_uuid) {
1082 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Current engine id is NULL");
1083 return TTSD_ERROR_OPERATION_FAILED;
1086 is_engine_loaded = g_cur_engine.is_loaded;
1088 if (true == is_engine_loaded) {
1090 if (0 != ttsd_engine_agent_unload_current_engine()) {
1091 SLOG(LOG_ERROR, get_tag(), "[Engine Agent Error] fail to unload current engine");
1095 /* change current engine */
1096 if (0 != __internal_set_current_engine(engine_id)) {
1097 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set current engine. Recovery origin engine");
1099 /* roll back to old current engine. */
1100 __internal_set_current_engine(tmp_uuid);
1101 if (true == is_engine_loaded) {
1102 ttsd_engine_agent_load_current_engine();
1105 if (tmp_uuid != NULL) free(tmp_uuid);
1106 return TTSD_ERROR_OPERATION_FAILED;
1109 if (true == is_engine_loaded) {
1111 if (0 != ttsd_engine_agent_load_current_engine()) {
1112 SLOG(LOG_ERROR, get_tag(), "[Engine Agent Error] Fail to load new engine. Recovery origin engine");
1114 /* roll back to old current engine. */
1115 __internal_set_current_engine(tmp_uuid);
1116 if (true == is_engine_loaded) {
1117 ttsd_engine_agent_load_current_engine();
1120 if (tmp_uuid != NULL) free(tmp_uuid);
1121 return TTSD_ERROR_OPERATION_FAILED;
1123 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] load new engine : %s", engine_id);
1127 if (tmp_uuid != NULL) free(tmp_uuid);
1131 int ttsd_engine_agent_set_default_voice(const char* language, int vctype)
1133 if (false == g_agent_init) {
1134 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1135 return TTSD_ERROR_OPERATION_FAILED;
1138 if (false == g_cur_engine.is_loaded) {
1139 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1140 return TTSD_ERROR_OPERATION_FAILED;
1143 if (false == g_cur_engine.pefuncs->is_valid_voice(language, vctype)) {
1144 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Voice is NOT valid !!");
1145 return TTSD_ERROR_INVALID_VOICE;
1149 GSList *iter = NULL;
1150 ttsvoice_s* data = NULL;
1152 /* Update new 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, language) && data->type == vctype) {
1164 data->is_default = true;
1165 if (0 == data->client_ref_count) {
1167 if (NULL != g_cur_engine.pefuncs->load_voice) {
1168 ret = g_cur_engine.pefuncs->load_voice(data->lang, data->type);
1170 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] load voice : lang(%s), type(%d)",
1171 data->lang, data->type);
1172 data->is_loaded = true;
1174 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to load 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] Load voice of engine function is NULL");
1185 iter = g_slist_next(iter);
1188 #ifdef ENGINE_AGENT_DEBUG
1189 ttsd_print_voicelist();
1192 /* Update old default voice info */
1193 iter = g_slist_nth(g_cur_voices, 0);
1194 while (NULL != iter) {
1195 /*Get handle data from list*/
1199 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Voice data is NULL");
1200 return TTSD_ERROR_OPERATION_FAILED;
1203 if (0 == strcmp(data->lang, g_cur_engine.default_lang) && data->type == g_cur_engine.default_vctype) {
1204 data->is_default = false;
1205 if (0 == data->client_ref_count) {
1207 if (NULL != g_cur_engine.pefuncs->unload_voice) {
1208 ret = g_cur_engine.pefuncs->unload_voice(data->lang, data->type);
1210 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
1211 data->lang, data->type);
1212 data->is_loaded = false;
1214 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
1215 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1218 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Unload voice of engine function is NULL");
1225 iter = g_slist_next(iter);
1228 if (NULL != g_cur_engine.default_lang) free(g_cur_engine.default_lang);
1230 g_cur_engine.default_lang = strdup(language);
1231 g_cur_engine.default_vctype = vctype;
1233 #ifdef ENGINE_AGENT_DEBUG
1234 ttsd_print_voicelist();
1237 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Set default voice : lang(%s), type(%d)",
1238 g_cur_engine.default_lang, g_cur_engine.default_vctype);
1243 int ttsd_engine_agent_set_default_speed(int speed)
1245 if (false == g_agent_init) {
1246 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1247 return TTSD_ERROR_OPERATION_FAILED;
1250 g_cur_engine.default_speed = speed;
1255 int ttsd_engine_agent_set_default_pitch(int pitch)
1257 if (false == g_agent_init) {
1258 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1259 return TTSD_ERROR_OPERATION_FAILED;
1262 if (false == g_cur_engine.is_loaded) {
1263 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1264 return TTSD_ERROR_OPERATION_FAILED;
1267 if (NULL == g_cur_engine.pefuncs->set_pitch) {
1268 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not support pitch");
1269 return TTSD_ERROR_OPERATION_FAILED;
1272 int ret = g_cur_engine.pefuncs->set_pitch(pitch);
1274 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)",
1275 pitch, __ttsd_get_engine_error_code(ret));
1276 return TTSD_ERROR_OPERATION_FAILED;
1279 g_cur_engine.default_pitch = pitch;
1284 int ttsd_engine_agent_is_credential_needed(int uid, bool* credential_needed)
1286 if (NULL == credential_needed) {
1287 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Invalid Parameter");
1288 return TTSP_ERROR_INVALID_PARAMETER;
1291 if (false == g_agent_init) {
1292 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1293 return TTSD_ERROR_OPERATION_FAILED;
1296 if (false == g_cur_engine.is_loaded) {
1297 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1298 return TTSD_ERROR_OPERATION_FAILED;
1301 if (NULL == g_cur_engine.pefuncs->need_app_credential) {
1302 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not support to check app credential");
1303 return TTSD_ERROR_OPERATION_FAILED;
1306 bool result = false;
1307 result = g_cur_engine.pefuncs->need_app_credential();
1308 *credential_needed = result;
1310 return TTSP_ERROR_NONE;
1313 /******************************************************************************************
1314 * TTS Engine Interfaces for client
1315 *******************************************************************************************/
1317 int ttsd_engine_load_voice(const char* lang, const int vctype)
1319 /* 1. Find voice info */
1321 GSList *iter = NULL;
1322 ttsvoice_s* data = NULL;
1324 iter = g_slist_nth(g_cur_voices, 0);
1325 while (NULL != iter) {
1326 /*Get handle data from list*/
1330 if (0 == strcmp(data->lang, lang) && data->type == vctype) {
1331 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1332 data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1338 iter = g_slist_next(iter);
1343 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
1344 return TTSD_ERROR_OPERATION_FAILED;
1347 /* 2. increse ref count */
1348 data->client_ref_count++;
1350 /* 3. if ref count change 0 to 1 and not default, load voice */
1351 if (1 == data->client_ref_count && false == data->is_default) {
1353 if (NULL != g_cur_engine.pefuncs->load_voice) {
1354 ret = g_cur_engine.pefuncs->load_voice(data->lang, data->type);
1356 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Load voice : lang(%s), type(%d)",
1357 data->lang, data->type);
1358 data->is_loaded = true;
1360 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
1361 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1363 return TTSD_ERROR_OPERATION_FAILED;
1366 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Load voice of engine function is NULL");
1369 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Not load voice : default voice(%d) or ref count(%d)",
1370 data->is_default, data->client_ref_count);
1373 #ifdef ENGINE_AGENT_DEBUG
1374 ttsd_print_voicelist();
1380 int ttsd_engine_unload_voice(const char* lang, const int vctype)
1382 /* 1. Find voice info */
1384 GSList *iter = NULL;
1385 ttsvoice_s* data = NULL;
1387 iter = g_slist_nth(g_cur_voices, 0);
1388 while (NULL != iter) {
1389 /*Get handle data from list*/
1393 if (0 == strcmp(data->lang, lang) && data->type == vctype) {
1394 SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1395 data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1401 iter = g_slist_next(iter);
1406 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
1407 return TTSD_ERROR_OPERATION_FAILED;
1410 /* 2. Decrese ref count */
1411 data->client_ref_count--;
1413 /* 3. if ref count change 0 and not default, load voice */
1414 if (0 == data->client_ref_count && false == data->is_default) {
1416 if (NULL != g_cur_engine.pefuncs->unload_voice) {
1417 ret = g_cur_engine.pefuncs->unload_voice(data->lang, data->type);
1419 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
1420 data->lang, data->type);
1421 data->is_loaded = false;
1423 SECURE_SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
1424 data->lang, data->type, __ttsd_get_engine_error_code(ret));
1426 return TTSD_ERROR_OPERATION_FAILED;
1429 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent ERROR] Unload voice of engine function is NULL");
1432 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Not unload voice : default voice(%d) or ref count(%d)",
1433 data->is_default, data->client_ref_count);
1436 #ifdef ENGINE_AGENT_DEBUG
1437 ttsd_print_voicelist();
1442 int ttsd_engine_start_synthesis(const char* lang, int vctype, const char* text, int speed, const char* credential, void* user_param)
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 /* select voice for default */
1455 char* temp_lang = NULL;
1457 if (true != ttsd_engine_select_valid_voice(lang, vctype, &temp_lang, &temp_type)) {
1458 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to select default voice");
1459 if (NULL != temp_lang) free(temp_lang);
1460 return TTSD_ERROR_INVALID_VOICE;
1462 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine Agent] Start synthesis : language(%s), type(%d), speed(%d), text(%s), credential(%s)",
1463 temp_lang, temp_type, speed, text, credential);
1466 if (NULL == g_cur_engine.pefuncs->start_synth) {
1467 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] start_synth() of engine is NULL!!");
1468 if (NULL != temp_lang) free(temp_lang);
1469 return TTSD_ERROR_OPERATION_FAILED;
1475 temp_speed = g_cur_engine.default_speed;
1480 /* synthesize text */
1482 ret = g_cur_engine.pefuncs->start_synth(temp_lang, temp_type, text, temp_speed, credential, user_param);
1484 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] ***************************************");
1485 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] * synthesize error : %s *", __ttsd_get_engine_error_code(ret));
1486 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] ***************************************");
1487 if (NULL != temp_lang) free(temp_lang);
1491 if (NULL != temp_lang) free(temp_lang);
1495 int ttsd_engine_cancel_synthesis()
1497 if (false == g_agent_init) {
1498 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1499 return TTSD_ERROR_OPERATION_FAILED;
1502 if (false == g_cur_engine.is_loaded) {
1503 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1504 return TTSD_ERROR_OPERATION_FAILED;
1507 if (NULL == g_cur_engine.pefuncs->cancel_synth) {
1508 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] cancel_synth() of engine is NULL!!");
1509 return TTSD_ERROR_OPERATION_FAILED;
1512 /* stop synthesis */
1514 ret = g_cur_engine.pefuncs->cancel_synth();
1516 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] fail cancel synthesis : %s", __ttsd_get_engine_error_code(ret));
1517 return TTSD_ERROR_OPERATION_FAILED;
1523 bool __supported_voice_cb(const char* language, int type, void* user_data)
1525 GList** voice_list = (GList**)user_data;
1527 if (NULL == language || NULL == voice_list) {
1528 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
1532 voice_s* voice = calloc(1, sizeof(voice_s));
1533 if (NULL == voice) {
1534 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to allocate memory");
1537 voice->language = strdup(language);
1540 *voice_list = g_list_append(*voice_list, voice);
1545 int ttsd_engine_get_voice_list(GList** voice_list)
1547 if (false == g_agent_init) {
1548 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1549 return TTSD_ERROR_OPERATION_FAILED;
1552 if (false == g_cur_engine.is_loaded) {
1553 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1554 return TTSD_ERROR_OPERATION_FAILED;
1558 ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, (void*)voice_list);
1560 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to get voice list : %s", __ttsd_get_engine_error_code(ret));
1561 return TTSD_ERROR_OPERATION_FAILED;
1567 int ttsd_engine_get_default_voice(char** lang, int* vctype)
1569 if (false == g_agent_init) {
1570 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1571 return TTSD_ERROR_OPERATION_FAILED;
1574 if (false == g_cur_engine.is_loaded) {
1575 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not loaded engine");
1576 return TTSD_ERROR_OPERATION_FAILED;
1579 if (NULL == lang || NULL == vctype) {
1580 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] BAD Parameter");
1581 return TTSD_ERROR_INVALID_PARAMETER;
1584 if (NULL != g_cur_engine.default_lang) {
1585 *lang = strdup(g_cur_engine.default_lang);
1586 *vctype = g_cur_engine.default_vctype;
1588 SECURE_SLOG(LOG_DEBUG, get_tag(), "[Engine] Get default voice : language(%s), type(%d)", *lang, *vctype);
1590 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Default voice is NULL");
1591 return TTSD_ERROR_OPERATION_FAILED;
1597 int ttsd_engine_set_private_data(const char* key, const char* data)
1599 if (false == g_agent_init) {
1600 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1601 return TTSD_ERROR_OPERATION_FAILED;
1604 if (false == g_cur_engine.is_loaded) {
1605 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No loaded engine");
1606 return TTSD_ERROR_ENGINE_NOT_FOUND;
1610 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Invalid parameter");
1611 return TTSD_ERROR_INVALID_PARAMETER;
1614 if (NULL == g_cur_engine.pefuncs->set_private_data) {
1615 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not supported feature");
1616 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1620 ret = g_cur_engine.pefuncs->set_private_data(key, data);
1622 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to set private data(%d)", ret);
1628 int ttsd_engine_get_private_data(const char* key, char** data)
1630 if (false == g_agent_init) {
1631 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not Initialized");
1632 return TTSD_ERROR_OPERATION_FAILED;
1635 if (false == g_cur_engine.is_loaded) {
1636 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] No loaded engine");
1637 return TTSD_ERROR_ENGINE_NOT_FOUND;
1640 if (NULL == key || NULL == data) {
1641 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Invalid parameter");
1642 return TTSD_ERROR_INVALID_PARAMETER;
1645 if (NULL == g_cur_engine.pefuncs->get_private_data) {
1646 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Not supported feature");
1647 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1652 ret = g_cur_engine.pefuncs->get_private_data(key, &temp);
1654 SLOG(LOG_ERROR, get_tag(), "[Engine Agent ERROR] Fail to get private data(%d)", ret);
1657 *data = strdup(temp);
1663 void __free_voice_list(GList* voice_list)
1666 voice_s* data = NULL;
1668 /* if list have item */
1669 if (g_list_length(voice_list) > 0) {
1670 /* Get a first item */
1671 iter = g_list_first(voice_list);
1673 while (NULL != iter) {
1677 if (NULL != data->language) free(data->language);
1681 voice_list = g_list_remove_link(voice_list, iter);
1683 iter = g_list_first(voice_list);
1689 * TTS Engine Callback Functions ` *
1691 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)
1693 g_result_cb(event, data, data_size, audio_type, rate, user_data);
1697 /* function for debugging */
1698 int ttsd_print_enginelist()
1701 ttsengine_info_s *data = NULL;
1703 if (g_list_length(g_engine_list) > 0) {
1704 iter = g_list_first(g_engine_list);
1706 SLOG(LOG_DEBUG, get_tag(), "----- engine list -----");
1709 while (NULL != iter) {
1712 SECURE_SLOG(LOG_DEBUG, get_tag(), "[%dth]", i);
1713 SECURE_SLOG(LOG_DEBUG, get_tag(), "engine uuid : %s", data->engine_uuid);
1714 SECURE_SLOG(LOG_DEBUG, get_tag(), "engine name : %s", data->engine_name);
1715 SECURE_SLOG(LOG_DEBUG, get_tag(), "engine path : %s", data->engine_path);
1716 SECURE_SLOG(LOG_DEBUG, get_tag(), "setting ug path : %s", data->setting_ug_path);
1718 iter = g_list_next(iter);
1721 SLOG(LOG_DEBUG, get_tag(), "-----------------------");
1722 SLOG(LOG_DEBUG, get_tag(), " ");
1724 SLOG(LOG_DEBUG, get_tag(), "----- engine list -----");
1725 SLOG(LOG_DEBUG, get_tag(), "No Engine in directory");
1726 SLOG(LOG_DEBUG, get_tag(), "-----------------------");
1732 int ttsd_print_voicelist()
1735 GSList *iter = NULL;
1736 ttsvoice_s* data = NULL;
1738 SLOG(LOG_DEBUG, get_tag(), "=== Voice list ===");
1740 if (g_slist_length(g_cur_voices) > 0) {
1741 /* Get a first item */
1742 iter = g_slist_nth(g_cur_voices, 0);
1745 while (NULL != iter) {
1746 /*Get handle data from list*/
1749 if (NULL == data || NULL == data->lang) {
1750 SLOG(LOG_ERROR, get_tag(), "[ERROR] Data is invalid");
1754 SLOG(LOG_DEBUG, get_tag(), "[%dth] default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1755 i, data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1758 iter = g_slist_next(iter);
1763 SLOG(LOG_DEBUG, get_tag(), "==================");