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
28 typedef struct _ttsengine_info {
33 char* engine_setting_path;
35 /* info for using engine load */
39 tts_engine_callback_s* callbacks;
41 /* engine base setting */
59 static bool g_agent_init;
61 /** Current engine information */
62 static ttsengine_info_s* g_engine_info = NULL;
64 /** Current voice information */
65 static GSList* g_cur_voices = NULL;
67 /** Callback function for voice list */
68 static bool __supported_voice_cb(const char* language, int type, void* user_data);
70 /** Free voice list */
71 static void __free_voice_list(GList* voice_list);
73 static int ttsd_print_voicelist();
75 /** Get engine info */
76 int __internal_get_engine_info(ttse_request_callback_s* callback);
78 static const char* __ttsd_get_engine_error_code(ttse_error_e err)
81 case TTSE_ERROR_NONE: return "TTSE_ERROR_NONE";
82 case TTSE_ERROR_OUT_OF_MEMORY: return "TTSE_ERROR_OUT_OF_MEMORY";
83 case TTSE_ERROR_IO_ERROR: return "TTSE_ERROR_IO_ERROR";
84 case TTSE_ERROR_INVALID_PARAMETER: return "TTSE_ERROR_INVALID_PARAMETER";
85 case TTSE_ERROR_NETWORK_DOWN: return "TTSE_ERROR_NETWORK_DOWN";
86 case TTSE_ERROR_INVALID_STATE: return "TTSE_ERROR_INVALID_STATE";
87 case TTSE_ERROR_INVALID_VOICE: return "TTSE_ERROR_INVALID_VOICE";
88 case TTSE_ERROR_OPERATION_FAILED: return "TTSE_ERROR_OPERATION_FAILED";
90 return "Invalid error code";
94 int ttsd_engine_agent_init()
96 if (true == g_agent_init) {
97 SLOG(LOG_WARN, tts_tag(), "[Engine Agent] Already initialized");
98 return TTSD_ERROR_OPERATION_FAILED;
101 ttsengine_info_s* temp;
102 temp = (ttsengine_info_s*)calloc(1, sizeof(ttsengine_info_s));
104 SLOG(LOG_WARN, tts_tag(), "[Engine Agent] Fail to alloc memory");
105 return TTSD_ERROR_OUT_OF_MEMORY;
108 if (0 != ttsd_config_get_default_voice(&(temp->default_lang), &(temp->default_vctype))) {
109 SLOG(LOG_WARN, tts_tag(), "[Server WARNING] There is No default voice in config");
110 /* Set default voice */
111 temp->default_lang = strdup(TTS_BASE_LANGUAGE);
112 temp->default_vctype = TTSE_VOICE_TYPE_FEMALE;
115 SLOG(LOG_DEBUG, tts_tag(), "[Server DEBUG] language(%s), type(%d)", temp->default_lang, temp->default_vctype);
117 if (0 != ttsd_config_get_default_speed(&(temp->default_speed))) {
118 SLOG(LOG_WARN, tts_tag(), "[Server WARNING] There is No default speed in config");
119 temp->default_speed = TTS_SPEED_NORMAL;
122 if (0 != ttsd_config_get_default_pitch(&(temp->default_pitch))) {
123 SLOG(LOG_WARN, tts_tag(), "[Server WARNING] There is No default pitch in config");
124 temp->default_pitch = TTS_PITCH_NORMAL;
127 temp->is_loaded = false;
128 g_engine_info = temp;
132 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Initialize Engine Agent");
136 int ttsd_engine_agent_release()
138 if (false == g_agent_init) {
139 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
140 return TTSD_ERROR_OPERATION_FAILED;
143 /* unload current engine */
144 if (g_engine_info->is_loaded) {
145 ttsd_engine_agent_unload_current_engine();
148 if (NULL != g_engine_info->default_lang) {
149 free(g_engine_info->default_lang);
150 g_engine_info->default_lang = NULL;
153 if (NULL != g_engine_info->engine_uuid) {
154 free(g_engine_info->engine_uuid);
155 g_engine_info->engine_uuid = NULL;
158 if (NULL != g_engine_info->engine_name) {
159 free(g_engine_info->engine_name);
160 g_engine_info->engine_name = NULL;
163 if (NULL != g_engine_info->engine_setting_path) {
164 free(g_engine_info->engine_setting_path);
165 g_engine_info->engine_setting_path = NULL;
168 if (NULL != g_engine_info->engine_path) {
169 free(g_engine_info->engine_path);
170 g_engine_info->engine_path = NULL;
174 g_engine_info = NULL;
176 g_agent_init = false;
178 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Release Engine Agent");
183 static bool __set_voice_info_cb(const char* language, int type, void* user_data)
185 if (NULL == language) {
186 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
190 ttsvoice_s* voice = calloc(1, sizeof(ttsvoice_s));
192 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
195 voice->lang = strdup(language);
198 voice->client_ref_count = 0;
199 voice->is_loaded = false;
201 if (0 == strcmp(g_engine_info->default_lang, language) && g_engine_info->default_vctype == type) {
202 voice->is_default = true;
203 voice->is_loaded = true;
205 voice->is_default = false;
208 g_cur_voices = g_slist_append(g_cur_voices, voice);
213 static int __update_voice_list()
215 if (false == g_agent_init) {
216 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
217 return TTSD_ERROR_OPERATION_FAILED;
221 if (NULL != g_cur_voices) {
223 ttsvoice_s* data = NULL;
225 iter = g_slist_nth(g_cur_voices, 0);
226 while (NULL != iter) {
230 if (NULL != data->lang) {
235 g_cur_voices = g_slist_remove(g_cur_voices, data);
240 iter = g_slist_nth(g_cur_voices, 0);
247 ret = g_engine_info->callbacks->foreach_voices(__set_voice_info_cb, NULL);
249 if (0 != ret || 0 >= g_slist_length(g_cur_voices)) {
250 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
254 #ifdef ENGINE_AGENT_DEBUG
255 ttsd_print_voicelist();
260 int ttsd_engine_agent_load_current_engine(ttse_request_callback_s* callback)
262 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent DEBUG] === ttsd_engine_agent_load_current_engine START");
265 if (false == g_agent_init) {
266 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
267 return TTSD_ERROR_OPERATION_FAILED;
270 /* check whether current engine is loaded or not */
271 if (true == g_engine_info->is_loaded) {
272 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent] Engine has already been loaded ");
276 if (NULL == callback) {
277 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
278 return TTSD_ERROR_ENGINE_NOT_FOUND;
281 if (NULL == callback->get_info
282 || NULL == callback->initialize || NULL == callback->deinitialize
283 || NULL == callback->foreach_voices || NULL == callback->is_valid_voice
284 || NULL == callback->set_pitch
285 || NULL == callback->load_voice || NULL == callback->unload_voice
286 || NULL == callback->start_synth || NULL == callback->cancel_synth
287 || NULL == callback->check_app_agreed || NULL == callback->need_app_credential) {
288 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
289 return TTSD_ERROR_ENGINE_NOT_FOUND;
292 /* Get current engine info */
293 int ret = __internal_get_engine_info(callback);
295 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get engine info");
299 /* Initialize engine */
300 ret = g_engine_info->callbacks->initialize();
302 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to initialize current engine : %s", __ttsd_get_engine_error_code(ret));
303 return TTSD_ERROR_OPERATION_FAILED;
306 /* Get voice info of current engine */
307 ret = __update_voice_list();
309 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set voice info : result(%d)", ret);
310 return TTSD_ERROR_OPERATION_FAILED;
313 /* Select default voice */
314 if (NULL != g_engine_info->default_lang) {
315 bool is_valid = false;
316 ret = g_engine_info->callbacks->is_valid_voice(g_engine_info->default_lang, g_engine_info->default_vctype, &is_valid);
318 if (true == is_valid) {
319 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Set origin default voice to current engine : lang(%s), type(%d)",
320 g_engine_info->default_lang, g_engine_info->default_vctype);
322 SLOG(LOG_WARN, tts_tag(), "[Engine Agent WARNING] Fail to set origin default voice : lang(%s), type(%d)",
323 g_engine_info->default_lang, g_engine_info->default_vctype);
325 /* TODO - Error Tolerance when Default voice is not valid */
326 return TTSD_ERROR_OPERATION_FAILED;
329 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail(Engine ERROR) : %s", __ttsd_get_engine_error_code(ret));
334 /* load default voice */
335 ret = g_engine_info->callbacks->load_voice(g_engine_info->default_lang, g_engine_info->default_vctype);
337 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Load default voice : lang(%s), type(%d)",
338 g_engine_info->default_lang, g_engine_info->default_vctype);
340 SLOG(LOG_WARN, tts_tag(), "[Engine Agent ERROR] Fail to load default voice : lang(%s), type(%d) result(%s)",
341 g_engine_info->default_lang, g_engine_info->default_vctype, __ttsd_get_engine_error_code(ret));
343 return TTSD_ERROR_OPERATION_FAILED;
346 /* set default pitch */
347 ret = g_engine_info->callbacks->set_pitch(g_engine_info->default_pitch);
349 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)",
350 g_engine_info->default_pitch, __ttsd_get_engine_error_code(ret));
353 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Set default pitch : pitch(%d)", g_engine_info->default_pitch);
356 g_engine_info->is_loaded = true;
361 int ttsd_engine_agent_unload_current_engine()
363 if (false == g_agent_init) {
364 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
365 return TTSD_ERROR_OPERATION_FAILED;
368 if (false == g_engine_info->is_loaded) {
369 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Engine has already been unloaded ");
373 /* shutdown engine */
375 ret = g_engine_info->callbacks->deinitialize();
377 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent] Fail deinitialize() : %s", __ttsd_get_engine_error_code(ret));
380 /* reset current engine data */
381 g_engine_info->is_loaded = false;
384 ttsvoice_s* data = NULL;
386 iter = g_slist_nth(g_cur_voices, 0);
387 while (NULL != iter) {
391 if (NULL != data->lang) free(data->lang);
392 g_cur_voices = g_slist_remove(g_cur_voices, data);
397 iter = g_slist_nth(g_cur_voices, 0);
400 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent Success] Unload current engine");
405 bool ttsd_engine_agent_need_network()
407 if (false == g_agent_init) {
408 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
409 return TTSD_ERROR_OPERATION_FAILED;
412 return g_engine_info->use_network;
415 bool ttsd_engine_agent_is_same_engine(const char* engine_id)
417 if (false == g_agent_init) {
418 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
422 if (NULL == engine_id) {
423 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] engine_id is NULL");
427 if (NULL == g_engine_info) {
428 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] g_engine_info is NULL");
432 if (false == g_engine_info->is_loaded) {
433 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
437 /* compare current engine and engine id.*/
438 if (NULL != g_engine_info->engine_uuid && 0 == strncmp(g_engine_info->engine_uuid, engine_id, strlen(engine_id))) {
445 bool ttsd_engine_select_valid_voice(const char* lang, int type, char** out_lang, int* out_type)
447 if (NULL == lang || NULL == out_lang || NULL == out_type) {
451 if (NULL == g_engine_info) {
452 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] g_engine_info is NULL");
456 if (false == g_engine_info->is_loaded) {
457 SLOG(LOG_WARN, tts_tag(), "[Engine Agent WARNING] Not loaded engine");
461 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Select voice : input lang(%s), input type(%d), default lang(%s), default type(%d)",
462 (NULL == lang) ? "NULL" : lang, type, (NULL == g_engine_info->default_lang) ? "NULL" : g_engine_info->default_lang, g_engine_info->default_vctype);
464 /* case 1 : Both are default */
465 if (0 == strncmp(lang, "default", strlen(lang)) && 0 == type) {
466 if (NULL != g_engine_info->default_lang) {
467 *out_lang = strdup(g_engine_info->default_lang);
472 *out_type = g_engine_info->default_vctype;
477 GList* voice_list = NULL;
479 ret = g_engine_info->callbacks->foreach_voices(__supported_voice_cb, &voice_list);
480 if (0 != ret || 0 >= g_list_length(voice_list)) {
481 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
491 /* case 2 : lang and type are not default type */
492 if (0 != strncmp(lang, "default", strlen("default")) && 0 != type) {
493 iter = g_list_first(voice_list);
495 while (NULL != iter) {
496 /* Get handle data from list */
499 if (0 == strncmp(voice->language, lang, strlen(lang)) && voice->type == type) {
500 *out_lang = strdup(voice->language);
501 *out_type = voice->type;
506 iter = g_list_next(iter);
509 } else if (0 != strncmp(lang, "default", strlen("default")) && 0 == type) {
510 /* Only type is default */
511 if (0 == strncmp(lang, g_engine_info->default_lang, strlen(g_engine_info->default_lang))) {
512 *out_lang = strdup(g_engine_info->default_lang);
513 *out_type = g_engine_info->default_vctype;
516 voice_s* voice_selected = NULL;
517 iter = g_list_first(voice_list);
518 while (NULL != iter) {
519 /* Get handle data from list */
522 if (0 == strncmp(voice->language, lang, strlen(lang))) {
523 voice_selected = voice;
524 if (voice->type == g_engine_info->default_vctype) {
525 voice_selected = voice;
529 iter = g_list_next(iter);
532 if (NULL != voice_selected) {
533 *out_lang = strdup(voice_selected->language);
534 *out_type = voice_selected->type;
538 } else if (0 == strncmp(lang, "default", strlen("default")) && 0 != type) {
539 /* Only lang is default */
540 if (type == g_engine_info->default_vctype) {
541 *out_lang = strdup(g_engine_info->default_lang);
542 *out_type = g_engine_info->default_vctype;
545 voice_s* voice_selected = NULL;
546 iter = g_list_first(voice_list);
547 while (NULL != iter) {
548 /* Get handle data from list */
551 if (0 == strncmp(voice->language, g_engine_info->default_lang, strlen(g_engine_info->default_lang))) {
552 voice_selected = voice;
553 if (voice->type == type) {
554 voice_selected = voice;
558 iter = g_list_next(iter);
561 if (NULL != voice_selected) {
562 *out_lang = strdup(voice->language);
563 *out_type = voice_selected->type;
569 if (true == result) {
570 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Selected voice : lang(%s), type(%d)", *out_lang, *out_type);
573 __free_voice_list(voice_list);
580 int ttsd_engine_agent_set_default_voice(const char* language, int vctype)
582 if (NULL == language) {
583 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] language is NULL");
587 if (false == g_agent_init) {
588 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
589 return TTSD_ERROR_OPERATION_FAILED;
592 if (NULL == g_engine_info) {
593 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] g_engine_info is NULL");
597 if (false == g_engine_info->is_loaded) {
598 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
599 return TTSD_ERROR_ENGINE_NOT_FOUND;
603 bool is_valid = false;
604 ret = g_engine_info->callbacks->is_valid_voice(language, vctype, &is_valid);
606 if (true == is_valid) {
607 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Current voice is valid : lang(%s), type(%d)",
608 (NULL == g_engine_info->default_lang) ? "NULL" : g_engine_info->default_lang, g_engine_info->default_vctype);
610 SLOG(LOG_WARN, tts_tag(), "[Engine Agent WARNING] Current voice is invalid : lang(%s), type(%d)",
611 (NULL == g_engine_info->default_lang) ? "NULL" : g_engine_info->default_lang, g_engine_info->default_vctype);
613 return TTSD_ERROR_OPERATION_FAILED;
616 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail(Engine ERROR) : %s", __ttsd_get_engine_error_code(ret));
622 ttsvoice_s* data = NULL;
624 /* Update new default voice info */
625 iter = g_slist_nth(g_cur_voices, 0);
626 while (NULL != iter) {
627 /* Get handle data from list */
631 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Voice data is NULL");
632 return TTSD_ERROR_OPERATION_FAILED;
635 if (NULL != data->lang) {
636 if (0 == strcmp(data->lang, language) && data->type == vctype) {
637 data->is_default = true;
638 if (0 == data->client_ref_count) {
640 ret = g_engine_info->callbacks->load_voice(data->lang, data->type);
642 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] load voice : lang(%s), type(%d)",
643 data->lang, data->type);
644 data->is_loaded = true;
646 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
647 data->lang, data->type, __ttsd_get_engine_error_code(ret));
655 iter = g_slist_next(iter);
658 #ifdef ENGINE_AGENT_DEBUG
659 ttsd_print_voicelist();
662 /* Update old default voice info */
663 iter = g_slist_nth(g_cur_voices, 0);
664 while (NULL != iter) {
665 /*Get handle data from list*/
669 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Voice data is NULL");
670 return TTSD_ERROR_OPERATION_FAILED;
673 if (0 == strcmp(data->lang, g_engine_info->default_lang) && data->type == g_engine_info->default_vctype) {
674 data->is_default = false;
675 if (0 == data->client_ref_count) {
677 ret = g_engine_info->callbacks->unload_voice(data->lang, data->type);
679 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
680 data->lang, data->type);
681 data->is_loaded = false;
683 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
684 data->lang, data->type, __ttsd_get_engine_error_code(ret));
691 iter = g_slist_next(iter);
694 if (NULL != g_engine_info->default_lang) free(g_engine_info->default_lang);
696 g_engine_info->default_lang = strdup(language);
697 g_engine_info->default_vctype = vctype;
699 #ifdef ENGINE_AGENT_DEBUG
700 ttsd_print_voicelist();
703 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Set default voice : lang(%s), type(%d)",
704 g_engine_info->default_lang, g_engine_info->default_vctype);
709 int ttsd_engine_agent_set_default_speed(int speed)
711 if (false == g_agent_init) {
712 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
713 return TTSD_ERROR_OPERATION_FAILED;
716 g_engine_info->default_speed = speed;
721 int ttsd_engine_agent_set_default_pitch(int pitch)
723 if (false == g_agent_init) {
724 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
725 return TTSD_ERROR_OPERATION_FAILED;
728 if (NULL == g_engine_info) {
729 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No engine info");
730 return TTSD_ERROR_ENGINE_NOT_FOUND;
733 if (false == g_engine_info->is_loaded) {
734 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
735 return TTSD_ERROR_ENGINE_NOT_FOUND;
738 int ret = g_engine_info->callbacks->set_pitch(pitch);
740 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)",
741 pitch, __ttsd_get_engine_error_code(ret));
742 return TTSD_ERROR_OPERATION_FAILED;
745 g_engine_info->default_pitch = pitch;
747 SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Set pitch(%d)", pitch);
751 int ttsd_engine_agent_is_credential_needed(int uid, bool* credential_needed)
753 if (NULL == credential_needed) {
754 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid Parameter");
755 return TTSD_ERROR_INVALID_PARAMETER;
758 if (false == g_agent_init) {
759 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
760 return TTSD_ERROR_OPERATION_FAILED;
763 if (false == g_engine_info->is_loaded) {
764 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
765 return TTSD_ERROR_OPERATION_FAILED;
768 if (NULL == g_engine_info->callbacks->need_app_credential) {
769 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not support to check app credential");
770 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
774 result = g_engine_info->callbacks->need_app_credential();
775 *credential_needed = result;
777 SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Need app credential, credential_needed(%d)", *credential_needed);
778 return TTSD_ERROR_NONE;
781 /******************************************************************************************
782 * TTS Engine Interfaces for client
783 *******************************************************************************************/
785 int ttsd_engine_load_voice(const char* lang, const int vctype)
787 if (false == g_agent_init) {
788 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
789 return TTSD_ERROR_OPERATION_FAILED;
792 if (false == g_engine_info->is_loaded) {
793 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
794 return TTSD_ERROR_ENGINE_NOT_FOUND;
798 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No language parameter");
799 return TTSD_ERROR_INVALID_PARAMETER;
802 /* 1. Find voice info */
805 ttsvoice_s* data = NULL;
807 iter = g_slist_nth(g_cur_voices, 0);
808 while (NULL != iter) {
809 /*Get handle data from list*/
813 if (NULL != data->lang && 0 == strcmp(data->lang, lang) && data->type == vctype) {
814 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
815 data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
821 iter = g_slist_next(iter);
826 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
827 return TTSD_ERROR_OPERATION_FAILED;
830 /* 2. increse ref count */
831 data->client_ref_count++;
833 /* 3. if ref count change 0 to 1 and not default, load voice */
834 if (1 == data->client_ref_count && false == data->is_default) {
836 ret = g_engine_info->callbacks->load_voice(data->lang, data->type);
838 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Load voice : lang(%s), type(%d)",
839 data->lang, data->type);
840 data->is_loaded = true;
842 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
843 data->lang, data->type, __ttsd_get_engine_error_code(ret));
845 return TTSD_ERROR_OPERATION_FAILED;
848 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Not load voice : default voice(%d) or ref count(%d)",
849 data->is_default, data->client_ref_count);
852 #ifdef ENGINE_AGENT_DEBUG
853 ttsd_print_voicelist();
859 int ttsd_engine_unload_voice(const char* lang, const int vctype)
861 if (false == g_agent_init) {
862 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
863 return TTSD_ERROR_OPERATION_FAILED;
866 if (false == g_engine_info->is_loaded) {
867 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
868 return TTSD_ERROR_ENGINE_NOT_FOUND;
872 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No language parameter");
873 return TTSD_ERROR_INVALID_PARAMETER;
876 /* 1. Find voice info */
879 ttsvoice_s* data = NULL;
881 iter = g_slist_nth(g_cur_voices, 0);
882 while (NULL != iter) {
883 /*Get handle data from list*/
887 if (NULL != data->lang && 0 == strcmp(data->lang, lang) && data->type == vctype) {
888 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
889 data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
895 iter = g_slist_next(iter);
900 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
901 return TTSD_ERROR_OPERATION_FAILED;
904 /* 2. Decrese ref count */
905 data->client_ref_count--;
907 /* 3. if ref count change 0 and not default, load voice */
908 if (0 == data->client_ref_count && false == data->is_default) {
910 ret = g_engine_info->callbacks->unload_voice(data->lang, data->type);
912 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
913 data->lang, data->type);
914 data->is_loaded = false;
916 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
917 data->lang, data->type, __ttsd_get_engine_error_code(ret));
919 return TTSD_ERROR_OPERATION_FAILED;
922 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Not unload voice : default voice(%d) or ref count(%d)",
923 data->is_default, data->client_ref_count);
926 #ifdef ENGINE_AGENT_DEBUG
927 ttsd_print_voicelist();
932 int ttsd_engine_start_synthesis(const char* lang, int vctype, const char* text, int speed, const char* appid, const char* credential, void* user_param)
934 if (NULL == lang || NULL == text) {
935 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
936 return TTSD_ERROR_INVALID_PARAMETER;
939 if (false == g_agent_init) {
940 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
941 return TTSD_ERROR_OPERATION_FAILED;
944 if (false == g_engine_info->is_loaded) {
945 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
946 return TTSD_ERROR_ENGINE_NOT_FOUND;
949 /* select voice for default */
950 char* temp_lang = NULL;
952 if (true != ttsd_engine_select_valid_voice(lang, vctype, &temp_lang, &temp_type)) {
953 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to select default voice");
954 if (NULL != temp_lang) free(temp_lang);
955 return TTSD_ERROR_INVALID_VOICE;
957 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Start synthesis : language(%s), type(%d), speed(%d), text(%s), credential(%s)",
958 (NULL == temp_lang) ? "NULL" : temp_lang, temp_type, speed, (NULL == text) ? "NULL" : text, (NULL == credential) ? "NULL" : credential);
964 temp_speed = g_engine_info->default_speed;
969 /* synthesize text */
971 ret = g_engine_info->callbacks->start_synth(temp_lang, temp_type, text, temp_speed, appid, credential, user_param);
973 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] ***************************************");
974 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] * synthesize error : %s *", __ttsd_get_engine_error_code(ret));
975 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] ***************************************");
976 if (NULL != temp_lang) {
983 if (NULL != temp_lang) {
990 int ttsd_engine_cancel_synthesis()
992 if (false == g_agent_init) {
993 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
994 return TTSD_ERROR_OPERATION_FAILED;
997 if (false == g_engine_info->is_loaded) {
998 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
999 return TTSD_ERROR_ENGINE_NOT_FOUND;
1002 SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Cancel synth");
1003 /* stop synthesis */
1005 ret = g_engine_info->callbacks->cancel_synth();
1007 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail cancel synthesis : %s", __ttsd_get_engine_error_code(ret));
1013 bool __supported_voice_cb(const char* language, int type, void* user_data)
1015 GList** voice_list = (GList**)user_data;
1017 if (NULL == language || NULL == voice_list) {
1018 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
1022 voice_s* voice = calloc(1, sizeof(voice_s));
1023 if (NULL == voice) {
1024 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
1027 voice->language = strdup(language);
1030 *voice_list = g_list_append(*voice_list, voice);
1035 int ttsd_engine_get_voice_list(GList** voice_list)
1037 if (NULL == voice_list) {
1038 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1039 return TTSD_ERROR_INVALID_PARAMETER;
1042 if (false == g_agent_init) {
1043 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1044 return TTSD_ERROR_OPERATION_FAILED;
1047 if (false == g_engine_info->is_loaded) {
1048 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1049 return TTSD_ERROR_ENGINE_NOT_FOUND;
1053 ret = g_engine_info->callbacks->foreach_voices(__supported_voice_cb, (void*)voice_list);
1055 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get voice list : %s", __ttsd_get_engine_error_code(ret));
1061 int ttsd_engine_get_default_voice(char** lang, int* vctype)
1063 if (false == g_agent_init) {
1064 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1065 return TTSD_ERROR_OPERATION_FAILED;
1068 if (false == g_engine_info->is_loaded) {
1069 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1070 return TTSD_ERROR_ENGINE_NOT_FOUND;
1073 if (NULL == lang || NULL == vctype) {
1074 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] BAD Parameter");
1075 return TTSD_ERROR_INVALID_PARAMETER;
1078 if (NULL != g_engine_info->default_lang) {
1079 *lang = strdup(g_engine_info->default_lang);
1080 *vctype = g_engine_info->default_vctype;
1082 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine] Get default voice : language(%s), type(%d)", *lang, *vctype);
1084 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Default voice is NULL");
1085 return TTSD_ERROR_OPERATION_FAILED;
1091 int ttsd_engine_set_private_data(const char* key, const char* data)
1093 if (false == g_agent_init) {
1094 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1095 return TTSD_ERROR_OPERATION_FAILED;
1098 if (false == g_engine_info->is_loaded) {
1099 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1100 return TTSD_ERROR_ENGINE_NOT_FOUND;
1104 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1105 return TTSD_ERROR_INVALID_PARAMETER;
1108 if (NULL == g_engine_info->callbacks->private_data_set) {
1109 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1110 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1113 int ret = g_engine_info->callbacks->private_data_set(key, data);
1116 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set private data(%d)", ret);
1122 int ttsd_engine_get_private_data(const char* key, char** data)
1124 if (false == g_agent_init) {
1125 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1126 return TTSD_ERROR_OPERATION_FAILED;
1129 if (false == g_engine_info->is_loaded) {
1130 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1131 return TTSD_ERROR_ENGINE_NOT_FOUND;
1134 if (NULL == key || NULL == data) {
1135 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1136 return TTSD_ERROR_INVALID_PARAMETER;
1140 if (NULL == g_engine_info->callbacks->private_data_requested) {
1141 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1142 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1147 ret = g_engine_info->callbacks->private_data_requested(key, &temp);
1149 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get private data(%d)", ret);
1153 *data = strdup("NULL");
1155 *data = strdup(temp);
1160 void __free_voice_list(GList* voice_list)
1163 voice_s* data = NULL;
1165 /* if list have item */
1166 if (g_list_length(voice_list) > 0) {
1167 /* Get a first item */
1168 iter = g_list_first(voice_list);
1170 while (NULL != iter) {
1174 if (NULL != data->language) free(data->language);
1178 voice_list = g_list_remove_link(voice_list, iter);
1180 iter = g_list_first(voice_list);
1186 * TTS Engine Callback Functions ` *
1189 /* function for debugging */
1190 int ttsd_print_voicelist()
1193 GSList *iter = NULL;
1194 ttsvoice_s* data = NULL;
1196 SLOG(LOG_DEBUG, tts_tag(), "=== Voice list ===");
1198 if (g_slist_length(g_cur_voices) > 0) {
1199 /* Get a first item */
1200 iter = g_slist_nth(g_cur_voices, 0);
1203 while (NULL != iter) {
1204 /*Get handle data from list*/
1207 if (NULL == data || NULL == data->lang) {
1208 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Data is invalid");
1212 SLOG(LOG_DEBUG, tts_tag(), "[%dth] default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1213 i, data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1216 iter = g_slist_next(iter);
1221 SLOG(LOG_DEBUG, tts_tag(), "==================");
1226 int __internal_get_engine_info(ttse_request_callback_s* callback)
1228 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent DEBUG] === inside __internal_get_engine_info");
1230 if (NULL == callback) {
1231 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
1232 return TTSD_ERROR_ENGINE_NOT_FOUND;
1235 if (NULL == callback->get_info) {
1236 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
1237 return TTSD_ERROR_ENGINE_NOT_FOUND;
1240 if (0 != callback->get_info(&(g_engine_info->engine_uuid), &(g_engine_info->engine_name), &(g_engine_info->engine_setting_path), &(g_engine_info->use_network))) {
1241 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get engine info");
1242 return TTSD_ERROR_ENGINE_NOT_FOUND;
1245 if (NULL != g_engine_info->engine_path) {
1246 free(g_engine_info->engine_path);
1247 g_engine_info->engine_path = NULL;
1249 g_engine_info->engine_path = strdup("empty");
1250 g_engine_info->is_loaded = false;
1252 if (NULL != g_engine_info->callbacks) {
1253 free(g_engine_info->callbacks);
1254 g_engine_info->callbacks = NULL;
1256 g_engine_info->callbacks = (tts_engine_callback_s*)calloc(1, sizeof(tts_engine_callback_s));
1257 if (NULL == g_engine_info->callbacks) {
1258 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
1259 return TTSD_ERROR_OUT_OF_MEMORY;
1262 g_engine_info->callbacks->get_info = callback->get_info;
1263 g_engine_info->callbacks->initialize = callback->initialize;
1264 g_engine_info->callbacks->deinitialize = callback->deinitialize;
1265 g_engine_info->callbacks->foreach_voices = callback->foreach_voices;
1266 g_engine_info->callbacks->is_valid_voice = callback->is_valid_voice;
1267 g_engine_info->callbacks->set_pitch = callback->set_pitch;
1268 g_engine_info->callbacks->load_voice = callback->load_voice;
1269 g_engine_info->callbacks->unload_voice = callback->unload_voice;
1270 g_engine_info->callbacks->start_synth = callback->start_synth;
1271 g_engine_info->callbacks->cancel_synth = callback->cancel_synth;
1272 g_engine_info->callbacks->check_app_agreed = callback->check_app_agreed;
1273 g_engine_info->callbacks->need_app_credential = callback->need_app_credential;
1275 g_engine_info->callbacks->private_data_set = NULL;
1276 g_engine_info->callbacks->private_data_requested = NULL;
1278 SLOG(LOG_DEBUG, tts_tag(), "--- Valid Engine ---");
1279 SLOG(LOG_DEBUG, tts_tag(), "Engine uuid : %s", g_engine_info->engine_uuid);
1280 SLOG(LOG_DEBUG, tts_tag(), "Engine name : %s", g_engine_info->engine_name);
1281 SLOG(LOG_DEBUG, tts_tag(), "Engine path : %s", g_engine_info->engine_path);
1282 SLOG(LOG_DEBUG, tts_tag(), "Engine setting path : %s", g_engine_info->engine_setting_path);
1283 SLOG(LOG_DEBUG, tts_tag(), "Use network : %s", g_engine_info->use_network ? "true" : "false");
1284 SLOG(LOG_DEBUG, tts_tag(), "--------------------");
1285 SLOG(LOG_DEBUG, tts_tag(), " ");
1287 return TTSD_ERROR_NONE;
1292 /** Set callbacks of the current engine */
1293 int ttsd_engine_agent_set_private_data_set_cb(ttse_private_data_set_cb callback)
1295 if (false == g_agent_init) {
1296 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1297 return TTSD_ERROR_OPERATION_FAILED;
1300 if (NULL == g_engine_info) {
1301 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] The engine is not valid");
1302 return TTSD_ERROR_INVALID_PARAMETER;
1305 if (false == g_engine_info->is_loaded) {
1306 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
1307 return TTSD_ERROR_OPERATION_FAILED;
1310 g_engine_info->callbacks->private_data_set = callback;
1312 return TTSD_ERROR_NONE;
1315 int ttsd_engine_agent_set_private_data_requested_cb(ttse_private_data_requested_cb callback)
1317 if (false == g_agent_init) {
1318 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1319 return TTSD_ERROR_OPERATION_FAILED;
1322 if (NULL == g_engine_info) {
1323 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] The engine is not valid");
1324 return TTSD_ERROR_INVALID_PARAMETER;
1327 if (false == g_engine_info->is_loaded) {
1328 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
1329 return TTSD_ERROR_OPERATION_FAILED;
1332 g_engine_info->callbacks->private_data_requested = callback;
1334 return TTSD_ERROR_NONE;