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.
20 #include "tts_config_parser.h"
24 #define TTS_TAG_ENGINE_BASE_TAG "tts-engine"
25 #define TTS_TAG_ENGINE_NAME "name"
26 #define TTS_TAG_ENGINE_ID "id"
27 #define TTS_TAG_ENGINE_SETTING "setting"
28 #define TTS_TAG_ENGINE_VOICE_SET "voices"
29 #define TTS_TAG_ENGINE_VOICE "voice"
30 #define TTS_TAG_ENGINE_VOICE_TYPE "type"
31 #define TTS_TAG_ENGINE_PITCH_SUPPORT "pitch-support"
32 #define TTS_TAG_ENGINE_TEXT_SIZE "text-size"
34 #define TTS_TAG_CONFIG_BASE_TAG "tts-config"
35 #define TTS_TAG_CONFIG_ENGINE_ID "engine"
36 #define TTS_TAG_CONFIG_ENGINE_SETTING "engine-setting"
37 #define TTS_TAG_CONFIG_AUTO_VOICE "auto"
38 #define TTS_TAG_CONFIG_VOICE_TYPE "voice-type"
39 #define TTS_TAG_CONFIG_LANGUAGE "language"
40 #define TTS_TAG_CONFIG_SPEECH_RATE "speech-rate"
41 #define TTS_TAG_CONFIG_PITCH "pitch"
42 #define TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO "background-volume-ratio"
43 #define TTS_TAG_VOICE_TYPE_FEMALE "female"
44 #define TTS_TAG_VOICE_TYPE_MALE "male"
45 #define TTS_TAG_VOICE_TYPE_CHILD "child"
47 #define TTS_MAX_TEXT_SIZE 2000
49 static xmlDocPtr g_config_doc = NULL;
50 char g_engine_id[128] = {0,};
51 char g_setting[128] = {0,};
52 char g_language[128] = {0,};
54 static tts_config_s* g_config_info = NULL;
56 static pthread_mutex_t g_config_info_mutex = PTHREAD_MUTEX_INITIALIZER;
58 int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info)
60 if (NULL == path || NULL == engine_info) {
61 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
65 // Avoid to parse non-xml file
66 char* file_ext = strrchr(path, '.');
67 if (NULL == ++file_ext || (file_ext && 0 != strncmp("xml", file_ext, strlen(file_ext)))) {
68 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] File extention is not XML type, file_ext(%s)", (file_ext) ? file_ext : "NULL");
72 bool isTextsize = false;
74 xmlNodePtr cur = NULL;
78 if (0 == access(path, F_OK)) {
79 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Success to access to %s", path);
80 doc = xmlParseFile(path);
82 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse xml file");
86 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to access to %s", path);
90 cur = xmlDocGetRootElement(doc);
92 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document. doc path(%s, %p)", path, doc);
98 if (xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_BASE_TAG)) {
99 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] The wrong type, root node is NOT 'tts-engine'. doc path(%s, %p)", path, doc);
105 cur = cur->xmlChildrenNode;
107 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document. doc path(%s, %p)", path, doc);
113 /* alloc engine info */
114 tts_engine_info_s* temp;
115 temp = (tts_engine_info_s*)calloc(1, sizeof(tts_engine_info_s));
117 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Out of memory. doc path(%s, %p)", path, doc);
126 temp->setting = NULL;
127 temp->pitch_support = false;
130 while (cur != NULL) {
131 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_NAME)) {
132 key = xmlNodeGetContent(cur);
134 if (NULL != temp->name) {
138 temp->name = strdup((char*)key);
142 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_NAME);
144 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_ID)) {
145 key = xmlNodeGetContent(cur);
147 if (NULL != temp->uuid) {
151 temp->uuid = strdup((char*)key);
155 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_ID);
157 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_SETTING)) {
158 key = xmlNodeGetContent(cur);
160 if (NULL != temp->setting) {
162 temp->setting = NULL;
164 temp->setting = strdup((char*)key);
168 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_SETTING);
170 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE_SET)) {
171 xmlNodePtr voice_node = NULL;
172 voice_node = cur->xmlChildrenNode;
174 while (NULL != voice_node) {
175 if (0 == xmlStrcmp(voice_node->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE)) {
176 tts_config_voice_s* temp_voice = (tts_config_voice_s*)calloc(1, sizeof(tts_config_voice_s));
177 if (NULL == temp_voice) {
178 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Out of memory");
182 attr = xmlGetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE);
184 if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
185 temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
186 } else if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
187 temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
188 } else if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
189 temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
191 temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_USER_DEFINED;
196 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE_TYPE);
202 key = xmlNodeGetContent(voice_node);
204 if (NULL != temp_voice->language) {
205 free(temp_voice->language);
206 temp_voice->language = NULL;
208 temp_voice->language = strdup((char*)key);
211 temp->voices = g_slist_append(temp->voices, temp_voice);
213 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE);
214 if (NULL != temp_voice) {
220 voice_node = voice_node->next;
222 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_PITCH_SUPPORT)) {
223 key = xmlNodeGetContent(cur);
225 if (0 == xmlStrcmp(key, (const xmlChar *)"true")) {
226 temp->pitch_support = true;
231 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_PITCH_SUPPORT);
233 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_TEXT_SIZE)) {
235 key = xmlNodeGetContent(cur);
237 temp->text_size = atoi((char*)key);
240 SLOG(LOG_INFO, TAG_TTSCONFIG, "[INFO] text size is unlimited.");
247 if (false == isTextsize) {
248 temp->text_size = TTS_MAX_TEXT_SIZE;
252 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] doc path(%s, %p)", path, doc);
257 if (NULL == temp->uuid) {
259 SECURE_SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Invalid engine : %s", path);
260 tts_parser_free_engine_info(temp);
269 int tts_parser_free_engine_info(tts_engine_info_s* engine_info)
271 if (NULL == engine_info) {
272 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
276 if (NULL != engine_info->name) {
277 free(engine_info->name);
278 engine_info->name = NULL;
280 if (NULL != engine_info->uuid) {
281 free(engine_info->uuid);
282 engine_info->uuid = NULL;
284 if (NULL != engine_info->setting) {
285 free(engine_info->setting);
286 engine_info->setting = NULL;
289 tts_config_voice_s *temp_voice;
290 temp_voice = g_slist_nth_data(engine_info->voices, 0);
292 while (NULL != temp_voice) {
293 if (NULL != temp_voice) {
294 if (NULL != temp_voice->language) {
295 free(temp_voice->language);
296 temp_voice->language = NULL;
298 engine_info->voices = g_slist_remove(engine_info->voices, temp_voice);
303 temp_voice = g_slist_nth_data(engine_info->voices, 0);
306 if (NULL != engine_info) {
314 int tts_parser_print_engine_info(tts_engine_info_s* engine_info)
316 if (NULL == engine_info) {
317 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
321 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "== get engine info ==");
322 SLOG(LOG_DEBUG, TAG_TTSCONFIG, " name : %s", engine_info->name);
323 SLOG(LOG_DEBUG, TAG_TTSCONFIG, " id : %s", engine_info->uuid);
324 if (NULL != engine_info->setting)
325 SLOG(LOG_DEBUG, TAG_TTSCONFIG, " setting : %s", engine_info->setting);
327 SLOG(LOG_DEBUG, TAG_TTSCONFIG, " voices");
329 tts_config_voice_s *temp_voice;
331 if (g_slist_length(engine_info->voices) > 0) {
332 /* Get a first item */
333 iter = g_slist_nth(engine_info->voices, 0);
336 while (NULL != iter) {
337 /*Get handle data from list*/
338 temp_voice = iter->data;
340 SLOG(LOG_DEBUG, TAG_TTSCONFIG, " [%dth] type(%d) lang(%s)",
341 i, temp_voice->type, temp_voice->language);
344 iter = g_slist_next(iter);
348 SLOG(LOG_ERROR, TAG_TTSCONFIG, " Voice is NONE");
351 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@");
356 int tts_parser_load_config(void)
358 xmlDocPtr doc = NULL;
359 xmlNodePtr cur = NULL;
361 bool is_default_open = false;
363 /* For Thread safety */
366 if (0 != access(TTS_CONFIG, F_OK)) {
367 doc = xmlParseFile(TTS_DEFAULT_CONFIG);
369 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", TTS_DEFAULT_CONFIG);
373 is_default_open = true;
377 while (NULL == doc) {
378 doc = xmlParseFile(TTS_CONFIG);
385 if (TTS_RETRY_COUNT == retry_count) {
386 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
387 doc = xmlParseFile(TTS_DEFAULT_CONFIG);
389 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", TTS_DEFAULT_CONFIG);
393 is_default_open = true;
399 cur = xmlDocGetRootElement(doc);
401 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document(%p)", doc);
408 if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
409 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] The wrong type, root node is NOT %s. doc(%p)", TTS_TAG_CONFIG_BASE_TAG, doc);
416 cur = cur->xmlChildrenNode;
418 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document(%p)", doc);
425 /* alloc engine info */
427 temp = (tts_config_s*)calloc(1, sizeof(tts_config_s));
429 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Out of memory(%p)", doc);
436 memset(g_engine_id, '\0', sizeof(g_engine_id));
437 memset(g_setting, '\0', sizeof(g_setting));
438 memset(g_language, '\0', sizeof(g_language));
440 temp->engine_id = g_engine_id;
441 temp->setting = g_setting;
442 temp->language = g_language;
444 while (cur != NULL) {
445 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_ID)) {
446 key = xmlNodeGetContent(cur);
448 strncpy(temp->engine_id, (char*)key, sizeof(g_engine_id) - 1);
452 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] engine id is NULL");
454 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_SETTING)) {
455 key = xmlNodeGetContent(cur);
457 strncpy(temp->setting, (char*)key, sizeof(g_setting) - 1);
461 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] setting path is NULL");
463 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_AUTO_VOICE)) {
464 key = xmlNodeGetContent(cur);
466 if (0 == xmlStrcmp(key, (const xmlChar *)"on")) {
467 temp->auto_voice = true;
468 } else if (0 == xmlStrcmp(key, (const xmlChar *)"off")) {
469 temp->auto_voice = false;
471 SLOG(LOG_ERROR, TAG_TTSCONFIG, "Auto voice is wrong");
472 temp->auto_voice = true;
478 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] voice type is NULL");
480 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_VOICE_TYPE)) {
481 key = xmlNodeGetContent(cur);
483 if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
484 temp->type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
485 } else if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
486 temp->type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
487 } else if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
488 temp->type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
490 SLOG(LOG_WARN, TAG_TTSCONFIG, "Voice type is user defined");
491 temp->type = (int)TTS_CONFIG_VOICE_TYPE_USER_DEFINED;
497 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] voice type is NULL");
499 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
500 key = xmlNodeGetContent(cur);
502 strncpy(temp->language, (char*)key, sizeof(g_language) - 1);
506 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] engine uuid is NULL");
509 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_SPEECH_RATE)) {
510 key = xmlNodeGetContent(cur);
512 temp->speech_rate = atoi((char*)key);
515 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] speech rate is NULL");
517 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_PITCH)) {
518 key = xmlNodeGetContent(cur);
520 temp->pitch = atoi((char*)key);
524 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Pitch is NULL");
526 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO)) {
527 key = xmlNodeGetContent(cur);
529 temp->bg_volume_ratio = atof((char*)key);
533 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Background volume ratio is NULL");
542 g_config_info = temp;
545 if (true == is_default_open) {
549 ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
555 if (TTS_RETRY_COUNT == retry_count) {
556 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Save result : %d", ret);
562 if (0 > chmod(TTS_CONFIG, 0600)) {
563 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to change file mode : %d", ret);
566 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Default config is changed : pid(%d)", getpid());
572 int tts_parser_unload_config(void)
574 if (NULL != g_config_doc) {
575 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Free g_config_doc(%p)", g_config_doc);
576 xmlFreeDoc(g_config_doc);
579 pthread_mutex_lock(&g_config_info_mutex);
580 if (NULL != g_config_info) {
581 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Free config_info(%p)", g_config_info);
583 g_config_info = NULL;
585 pthread_mutex_unlock(&g_config_info_mutex);
591 int tts_parser_set_config_info(tts_config_s* config_info)
593 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Set config info");
594 if (NULL == config_info) {
595 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] config_info is NULL");
598 pthread_mutex_lock(&g_config_info_mutex);
599 if (NULL == g_config_info) {
600 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] g_config_info is NULL");
601 pthread_mutex_unlock(&g_config_info_mutex);
604 memcpy(g_config_info, config_info, sizeof(tts_config_s));
605 pthread_mutex_unlock(&g_config_info_mutex);
609 int tts_parser_get_config_info(tts_config_s* config_info)
611 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Get config info");
612 if (NULL == config_info) {
613 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] config_info is NULL");
616 pthread_mutex_lock(&g_config_info_mutex);
617 if (NULL == g_config_info) {
618 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] g_config_info is NULL");
619 pthread_mutex_unlock(&g_config_info_mutex);
622 memcpy(config_info, g_config_info, sizeof(tts_config_s));
623 pthread_mutex_unlock(&g_config_info_mutex);
627 int tts_parser_copy_xml(const char* original, const char* destination)
629 if (NULL == original || NULL == destination) {
630 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
634 xmlDocPtr doc = NULL;
635 if (0 == access(original, F_OK)) {
636 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Success to access to %s", original);
637 doc = xmlParseFile(original);
639 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", original);
643 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to access to %s", original);
647 int ret = xmlSaveFile(destination, doc);
649 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Save result : %d", ret);
652 pFile = fopen(destination, "r");
655 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to open file %s", destination);
660 SLOG(LOG_INFO, TAG_TTSCONFIG, "[DEBUG] Success to fsync %s", destination);
662 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Success to save %s", destination);
666 if (0 > chmod(destination, 0600)) {
667 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to change file mode : %d", ret);
671 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] doc(%p)", doc);
676 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[SUCCESS] Copying xml");
681 static int __set_value_into_configuration(const char* key, const char* value)
683 if(NULL == key || NULL == value) {
684 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Parameter is NULL");
687 xmlNodePtr cur = NULL;
688 cur = xmlDocGetRootElement(g_config_doc);
690 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document");
694 if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
695 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
699 cur = cur->xmlChildrenNode;
701 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document");
705 while (cur != NULL) {
706 if (0 == xmlStrcmp(cur->name, (const xmlChar *)key)) {
707 xmlNodeSetContent(cur, (const xmlChar *)value);
709 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Set key(%s) : value(%s)", key, value);
719 static void __save_configuration(xmlDocPtr config_doc)
721 if (0 != access(TTS_CONFIG, F_OK)) {
722 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to access to %s", TTS_CONFIG);
726 int ret = xmlSaveFile(TTS_CONFIG, config_doc);
728 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Save result : %d", ret);
731 pFile = fopen(TTS_CONFIG, "r");
734 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to open file %s", TTS_CONFIG);
739 SLOG(LOG_INFO, TAG_TTSCONFIG, "[DEBUG] Success to fsync %s", TTS_CONFIG);
741 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Success to save %s", TTS_CONFIG);
745 static char* __convert_voice_type_into_char(tts_config_voice_type_e voice_type)
747 switch (voice_type) {
748 case TTS_CONFIG_VOICE_TYPE_MALE:
749 return TTS_TAG_VOICE_TYPE_MALE;
750 case TTS_CONFIG_VOICE_TYPE_FEMALE:
751 return TTS_TAG_VOICE_TYPE_FEMALE;
752 case TTS_CONFIG_VOICE_TYPE_CHILD:
753 return TTS_TAG_VOICE_TYPE_CHILD;
755 return TTS_TAG_VOICE_TYPE_FEMALE;
759 int tts_parser_set_engine(const char* engine_id, const char* setting, const char* language, int type)
761 if (NULL == engine_id) {
762 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
766 if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_ENGINE_ID, engine_id)) {
770 if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_LANGUAGE, language)) {
774 if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_ENGINE_SETTING, setting)) {
778 if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_VOICE_TYPE, __convert_voice_type_into_char(type))) {
782 __save_configuration(g_config_doc);
787 int tts_parser_set_voice(const char* language, int type)
789 if (NULL == language) {
790 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
794 if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_LANGUAGE, language)) {
798 if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_VOICE_TYPE, __convert_voice_type_into_char(type))) {
802 __save_configuration(g_config_doc);
807 int tts_parser_set_auto_voice(bool value)
809 char* temp = value ? "on" : "off";
810 if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_AUTO_VOICE, temp)) {
814 __save_configuration(g_config_doc);
819 int tts_parser_set_speech_rate(int value)
822 memset(temp, '\0', 10);
823 snprintf(temp, 10, "%d", value);
825 if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_SPEECH_RATE, temp)) {
829 __save_configuration(g_config_doc);
834 int tts_parser_set_pitch(int value)
837 memset(temp, '\0', 10);
838 snprintf(temp, 10, "%d", value);
840 if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_PITCH, temp)) {
844 __save_configuration(g_config_doc);
849 int tts_parser_set_bg_volume_ratio(double value)
852 memset(temp, '\0', 10);
853 snprintf(temp, 10, "%lf", value);
855 if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO, temp)) {
859 __save_configuration(g_config_doc);
864 int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voice, char** language, int* voice_type,
865 int* speech_rate, int* pitch, double* bg_volume_ratio)
867 if (NULL == engine || NULL == setting || NULL == language || NULL == voice_type || NULL == speech_rate) {
868 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
872 xmlDocPtr doc = NULL;
873 xmlNodePtr cur_new = NULL;
874 xmlNodePtr cur_old = NULL;
880 while (NULL == doc) {
881 if (0 == access(TTS_CONFIG, F_OK)) {
882 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Success to access to %s", TTS_CONFIG);
883 doc = xmlParseFile(TTS_CONFIG);
891 if (TTS_RETRY_COUNT == retry_count) {
892 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
897 cur_new = xmlDocGetRootElement(doc);
898 cur_old = xmlDocGetRootElement(g_config_doc);
899 if (cur_new == NULL || cur_old == NULL) {
900 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document(%p)", doc);
906 if (xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_BASE_TAG) ||
907 xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_BASE_TAG)) {
908 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] The wrong type, root node is NOT %s. doc(%p)", TTS_TAG_CONFIG_BASE_TAG, doc);
914 cur_new = cur_new->xmlChildrenNode;
915 cur_old = cur_old->xmlChildrenNode;
916 if (cur_new == NULL || cur_old == NULL) {
917 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document(%p)", doc);
923 while (cur_new != NULL && cur_old != NULL) {
924 if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_ID)) {
925 if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_ID)) {
926 key_old = xmlNodeGetContent(cur_old);
927 if (NULL != key_old) {
928 key_new = xmlNodeGetContent(cur_new);
929 if (NULL != key_new) {
930 if (0 != xmlStrcmp(key_old, key_new)) {
931 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old engine id(%s), New engine(%s)",
932 (char*)key_old, (char*)key_new);
933 if (NULL != *engine) {
937 *engine = strdup((char*)key_new);
946 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
948 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_SETTING)) {
949 if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_SETTING)) {
950 key_old = xmlNodeGetContent(cur_old);
951 if (NULL != key_old) {
952 key_new = xmlNodeGetContent(cur_new);
953 if (NULL != key_new) {
954 if (0 != xmlStrcmp(key_old, key_new)) {
955 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old engine setting(%s), New engine setting(%s)",
956 (char*)key_old, (char*)key_new);
957 if (NULL != *setting) {
961 *setting = strdup((char*)key_new);
970 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
972 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_AUTO_VOICE)) {
973 if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_AUTO_VOICE)) {
974 key_old = xmlNodeGetContent(cur_old);
975 if (NULL != key_old) {
976 key_new = xmlNodeGetContent(cur_new);
977 if (NULL != key_new) {
978 if (0 != xmlStrcmp(key_old, key_new)) {
979 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old auto voice (%s), New auto voice(%s)",
980 (char*)key_old, (char*)key_new);
981 if (0 == xmlStrcmp((const xmlChar*)"on", key_new)) {
994 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
996 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_LANGUAGE)) {
997 if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_LANGUAGE)) {
998 key_old = xmlNodeGetContent(cur_old);
999 if (NULL != key_old) {
1000 key_new = xmlNodeGetContent(cur_new);
1001 if (NULL != key_new) {
1002 if (0 != xmlStrcmp(key_old, key_new)) {
1003 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old language(%s), New language(%s)",
1004 (char*)key_old, (char*)key_new);
1005 if (NULL != *language) {
1009 *language = strdup((char*)key_new);
1018 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1020 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_VOICE_TYPE)) {
1021 if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_VOICE_TYPE)) {
1022 key_old = xmlNodeGetContent(cur_old);
1023 if (NULL != key_old) {
1024 key_new = xmlNodeGetContent(cur_new);
1025 if (NULL != key_new) {
1026 if (0 != xmlStrcmp(key_old, key_new)) {
1027 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old voice type(%s), New voice type(%s)",
1028 (char*)key_old, (char*)key_new);
1029 if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
1030 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
1031 } else if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
1032 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
1033 } else if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
1034 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
1036 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] New voice type is not valid");
1046 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1048 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_SPEECH_RATE)) {
1049 if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_SPEECH_RATE)) {
1050 key_old = xmlNodeGetContent(cur_old);
1051 if (NULL != key_old) {
1052 key_new = xmlNodeGetContent(cur_new);
1053 if (NULL != key_new) {
1054 if (0 != xmlStrcmp(key_old, key_new)) {
1055 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old speech rate(%s), New speech rate(%s)",
1056 (char*)key_old, (char*)key_new);
1057 *speech_rate = atoi((char*)key_new);
1066 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1068 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_PITCH)) {
1069 if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_PITCH)) {
1070 key_old = xmlNodeGetContent(cur_old);
1071 if (NULL != key_old) {
1072 key_new = xmlNodeGetContent(cur_new);
1073 if (NULL != key_new) {
1074 if (0 != xmlStrcmp(key_old, key_new)) {
1075 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old pitch(%s), New pitch(%s)",
1076 (char*)key_old, (char*)key_new);
1077 *pitch = atoi((char*)key_new);
1086 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1088 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO)) {
1089 if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO)) {
1090 key_old = xmlNodeGetContent(cur_old);
1091 if (NULL != key_old) {
1092 key_new = xmlNodeGetContent(cur_new);
1093 if (NULL != key_new) {
1094 if (0 != xmlStrcmp(key_old, key_new)) {
1095 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old bg volume ratio(%s), New bg volume ratio(%s)",
1096 (char*)key_old, (char*)key_new);
1097 *bg_volume_ratio = atof((char*)key_new);
1106 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1112 cur_new = cur_new->next;
1113 cur_old = cur_old->next;
1116 if (NULL != g_config_doc) {
1117 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Free g_config_doc(%p)", g_config_doc);
1118 xmlFreeDoc(g_config_doc);
1119 g_config_doc = NULL;
1126 int tts_parser_reset()
1128 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Reset g_config_doc as %s", TTS_DEFAULT_CONFIG);
1130 if (NULL != g_config_doc) {
1131 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Free g_config_doc(%p)", g_config_doc);
1132 xmlFreeDoc(g_config_doc);
1133 g_config_doc = NULL;
1136 g_config_doc = xmlParseFile(TTS_DEFAULT_CONFIG);
1137 if (NULL == g_config_doc) {
1138 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse %s", TTS_DEFAULT_CONFIG);
1142 __save_configuration(g_config_doc);