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;
750 int ttsd_engine_agent_is_credential_needed(int uid, bool* credential_needed)
752 if (NULL == credential_needed) {
753 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid Parameter");
754 return TTSD_ERROR_INVALID_PARAMETER;
757 if (false == g_agent_init) {
758 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
759 return TTSD_ERROR_OPERATION_FAILED;
762 if (false == g_engine_info->is_loaded) {
763 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
764 return TTSD_ERROR_OPERATION_FAILED;
767 if (NULL == g_engine_info->callbacks->need_app_credential) {
768 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not support to check app credential");
769 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
773 result = g_engine_info->callbacks->need_app_credential();
774 *credential_needed = result;
776 return TTSD_ERROR_NONE;
779 /******************************************************************************************
780 * TTS Engine Interfaces for client
781 *******************************************************************************************/
783 int ttsd_engine_load_voice(const char* lang, const int vctype)
785 if (false == g_agent_init) {
786 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
787 return TTSD_ERROR_OPERATION_FAILED;
790 if (false == g_engine_info->is_loaded) {
791 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
792 return TTSD_ERROR_ENGINE_NOT_FOUND;
796 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No language parameter");
797 return TTSD_ERROR_INVALID_PARAMETER;
800 /* 1. Find voice info */
803 ttsvoice_s* data = NULL;
805 iter = g_slist_nth(g_cur_voices, 0);
806 while (NULL != iter) {
807 /*Get handle data from list*/
811 if (NULL != data->lang && 0 == strcmp(data->lang, lang) && data->type == vctype) {
812 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
813 data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
819 iter = g_slist_next(iter);
824 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
825 return TTSD_ERROR_OPERATION_FAILED;
828 /* 2. increse ref count */
829 data->client_ref_count++;
831 /* 3. if ref count change 0 to 1 and not default, load voice */
832 if (1 == data->client_ref_count && false == data->is_default) {
834 ret = g_engine_info->callbacks->load_voice(data->lang, data->type);
836 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Load voice : lang(%s), type(%d)",
837 data->lang, data->type);
838 data->is_loaded = true;
840 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
841 data->lang, data->type, __ttsd_get_engine_error_code(ret));
843 return TTSD_ERROR_OPERATION_FAILED;
846 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Not load voice : default voice(%d) or ref count(%d)",
847 data->is_default, data->client_ref_count);
850 #ifdef ENGINE_AGENT_DEBUG
851 ttsd_print_voicelist();
857 int ttsd_engine_unload_voice(const char* lang, const int vctype)
859 if (false == g_agent_init) {
860 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
861 return TTSD_ERROR_OPERATION_FAILED;
864 if (false == g_engine_info->is_loaded) {
865 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
866 return TTSD_ERROR_ENGINE_NOT_FOUND;
870 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No language parameter");
871 return TTSD_ERROR_INVALID_PARAMETER;
874 /* 1. Find voice info */
877 ttsvoice_s* data = NULL;
879 iter = g_slist_nth(g_cur_voices, 0);
880 while (NULL != iter) {
881 /*Get handle data from list*/
885 if (NULL != data->lang && 0 == strcmp(data->lang, lang) && data->type == vctype) {
886 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
887 data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
893 iter = g_slist_next(iter);
898 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
899 return TTSD_ERROR_OPERATION_FAILED;
902 /* 2. Decrese ref count */
903 data->client_ref_count--;
905 /* 3. if ref count change 0 and not default, load voice */
906 if (0 == data->client_ref_count && false == data->is_default) {
908 ret = g_engine_info->callbacks->unload_voice(data->lang, data->type);
910 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
911 data->lang, data->type);
912 data->is_loaded = false;
914 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
915 data->lang, data->type, __ttsd_get_engine_error_code(ret));
917 return TTSD_ERROR_OPERATION_FAILED;
920 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Not unload voice : default voice(%d) or ref count(%d)",
921 data->is_default, data->client_ref_count);
924 #ifdef ENGINE_AGENT_DEBUG
925 ttsd_print_voicelist();
930 int ttsd_engine_start_synthesis(const char* lang, int vctype, const char* text, int speed, const char* appid, const char* credential, void* user_param)
932 if (NULL == lang || NULL == text) {
933 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
934 return TTSD_ERROR_INVALID_PARAMETER;
937 if (false == g_agent_init) {
938 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
939 return TTSD_ERROR_OPERATION_FAILED;
942 if (false == g_engine_info->is_loaded) {
943 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
944 return TTSD_ERROR_ENGINE_NOT_FOUND;
947 /* select voice for default */
948 char* temp_lang = NULL;
950 if (true != ttsd_engine_select_valid_voice(lang, vctype, &temp_lang, &temp_type)) {
951 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to select default voice");
952 if (NULL != temp_lang) free(temp_lang);
953 return TTSD_ERROR_INVALID_VOICE;
955 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Start synthesis : language(%s), type(%d), speed(%d), text(%s), credential(%s)",
956 (NULL == temp_lang) ? "NULL" : temp_lang, temp_type, speed, (NULL == text) ? "NULL" : text, (NULL == credential) ? "NULL" : credential);
962 temp_speed = g_engine_info->default_speed;
967 /* synthesize text */
969 ret = g_engine_info->callbacks->start_synth(temp_lang, temp_type, text, temp_speed, appid, credential, user_param);
971 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] ***************************************");
972 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] * synthesize error : %s *", __ttsd_get_engine_error_code(ret));
973 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] ***************************************");
974 if (NULL != temp_lang) {
981 if (NULL != temp_lang) {
988 int ttsd_engine_cancel_synthesis()
990 if (false == g_agent_init) {
991 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
992 return TTSD_ERROR_OPERATION_FAILED;
995 if (false == g_engine_info->is_loaded) {
996 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
997 return TTSD_ERROR_ENGINE_NOT_FOUND;
1000 /* stop synthesis */
1002 ret = g_engine_info->callbacks->cancel_synth();
1004 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail cancel synthesis : %s", __ttsd_get_engine_error_code(ret));
1010 bool __supported_voice_cb(const char* language, int type, void* user_data)
1012 GList** voice_list = (GList**)user_data;
1014 if (NULL == language || NULL == voice_list) {
1015 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
1019 voice_s* voice = calloc(1, sizeof(voice_s));
1020 if (NULL == voice) {
1021 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
1024 voice->language = strdup(language);
1027 *voice_list = g_list_append(*voice_list, voice);
1032 int ttsd_engine_get_voice_list(GList** voice_list)
1034 if (NULL == voice_list) {
1035 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1036 return TTSD_ERROR_INVALID_PARAMETER;
1039 if (false == g_agent_init) {
1040 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1041 return TTSD_ERROR_OPERATION_FAILED;
1044 if (false == g_engine_info->is_loaded) {
1045 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1046 return TTSD_ERROR_ENGINE_NOT_FOUND;
1050 ret = g_engine_info->callbacks->foreach_voices(__supported_voice_cb, (void*)voice_list);
1052 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get voice list : %s", __ttsd_get_engine_error_code(ret));
1058 int ttsd_engine_get_default_voice(char** lang, int* vctype)
1060 if (false == g_agent_init) {
1061 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1062 return TTSD_ERROR_OPERATION_FAILED;
1065 if (false == g_engine_info->is_loaded) {
1066 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1067 return TTSD_ERROR_ENGINE_NOT_FOUND;
1070 if (NULL == lang || NULL == vctype) {
1071 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] BAD Parameter");
1072 return TTSD_ERROR_INVALID_PARAMETER;
1075 if (NULL != g_engine_info->default_lang) {
1076 *lang = strdup(g_engine_info->default_lang);
1077 *vctype = g_engine_info->default_vctype;
1079 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine] Get default voice : language(%s), type(%d)", *lang, *vctype);
1081 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Default voice is NULL");
1082 return TTSD_ERROR_OPERATION_FAILED;
1088 int ttsd_engine_set_private_data(const char* key, const char* data)
1090 if (false == g_agent_init) {
1091 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1092 return TTSD_ERROR_OPERATION_FAILED;
1095 if (false == g_engine_info->is_loaded) {
1096 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1097 return TTSD_ERROR_ENGINE_NOT_FOUND;
1101 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1102 return TTSD_ERROR_INVALID_PARAMETER;
1105 if (NULL == g_engine_info->callbacks->private_data_set) {
1106 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1107 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1110 int ret = g_engine_info->callbacks->private_data_set(key, data);
1113 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set private data(%d)", ret);
1119 int ttsd_engine_get_private_data(const char* key, char** data)
1121 if (false == g_agent_init) {
1122 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1123 return TTSD_ERROR_OPERATION_FAILED;
1126 if (false == g_engine_info->is_loaded) {
1127 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1128 return TTSD_ERROR_ENGINE_NOT_FOUND;
1131 if (NULL == key || NULL == data) {
1132 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1133 return TTSD_ERROR_INVALID_PARAMETER;
1137 if (NULL == g_engine_info->callbacks->private_data_requested) {
1138 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1139 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1144 ret = g_engine_info->callbacks->private_data_requested(key, &temp);
1146 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get private data(%d)", ret);
1150 *data = strdup("NULL");
1152 *data = strdup(temp);
1157 void __free_voice_list(GList* voice_list)
1160 voice_s* data = NULL;
1162 /* if list have item */
1163 if (g_list_length(voice_list) > 0) {
1164 /* Get a first item */
1165 iter = g_list_first(voice_list);
1167 while (NULL != iter) {
1171 if (NULL != data->language) free(data->language);
1175 voice_list = g_list_remove_link(voice_list, iter);
1177 iter = g_list_first(voice_list);
1183 * TTS Engine Callback Functions ` *
1186 /* function for debugging */
1187 int ttsd_print_voicelist()
1190 GSList *iter = NULL;
1191 ttsvoice_s* data = NULL;
1193 SLOG(LOG_DEBUG, tts_tag(), "=== Voice list ===");
1195 if (g_slist_length(g_cur_voices) > 0) {
1196 /* Get a first item */
1197 iter = g_slist_nth(g_cur_voices, 0);
1200 while (NULL != iter) {
1201 /*Get handle data from list*/
1204 if (NULL == data || NULL == data->lang) {
1205 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Data is invalid");
1209 SLOG(LOG_DEBUG, tts_tag(), "[%dth] default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1210 i, data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1213 iter = g_slist_next(iter);
1218 SLOG(LOG_DEBUG, tts_tag(), "==================");
1223 int __internal_get_engine_info(ttse_request_callback_s* callback)
1225 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent DEBUG] === inside __internal_get_engine_info");
1227 if (NULL == callback) {
1228 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
1229 return TTSD_ERROR_ENGINE_NOT_FOUND;
1232 if (NULL == callback->get_info) {
1233 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
1234 return TTSD_ERROR_ENGINE_NOT_FOUND;
1237 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))) {
1238 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get engine info");
1239 return TTSD_ERROR_ENGINE_NOT_FOUND;
1242 if (NULL != g_engine_info->engine_path) {
1243 free(g_engine_info->engine_path);
1244 g_engine_info->engine_path = NULL;
1246 g_engine_info->engine_path = strdup("empty");
1247 g_engine_info->is_loaded = false;
1249 if (NULL != g_engine_info->callbacks) {
1250 free(g_engine_info->callbacks);
1251 g_engine_info->callbacks = NULL;
1253 g_engine_info->callbacks = (tts_engine_callback_s*)calloc(1, sizeof(tts_engine_callback_s));
1254 if (NULL == g_engine_info->callbacks) {
1255 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
1256 return TTSD_ERROR_OUT_OF_MEMORY;
1259 g_engine_info->callbacks->get_info = callback->get_info;
1260 g_engine_info->callbacks->initialize = callback->initialize;
1261 g_engine_info->callbacks->deinitialize = callback->deinitialize;
1262 g_engine_info->callbacks->foreach_voices = callback->foreach_voices;
1263 g_engine_info->callbacks->is_valid_voice = callback->is_valid_voice;
1264 g_engine_info->callbacks->set_pitch = callback->set_pitch;
1265 g_engine_info->callbacks->load_voice = callback->load_voice;
1266 g_engine_info->callbacks->unload_voice = callback->unload_voice;
1267 g_engine_info->callbacks->start_synth = callback->start_synth;
1268 g_engine_info->callbacks->cancel_synth = callback->cancel_synth;
1269 g_engine_info->callbacks->check_app_agreed = callback->check_app_agreed;
1270 g_engine_info->callbacks->need_app_credential = callback->need_app_credential;
1272 g_engine_info->callbacks->private_data_set = NULL;
1273 g_engine_info->callbacks->private_data_requested = NULL;
1275 SLOG(LOG_DEBUG, tts_tag(), "--- Valid Engine ---");
1276 SLOG(LOG_DEBUG, tts_tag(), "Engine uuid : %s", g_engine_info->engine_uuid);
1277 SLOG(LOG_DEBUG, tts_tag(), "Engine name : %s", g_engine_info->engine_name);
1278 SLOG(LOG_DEBUG, tts_tag(), "Engine path : %s", g_engine_info->engine_path);
1279 SLOG(LOG_DEBUG, tts_tag(), "Engine setting path : %s", g_engine_info->engine_setting_path);
1280 SLOG(LOG_DEBUG, tts_tag(), "Use network : %s", g_engine_info->use_network ? "true" : "false");
1281 SLOG(LOG_DEBUG, tts_tag(), "--------------------");
1282 SLOG(LOG_DEBUG, tts_tag(), " ");
1284 return TTSD_ERROR_NONE;
1289 /** Set callbacks of the current engine */
1290 int ttsd_engine_agent_set_private_data_set_cb(ttse_private_data_set_cb callback)
1292 if (false == g_agent_init) {
1293 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1294 return TTSD_ERROR_OPERATION_FAILED;
1297 if (NULL == g_engine_info) {
1298 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] The engine is not valid");
1299 return TTSD_ERROR_INVALID_PARAMETER;
1302 if (false == g_engine_info->is_loaded) {
1303 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
1304 return TTSD_ERROR_OPERATION_FAILED;
1307 g_engine_info->callbacks->private_data_set = callback;
1309 return TTSD_ERROR_NONE;
1312 int ttsd_engine_agent_set_private_data_requested_cb(ttse_private_data_requested_cb callback)
1314 if (false == g_agent_init) {
1315 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1316 return TTSD_ERROR_OPERATION_FAILED;
1319 if (NULL == g_engine_info) {
1320 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] The engine is not valid");
1321 return TTSD_ERROR_INVALID_PARAMETER;
1324 if (false == g_engine_info->is_loaded) {
1325 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
1326 return TTSD_ERROR_OPERATION_FAILED;
1329 g_engine_info->callbacks->private_data_requested = callback;
1331 return TTSD_ERROR_NONE;