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 static const char* __ttsd_get_engine_error_code(ttse_error_e err)
78 case TTSE_ERROR_NONE: return "TTSE_ERROR_NONE";
79 case TTSE_ERROR_OUT_OF_MEMORY: return "TTSE_ERROR_OUT_OF_MEMORY";
80 case TTSE_ERROR_IO_ERROR: return "TTSE_ERROR_IO_ERROR";
81 case TTSE_ERROR_INVALID_PARAMETER: return "TTSE_ERROR_INVALID_PARAMETER";
82 case TTSE_ERROR_NETWORK_DOWN: return "TTSE_ERROR_NETWORK_DOWN";
83 case TTSE_ERROR_INVALID_STATE: return "TTSE_ERROR_INVALID_STATE";
84 case TTSE_ERROR_INVALID_VOICE: return "TTSE_ERROR_INVALID_VOICE";
85 case TTSE_ERROR_OPERATION_FAILED: return "TTSE_ERROR_OPERATION_FAILED";
87 return "Invalid error code";
91 inline static bool __is_agent_initialized()
93 if (false == g_agent_init) {
94 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
98 if (NULL == g_engine_info) {
99 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No engine info");
106 inline static bool __is_engine_loaded()
108 if (false == g_engine_info->is_loaded) {
109 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
116 inline static int __check_engine_initialized_and_loaded()
118 if (false == __is_agent_initialized()) {
119 return TTSD_ERROR_INVALID_STATE;
122 if (false == __is_engine_loaded()) {
123 return TTSD_ERROR_ENGINE_NOT_FOUND;
126 return TTSD_ERROR_NONE;
129 static bool __is_callback_valid(ttse_request_callback_s *callback)
131 if (NULL == callback) {
132 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
136 if (NULL == callback->get_info
137 || NULL == callback->initialize || NULL == callback->deinitialize
138 || NULL == callback->foreach_voices || NULL == callback->is_valid_voice
139 || NULL == callback->set_pitch
140 || NULL == callback->load_voice || NULL == callback->unload_voice
141 || NULL == callback->start_synth || NULL == callback->cancel_synth
142 || NULL == callback->check_app_agreed || NULL == callback->need_app_credential) {
143 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
150 static int __set_engine_callback(ttse_request_callback_s* callback, ttsengine_info_s* engine_info)
152 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent DEBUG] internal get engine info");
154 if (0 != callback->get_info(&(engine_info->engine_uuid), &(engine_info->engine_name), &(engine_info->engine_setting_path), &(engine_info->use_network))) {
155 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get engine info");
156 return TTSD_ERROR_ENGINE_NOT_FOUND;
159 if (NULL != engine_info->engine_path) {
160 free(engine_info->engine_path);
161 engine_info->engine_path = NULL;
163 engine_info->engine_path = strdup("empty");
164 engine_info->is_loaded = false;
166 if (NULL != engine_info->callbacks) {
167 free(engine_info->callbacks);
168 engine_info->callbacks = NULL;
171 engine_info->callbacks = (tts_engine_callback_s*)calloc(1, sizeof(tts_engine_callback_s));
172 if (NULL == engine_info->callbacks) {
173 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
174 return TTSD_ERROR_OUT_OF_MEMORY;
177 engine_info->callbacks->get_info = callback->get_info;
178 engine_info->callbacks->initialize = callback->initialize;
179 engine_info->callbacks->deinitialize = callback->deinitialize;
180 engine_info->callbacks->foreach_voices = callback->foreach_voices;
181 engine_info->callbacks->is_valid_voice = callback->is_valid_voice;
182 engine_info->callbacks->set_pitch = callback->set_pitch;
183 engine_info->callbacks->load_voice = callback->load_voice;
184 engine_info->callbacks->unload_voice = callback->unload_voice;
185 engine_info->callbacks->start_synth = callback->start_synth;
186 engine_info->callbacks->cancel_synth = callback->cancel_synth;
187 engine_info->callbacks->check_app_agreed = callback->check_app_agreed;
188 engine_info->callbacks->need_app_credential = callback->need_app_credential;
190 engine_info->callbacks->private_data_set = NULL;
191 engine_info->callbacks->private_data_requested = NULL;
192 engine_info->callbacks->activated_mode_changed = NULL;
194 SLOG(LOG_DEBUG, tts_tag(), "--- Valid Engine ---");
195 SLOG(LOG_DEBUG, tts_tag(), "Engine uuid : %s", engine_info->engine_uuid);
196 SLOG(LOG_DEBUG, tts_tag(), "Engine name : %s", engine_info->engine_name);
197 SLOG(LOG_DEBUG, tts_tag(), "Engine path : %s", engine_info->engine_path);
198 SLOG(LOG_DEBUG, tts_tag(), "Engine setting path : %s", engine_info->engine_setting_path);
199 SLOG(LOG_DEBUG, tts_tag(), "Use network : %s", engine_info->use_network ? "true" : "false");
200 SLOG(LOG_DEBUG, tts_tag(), "--------------------");
201 SLOG(LOG_DEBUG, tts_tag(), " ");
203 return TTSD_ERROR_NONE;
206 int ttsd_engine_agent_init(ttse_request_callback_s *callback)
208 if (__is_agent_initialized()) {
209 SLOG(LOG_WARN, tts_tag(), "[Engine Agent] Already initialized");
210 return TTSD_ERROR_NONE;
213 if (false == __is_callback_valid(callback)) {
214 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
215 return TTSD_ERROR_ENGINE_NOT_FOUND;
218 ttsengine_info_s* temp;
219 temp = (ttsengine_info_s*)calloc(1, sizeof(ttsengine_info_s));
221 SLOG(LOG_WARN, tts_tag(), "[Engine Agent] Fail to alloc memory");
222 return TTSD_ERROR_OUT_OF_MEMORY;
225 if (0 != ttsd_config_get_default_voice(&(temp->default_lang), &(temp->default_vctype))) {
226 SLOG(LOG_WARN, tts_tag(), "[Server WARNING] There is No default voice in config");
227 /* Set default voice */
228 temp->default_lang = strdup(TTS_BASE_LANGUAGE);
229 temp->default_vctype = TTSE_VOICE_TYPE_FEMALE;
232 SLOG(LOG_DEBUG, tts_tag(), "[Server DEBUG] language(%s), type(%d)", temp->default_lang, temp->default_vctype);
234 if (0 != ttsd_config_get_default_speed(&(temp->default_speed))) {
235 SLOG(LOG_WARN, tts_tag(), "[Server WARNING] There is No default speed in config");
236 temp->default_speed = TTS_SPEED_NORMAL;
239 if (0 != ttsd_config_get_default_pitch(&(temp->default_pitch))) {
240 SLOG(LOG_WARN, tts_tag(), "[Server WARNING] There is No default pitch in config");
241 temp->default_pitch = TTS_PITCH_NORMAL;
244 /* Get current engine info */
245 int ret = __set_engine_callback(callback, temp);
246 if (TTSD_ERROR_NONE != ret) {
247 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get engine info");
253 g_engine_info = temp;
256 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Initialize Engine Agent");
257 return TTSD_ERROR_NONE;
260 int ttsd_engine_agent_release()
262 if (false == __is_agent_initialized()) {
263 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
264 return TTSD_ERROR_INVALID_STATE;
267 /* unload current engine */
268 if (__is_engine_loaded()) {
269 ttsd_engine_agent_unload_current_engine();
272 if (NULL != g_engine_info->default_lang) {
273 free(g_engine_info->default_lang);
274 g_engine_info->default_lang = NULL;
277 if (NULL != g_engine_info->engine_uuid) {
278 free(g_engine_info->engine_uuid);
279 g_engine_info->engine_uuid = NULL;
282 if (NULL != g_engine_info->engine_name) {
283 free(g_engine_info->engine_name);
284 g_engine_info->engine_name = NULL;
287 if (NULL != g_engine_info->engine_setting_path) {
288 free(g_engine_info->engine_setting_path);
289 g_engine_info->engine_setting_path = NULL;
292 if (NULL != g_engine_info->engine_path) {
293 free(g_engine_info->engine_path);
294 g_engine_info->engine_path = NULL;
298 g_engine_info = NULL;
300 g_agent_init = false;
302 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Release Engine Agent");
304 return TTSD_ERROR_NONE;
307 static bool __set_voice_info_cb(const char* language, int type, void* user_data)
309 if (NULL == language) {
310 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
314 ttsvoice_s* voice = calloc(1, sizeof(ttsvoice_s));
316 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
319 voice->lang = strdup(language);
322 voice->client_ref_count = 0;
323 voice->is_loaded = false;
325 if (0 == strcmp(g_engine_info->default_lang, language) && g_engine_info->default_vctype == type) {
326 voice->is_default = true;
327 voice->is_loaded = true;
329 voice->is_default = false;
332 g_cur_voices = g_slist_append(g_cur_voices, voice);
337 static void __clear_voice_list()
339 if (NULL == g_cur_voices) {
343 GSList *iter = g_slist_nth(g_cur_voices, 0);
344 while (NULL != iter) {
345 ttsvoice_s* data = iter->data;
348 if (NULL != data->lang) {
353 g_cur_voices = g_slist_remove(g_cur_voices, data);
358 iter = g_slist_nth(g_cur_voices, 0);
361 g_slist_free(g_cur_voices);
365 static int __update_voice_list()
367 if (false == __is_agent_initialized()) {
368 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
369 return TTSD_ERROR_INVALID_STATE;
372 __clear_voice_list();
375 ret = g_engine_info->callbacks->foreach_voices(__set_voice_info_cb, NULL);
377 if (0 != ret || 0 >= g_slist_length(g_cur_voices)) {
378 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
379 return TTSD_ERROR_OPERATION_FAILED;
382 #ifdef ENGINE_AGENT_DEBUG
383 ttsd_print_voicelist();
385 return TTSD_ERROR_NONE;
388 int ttsd_engine_agent_load_current_engine()
390 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent DEBUG] load current engine START");
392 if (false == __is_agent_initialized()) {
393 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
394 return TTSD_ERROR_INVALID_STATE;
397 /* check whether current engine is loaded or not */
398 if (__is_engine_loaded()) {
399 SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Engine has already been loaded ");
400 return TTSD_ERROR_NONE;
403 /* Initialize engine */
404 int ret = g_engine_info->callbacks->initialize();
406 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to initialize current engine : %s", __ttsd_get_engine_error_code(ret));
407 return TTSD_ERROR_OPERATION_FAILED;
410 /* Get voice info of current engine */
411 ret = __update_voice_list();
413 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set voice info : result(%d)", ret);
414 return TTSD_ERROR_OPERATION_FAILED;
417 /* Select default voice */
418 if (NULL != g_engine_info->default_lang) {
419 bool is_valid = false;
420 ret = g_engine_info->callbacks->is_valid_voice(g_engine_info->default_lang, g_engine_info->default_vctype, &is_valid);
422 if (true == is_valid) {
423 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Set origin default voice to current engine : lang(%s), type(%d)",
424 g_engine_info->default_lang, g_engine_info->default_vctype);
426 SLOG(LOG_WARN, tts_tag(), "[Engine Agent WARNING] Fail to set origin default voice : lang(%s), type(%d)",
427 g_engine_info->default_lang, g_engine_info->default_vctype);
429 /* TODO - Error Tolerance when Default voice is not valid */
430 return TTSD_ERROR_OPERATION_FAILED;
433 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail(Engine ERROR) : %s", __ttsd_get_engine_error_code(ret));
438 /* load default voice */
439 ret = g_engine_info->callbacks->load_voice(g_engine_info->default_lang, g_engine_info->default_vctype);
441 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Load default voice : lang(%s), type(%d)",
442 g_engine_info->default_lang, g_engine_info->default_vctype);
444 SLOG(LOG_WARN, tts_tag(), "[Engine Agent ERROR] Fail to load default voice : lang(%s), type(%d) result(%s)",
445 g_engine_info->default_lang, g_engine_info->default_vctype, __ttsd_get_engine_error_code(ret));
447 return TTSD_ERROR_OPERATION_FAILED;
450 /* set default pitch */
451 ret = g_engine_info->callbacks->set_pitch(g_engine_info->default_pitch);
453 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)",
454 g_engine_info->default_pitch, __ttsd_get_engine_error_code(ret));
457 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Set default pitch : pitch(%d)", g_engine_info->default_pitch);
460 g_engine_info->is_loaded = true;
462 return TTSD_ERROR_NONE;
465 int ttsd_engine_agent_unload_current_engine()
467 if (false == __is_agent_initialized()) {
468 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
469 return TTSD_ERROR_INVALID_STATE;
472 if (false == __is_engine_loaded()) {
473 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Engine has already been unloaded ");
474 return TTSD_ERROR_NONE;
477 /* shutdown engine */
479 ret = g_engine_info->callbacks->deinitialize();
481 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent] Fail deinitialize() : %s", __ttsd_get_engine_error_code(ret));
484 /* reset current engine data */
485 g_engine_info->is_loaded = false;
487 __clear_voice_list();
489 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent Success] Unload current engine");
491 return TTSD_ERROR_NONE;
494 bool ttsd_engine_agent_need_network()
496 if (false == __is_agent_initialized()) {
497 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
501 return g_engine_info->use_network;
504 bool ttsd_engine_agent_is_same_engine(const char* engine_id)
506 if (NULL == engine_id) {
507 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] engine_id is NULL");
511 int ret = __check_engine_initialized_and_loaded();
512 if (TTSD_ERROR_NONE != ret) {
513 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
517 /* compare current engine and engine id.*/
518 if (NULL != g_engine_info->engine_uuid && 0 == strncmp(g_engine_info->engine_uuid, engine_id, strlen(engine_id))) {
525 bool ttsd_engine_select_valid_voice(const char* lang, int type, char** out_lang, int* out_type)
527 if (NULL == lang || NULL == out_lang || NULL == out_type) {
531 int ret = __check_engine_initialized_and_loaded();
532 if (TTSD_ERROR_NONE != ret) {
533 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
537 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Select voice : input lang(%s), input type(%d), default lang(%s), default type(%d)",
538 (NULL == lang) ? "NULL" : lang, type, (NULL == g_engine_info->default_lang) ? "NULL" : g_engine_info->default_lang, g_engine_info->default_vctype);
540 /* case 1 : Both are default */
541 if (0 == strncmp(lang, "default", strlen(lang)) && 0 == type) {
542 if (NULL != g_engine_info->default_lang) {
543 *out_lang = strdup(g_engine_info->default_lang);
548 *out_type = g_engine_info->default_vctype;
553 GList* voice_list = NULL;
554 ret = g_engine_info->callbacks->foreach_voices(__supported_voice_cb, &voice_list);
555 if (0 != ret || 0 >= g_list_length(voice_list)) {
556 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
566 /* case 2 : lang and type are not default type */
567 if (0 != strncmp(lang, "default", strlen("default")) && 0 != type) {
568 iter = g_list_first(voice_list);
570 while (NULL != iter) {
571 /* Get handle data from list */
574 if (0 == strncmp(voice->language, lang, strlen(lang)) && voice->type == type) {
575 *out_lang = strdup(voice->language);
576 *out_type = voice->type;
581 iter = g_list_next(iter);
584 } else if (0 != strncmp(lang, "default", strlen("default")) && 0 == type) {
585 /* Only type is default */
586 if (0 == strncmp(lang, g_engine_info->default_lang, strlen(g_engine_info->default_lang))) {
587 *out_lang = strdup(g_engine_info->default_lang);
588 *out_type = g_engine_info->default_vctype;
591 voice_s* voice_selected = NULL;
592 iter = g_list_first(voice_list);
593 while (NULL != iter) {
594 /* Get handle data from list */
597 if (0 == strncmp(voice->language, lang, strlen(lang))) {
598 voice_selected = voice;
599 if (voice->type == g_engine_info->default_vctype) {
600 voice_selected = voice;
604 iter = g_list_next(iter);
607 if (NULL != voice_selected) {
608 *out_lang = strdup(voice_selected->language);
609 *out_type = voice_selected->type;
613 } else if (0 == strncmp(lang, "default", strlen("default")) && 0 != type) {
614 /* Only lang is default */
615 if (type == g_engine_info->default_vctype) {
616 *out_lang = strdup(g_engine_info->default_lang);
617 *out_type = g_engine_info->default_vctype;
620 voice_s* voice_selected = NULL;
621 iter = g_list_first(voice_list);
622 while (NULL != iter) {
623 /* Get handle data from list */
626 if (0 == strncmp(voice->language, g_engine_info->default_lang, strlen(g_engine_info->default_lang))) {
627 voice_selected = voice;
628 if (voice->type == type) {
629 voice_selected = voice;
633 iter = g_list_next(iter);
636 if (NULL != voice_selected) {
637 *out_lang = strdup(voice->language);
638 *out_type = voice_selected->type;
644 if (true == result) {
645 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Selected voice : lang(%s), type(%d)", *out_lang, *out_type);
648 __free_voice_list(voice_list);
653 static ttsvoice_s* __get_ttsvoice(const char* lang, const int vctype)
656 ttsvoice_s* data = NULL;
658 iter = g_slist_nth(g_cur_voices, 0);
659 while (NULL != iter) {
660 /*Get handle data from list*/
664 if (NULL != data->lang && 0 == strcmp(data->lang, lang) && data->type == vctype) {
665 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
666 data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
672 iter = g_slist_next(iter);
679 int ttsd_engine_agent_set_default_voice(const char* language, int vctype)
681 if (NULL == language) {
682 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] language is NULL");
683 return TTSD_ERROR_INVALID_PARAMETER;
686 int ret = __check_engine_initialized_and_loaded();
687 if (TTSD_ERROR_NONE != ret) {
688 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
692 bool is_valid = false;
693 ret = g_engine_info->callbacks->is_valid_voice(language, vctype, &is_valid);
695 if (true == is_valid) {
696 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Current voice is valid : lang(%s), type(%d)",
697 (NULL == g_engine_info->default_lang) ? "NULL" : g_engine_info->default_lang, g_engine_info->default_vctype);
699 SLOG(LOG_WARN, tts_tag(), "[Engine Agent WARNING] Current voice is invalid : lang(%s), type(%d)",
700 (NULL == g_engine_info->default_lang) ? "NULL" : g_engine_info->default_lang, g_engine_info->default_vctype);
702 return TTSD_ERROR_OPERATION_FAILED;
705 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail(Engine ERROR) : %s", __ttsd_get_engine_error_code(ret));
709 /* Update new default voice info */
710 ttsvoice_s* data = __get_ttsvoice(language, vctype);
712 data->is_default = true;
713 if (0 == data->client_ref_count) {
715 ret = g_engine_info->callbacks->load_voice(data->lang, data->type);
717 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] load voice : lang(%s), type(%d)",
718 data->lang, data->type);
719 data->is_loaded = true;
721 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
722 data->lang, data->type, __ttsd_get_engine_error_code(ret));
727 #ifdef ENGINE_AGENT_DEBUG
728 ttsd_print_voicelist();
731 /* Update old default voice info */
732 data = __get_ttsvoice(g_engine_info->default_lang, g_engine_info->default_vctype);
734 data->is_default = false;
735 if (0 == data->client_ref_count) {
737 ret = g_engine_info->callbacks->unload_voice(data->lang, data->type);
739 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
740 data->lang, data->type);
741 data->is_loaded = false;
743 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
744 data->lang, data->type, __ttsd_get_engine_error_code(ret));
749 if (NULL != g_engine_info->default_lang) {
750 free(g_engine_info->default_lang);
751 g_engine_info->default_lang = NULL;
754 g_engine_info->default_lang = strdup(language);
755 g_engine_info->default_vctype = vctype;
757 #ifdef ENGINE_AGENT_DEBUG
758 ttsd_print_voicelist();
761 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Set default voice : lang(%s), type(%d)",
762 g_engine_info->default_lang, g_engine_info->default_vctype);
764 return TTSD_ERROR_NONE;
767 int ttsd_engine_agent_set_default_speed(int speed)
769 if (false == __is_agent_initialized()) {
770 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
771 return TTSD_ERROR_INVALID_STATE;
774 g_engine_info->default_speed = speed;
776 return TTSD_ERROR_NONE;
779 int ttsd_engine_agent_set_default_pitch(int pitch)
781 int ret = __check_engine_initialized_and_loaded();
782 if (TTSD_ERROR_NONE != ret) {
783 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
787 ret = g_engine_info->callbacks->set_pitch(pitch);
789 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)",
790 pitch, __ttsd_get_engine_error_code(ret));
791 return TTSD_ERROR_OPERATION_FAILED;
794 g_engine_info->default_pitch = pitch;
796 SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Set pitch(%d)", pitch);
797 return TTSD_ERROR_NONE;
800 int ttsd_engine_agent_is_credential_needed(unsigned int uid, bool* credential_needed)
802 if (NULL == credential_needed) {
803 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid Parameter");
804 return TTSD_ERROR_INVALID_PARAMETER;
807 int ret = __check_engine_initialized_and_loaded();
808 if (TTSD_ERROR_NONE != ret) {
809 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
813 if (NULL == g_engine_info->callbacks->need_app_credential) {
814 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not support to check app credential");
815 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
819 result = g_engine_info->callbacks->need_app_credential();
820 *credential_needed = result;
822 SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Need app credential, credential_needed(%d)", *credential_needed);
823 return TTSD_ERROR_NONE;
826 /******************************************************************************************
827 * TTS Engine Interfaces for client
828 *******************************************************************************************/
830 int ttsd_engine_load_voice(const char* lang, const int vctype)
833 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No language parameter");
834 return TTSD_ERROR_INVALID_PARAMETER;
837 int ret = __check_engine_initialized_and_loaded();
838 if (TTSD_ERROR_NONE != ret) {
839 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
843 /* 1. Find voice info */
844 ttsvoice_s* data = __get_ttsvoice(lang, vctype);
846 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
847 return TTSD_ERROR_OPERATION_FAILED;
850 /* 2. increase ref count */
851 data->client_ref_count++;
853 /* 3. if ref count change 0 to 1 and not default, load voice */
854 if (1 == data->client_ref_count && false == data->is_default) {
856 ret = g_engine_info->callbacks->load_voice(data->lang, data->type);
858 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Load voice : lang(%s), type(%d)",
859 data->lang, data->type);
860 data->is_loaded = true;
862 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
863 data->lang, data->type, __ttsd_get_engine_error_code(ret));
865 return TTSD_ERROR_OPERATION_FAILED;
868 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Not load voice : default voice(%d) or ref count(%d)",
869 data->is_default, data->client_ref_count);
872 #ifdef ENGINE_AGENT_DEBUG
873 ttsd_print_voicelist();
876 return TTSD_ERROR_NONE;
879 int ttsd_engine_unload_voice(const char* lang, const int vctype)
882 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No language parameter");
883 return TTSD_ERROR_INVALID_PARAMETER;
886 int ret = __check_engine_initialized_and_loaded();
887 if (TTSD_ERROR_NONE != ret) {
888 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
892 /* 1. Find voice info */
893 ttsvoice_s* data = __get_ttsvoice(lang, vctype);
895 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
896 return TTSD_ERROR_OPERATION_FAILED;
899 /* 2. Decrease ref count */
900 data->client_ref_count--;
902 /* 3. if ref count change 0 and not default, load voice */
903 if (0 == data->client_ref_count && false == data->is_default) {
905 ret = g_engine_info->callbacks->unload_voice(data->lang, data->type);
907 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)",
908 data->lang, data->type);
909 data->is_loaded = false;
911 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
912 data->lang, data->type, __ttsd_get_engine_error_code(ret));
914 return TTSD_ERROR_OPERATION_FAILED;
917 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Not unload voice : default voice(%d) or ref count(%d)",
918 data->is_default, data->client_ref_count);
921 #ifdef ENGINE_AGENT_DEBUG
922 ttsd_print_voicelist();
924 return TTSD_ERROR_NONE;
927 int ttsd_engine_start_synthesis(const char* lang, int vctype, const char* text, int speed, const char* appid, const char* credential, void* user_param)
929 if (NULL == lang || NULL == text) {
930 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
931 return TTSD_ERROR_INVALID_PARAMETER;
934 int ret = __check_engine_initialized_and_loaded();
935 if (TTSD_ERROR_NONE != ret) {
936 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
940 /* select voice for default */
941 char* temp_lang = NULL;
943 if (true != ttsd_engine_select_valid_voice(lang, vctype, &temp_lang, &temp_type)) {
944 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to select default voice");
945 if (NULL != temp_lang) {
949 return TTSD_ERROR_INVALID_VOICE;
951 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Start synthesis : language(%s), type(%d), speed(%d), text(%s), credential(%s)",
952 (NULL == temp_lang) ? "NULL" : temp_lang, temp_type, speed, (NULL == text) ? "NULL" : text, (NULL == credential) ? "NULL" : credential);
958 temp_speed = g_engine_info->default_speed;
963 /* synthesize text */
964 ret = g_engine_info->callbacks->start_synth(temp_lang, temp_type, text, temp_speed, appid, credential, user_param);
966 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] ***************************************");
967 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] * synthesize error : %s *", __ttsd_get_engine_error_code(ret));
968 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] ***************************************");
969 if (NULL != temp_lang) {
976 if (NULL != temp_lang) {
980 return TTSD_ERROR_NONE;
983 int ttsd_engine_cancel_synthesis()
985 int ret = __check_engine_initialized_and_loaded();
986 if (TTSD_ERROR_NONE != ret) {
987 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
991 SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Cancel synth");
993 ret = g_engine_info->callbacks->cancel_synth();
995 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail cancel synthesis : %s", __ttsd_get_engine_error_code(ret));
1001 bool __supported_voice_cb(const char* language, int type, void* user_data)
1003 GList** voice_list = (GList**)user_data;
1005 if (NULL == language || NULL == voice_list) {
1006 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
1010 voice_s* voice = calloc(1, sizeof(voice_s));
1011 if (NULL == voice) {
1012 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
1015 voice->language = strdup(language);
1018 *voice_list = g_list_append(*voice_list, voice);
1023 int ttsd_engine_get_voice_list(GList** voice_list)
1025 if (NULL == voice_list) {
1026 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1027 return TTSD_ERROR_INVALID_PARAMETER;
1030 int ret = __check_engine_initialized_and_loaded();
1031 if (TTSD_ERROR_NONE != ret) {
1032 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
1036 ret = g_engine_info->callbacks->foreach_voices(__supported_voice_cb, (void*)voice_list);
1038 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get voice list : %s", __ttsd_get_engine_error_code(ret));
1044 int ttsd_engine_get_default_voice(char** lang, int* vctype)
1046 if (NULL == lang || NULL == vctype) {
1047 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] BAD Parameter");
1048 return TTSD_ERROR_INVALID_PARAMETER;
1051 int ret = __check_engine_initialized_and_loaded();
1052 if (TTSD_ERROR_NONE != ret) {
1053 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
1057 if (NULL != g_engine_info->default_lang) {
1058 *lang = strdup(g_engine_info->default_lang);
1059 *vctype = g_engine_info->default_vctype;
1061 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine] Get default voice : language(%s), type(%d)", *lang, *vctype);
1063 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Default voice is NULL");
1064 return TTSD_ERROR_OPERATION_FAILED;
1067 return TTSD_ERROR_NONE;
1070 int ttsd_engine_set_private_data(const char* key, const char* data)
1073 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1074 return TTSD_ERROR_INVALID_PARAMETER;
1077 int ret = __check_engine_initialized_and_loaded();
1078 if (TTSD_ERROR_NONE != ret) {
1079 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
1083 if (NULL == g_engine_info->callbacks->private_data_set) {
1084 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1085 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1088 ret = g_engine_info->callbacks->private_data_set(key, data);
1090 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set private data(%d)", ret);
1096 int ttsd_engine_get_private_data(const char* key, char** data)
1098 if (NULL == key || NULL == data) {
1099 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1100 return TTSD_ERROR_INVALID_PARAMETER;
1103 int ret = __check_engine_initialized_and_loaded();
1104 if (TTSD_ERROR_NONE != ret) {
1105 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
1109 if (NULL == g_engine_info->callbacks->private_data_requested) {
1110 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1111 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1115 ret = g_engine_info->callbacks->private_data_requested(key, &temp);
1117 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get private data(%d)", ret);
1121 *data = strdup("NULL");
1123 *data = strdup(temp);
1128 int ttsd_engine_check_app_agreed(const char* appid, bool* is_agreed)
1130 if (NULL == appid || NULL == is_agreed) {
1131 SLOG(LOG_WARN, tts_tag(), "[Engine Agent WARNING] Invalid parameter, appid is NULL");
1132 return TTSD_ERROR_NONE;
1135 int ret = __check_engine_initialized_and_loaded();
1136 if (TTSD_ERROR_NONE != ret) {
1137 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Precondition is not met(%s)", get_error_message(ret));
1141 if (NULL == g_engine_info->callbacks->check_app_agreed) {
1142 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1143 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1146 bool tmp = true; // default value is true until now
1147 ret = g_engine_info->callbacks->check_app_agreed(appid, &tmp);
1149 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to check app agreed(%d)", ret);
1150 return TTSD_ERROR_OPERATION_FAILED;
1158 int ttsd_engine_notify_activated_mode_changed(int activated_mode)
1160 if (false == __is_agent_initialized()) {
1161 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1162 return TTSD_ERROR_INVALID_STATE;
1165 if (NULL == g_engine_info->callbacks->activated_mode_changed) {
1166 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1167 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1170 g_engine_info->callbacks->activated_mode_changed(activated_mode);
1172 return TTSD_ERROR_NONE;
1175 void __free_voice_list(GList* voice_list)
1178 voice_s* data = NULL;
1180 /* if list have item */
1181 if (g_list_length(voice_list) > 0) {
1182 /* Get a first item */
1183 iter = g_list_first(voice_list);
1185 while (NULL != iter) {
1189 if (NULL != data->language) {
1190 free(data->language);
1191 data->language = NULL;
1197 voice_list = g_list_remove_link(voice_list, iter);
1199 iter = g_list_first(voice_list);
1205 * TTS Engine Callback Functions ` *
1208 /* function for debugging */
1209 int ttsd_print_voicelist()
1212 GSList *iter = NULL;
1213 ttsvoice_s* data = NULL;
1215 SLOG(LOG_DEBUG, tts_tag(), "@@@ Voice list @@@");
1217 if (g_slist_length(g_cur_voices) > 0) {
1218 /* Get a first item */
1219 iter = g_slist_nth(g_cur_voices, 0);
1222 while (NULL != iter) {
1223 /*Get handle data from list*/
1226 if (NULL == data || NULL == data->lang) {
1227 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Data is invalid");
1228 return TTSD_ERROR_NONE;
1231 SLOG(LOG_DEBUG, tts_tag(), "[%dth] default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1232 i, data->is_default, data->is_loaded, data->client_ref_count, data->lang, data->type);
1235 iter = g_slist_next(iter);
1240 SLOG(LOG_DEBUG, tts_tag(), "@@@@@");
1242 return TTSD_ERROR_NONE;
1246 /** Set callbacks of the current engine */
1247 int ttsd_engine_agent_set_private_data_set_cb(ttse_private_data_set_cb callback)
1249 if (false == __is_agent_initialized()) {
1250 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1251 return TTSD_ERROR_INVALID_STATE;
1254 g_engine_info->callbacks->private_data_set = callback;
1256 return TTSD_ERROR_NONE;
1259 int ttsd_engine_agent_set_private_data_requested_cb(ttse_private_data_requested_cb callback)
1261 if (false == __is_agent_initialized()) {
1262 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1263 return TTSD_ERROR_INVALID_STATE;
1266 g_engine_info->callbacks->private_data_requested = callback;
1268 return TTSD_ERROR_NONE;
1271 int ttsd_engine_agent_set_activated_mode_changed_cb(ttse_activated_mode_changed_cb callback)
1273 if (false == __is_agent_initialized()) {
1274 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1275 return TTSD_ERROR_INVALID_STATE;
1278 g_engine_info->callbacks->activated_mode_changed = callback;
1280 return TTSD_ERROR_NONE;