Add tts engine api for synthesis parameter instead of changing ttsd_engine_start_synt...
[platform/core/uifw/tts.git] / common / tts_config_parser.c
1 /*
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.
12 */
13
14 #include <dlog.h>
15 #include <stdio.h>
16 #include <sys/stat.h>
17 #include <unistd.h>
18 #include <vconf.h>
19
20 #include "tts_config_parser.h"
21 #include "tts_defs.h"
22
23
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"
33
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"
46
47 #define TTS_MAX_TEXT_SIZE       2000
48 #define VOLUME_BASE_VALUE       100.0
49
50 static xmlDocPtr g_config_doc = NULL;
51 char g_engine_id[128] = {0,};
52 char g_setting[128] = {0,};
53 char g_language[128] = {0,};
54
55 static tts_config_s* g_config_info = NULL;
56
57 static pthread_mutex_t g_config_info_mutex = PTHREAD_MUTEX_INITIALIZER;
58
59 int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info)
60 {
61         if (NULL == path || NULL == engine_info) {
62                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
63                 return -1;
64         }
65
66         // Avoid to parse non-xml file
67         char* file_ext = strrchr(path, '.');
68         if (NULL == ++file_ext || (file_ext && 0 != strncmp("xml", file_ext, strlen(file_ext)))) {
69                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] File extention is not XML type, file_ext(%s)", (file_ext) ? file_ext : "NULL");
70                 return -1;
71         }
72
73         bool isTextsize = false;
74         xmlDocPtr doc = NULL;
75         xmlNodePtr cur = NULL;
76
77         if (0 == access(path, F_OK)) {
78                 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Success to access to %s", path);
79                 doc = xmlParseFile(path);
80                 if (doc == NULL) {
81                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse xml file");
82                         return -1;
83                 }
84         } else {
85                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to access to %s", path);
86                 return -1;
87         }
88
89         cur = xmlDocGetRootElement(doc);
90         if (cur == NULL) {
91                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document. doc path(%s, %p)", path, doc);
92                 xmlFreeDoc(doc);
93                 doc = NULL;
94                 return -1;
95         }
96
97         if (xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_BASE_TAG)) {
98                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] The wrong type, root node is NOT 'tts-engine'. doc path(%s, %p)", path, doc);
99                 xmlFreeDoc(doc);
100                 doc = NULL;
101                 return -1;
102         }
103
104         cur = cur->xmlChildrenNode;
105         if (cur == NULL) {
106                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document. doc path(%s, %p)", path, doc);
107                 xmlFreeDoc(doc);
108                 doc = NULL;
109                 return -1;
110         }
111
112         /* alloc engine info */
113         tts_engine_info_s* temp;
114         temp = (tts_engine_info_s*)calloc(1, sizeof(tts_engine_info_s));
115         if (NULL == temp) {
116                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Out of memory. doc path(%s, %p)", path, doc);
117                 xmlFreeDoc(doc);
118                 doc = NULL;
119                 return -1;
120         }
121
122         temp->name = NULL;
123         temp->uuid = NULL;
124         temp->voices = NULL;
125         temp->setting = NULL;
126         temp->pitch_support = false;
127         temp->text_size = 0;
128
129         while (cur != NULL) {
130                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_NAME)) {
131                         xmlChar *key = xmlNodeGetContent(cur);
132                         if (NULL != key) {
133                                 if (NULL != temp->name) {
134                                         free(temp->name);
135                                         temp->name = NULL;
136                                 }
137                                 temp->name = strdup((char*)key);
138                                 xmlFree(key);
139                                 key = NULL;
140                         } else {
141                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_NAME);
142                         }
143                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_ID)) {
144                         xmlChar *key = xmlNodeGetContent(cur);
145                         if (NULL != key) {
146                                 if (NULL != temp->uuid) {
147                                         free(temp->uuid);
148                                         temp->uuid = NULL;
149                                 }
150                                 temp->uuid = strdup((char*)key);
151                                 xmlFree(key);
152                                 key = NULL;
153                         } else {
154                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_ID);
155                         }
156                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_SETTING)) {
157                         xmlChar *key = xmlNodeGetContent(cur);
158                         if (NULL != key) {
159                                 if (NULL != temp->setting) {
160                                         free(temp->setting);
161                                         temp->setting = NULL;
162                                 }
163                                 temp->setting = strdup((char*)key);
164                                 xmlFree(key);
165                                 key = NULL;
166                         } else {
167                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_SETTING);
168                         }
169                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE_SET)) {
170                         xmlNodePtr voice_node = NULL;
171                         voice_node = cur->xmlChildrenNode;
172
173                         while (NULL != voice_node) {
174                                 if (0 == xmlStrcmp(voice_node->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE)) {
175                                         tts_config_voice_s* temp_voice = (tts_config_voice_s*)calloc(1, sizeof(tts_config_voice_s));
176                                         if (NULL == temp_voice) {
177                                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Out of memory");
178                                                 break;
179                                         }
180
181                                         xmlChar *attr = xmlGetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE);
182                                         if (NULL != attr) {
183                                                 if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
184                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
185                                                 } else if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
186                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
187                                                 } else if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
188                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
189                                                 } else {
190                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_USER_DEFINED;
191                                                 }
192                                                 xmlFree(attr);
193                                                 attr = NULL;
194                                         } else {
195                                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE_TYPE);
196                                                 free(temp_voice);
197                                                 temp_voice = NULL;
198                                                 continue;
199                                         }
200
201                                         xmlChar *key = xmlNodeGetContent(voice_node);
202                                         if (NULL != key) {
203                                                 if (NULL != temp_voice->language) {
204                                                         free(temp_voice->language);
205                                                         temp_voice->language = NULL;
206                                                 }
207                                                 temp_voice->language = strdup((char*)key);
208                                                 xmlFree(key);
209                                                 key = NULL;
210                                                 temp->voices = g_slist_append(temp->voices, temp_voice);
211                                         } else {
212                                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE);
213                                                 if (NULL != temp_voice) {
214                                                         free(temp_voice);
215                                                         temp_voice = NULL;
216                                                 }
217                                         }
218                                 }
219                                 voice_node = voice_node->next;
220                         }
221                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_PITCH_SUPPORT)) {
222                         xmlChar *key = xmlNodeGetContent(cur);
223                         if (NULL != key) {
224                                 if (0 == xmlStrcmp(key, (const xmlChar *)"true")) {
225                                         temp->pitch_support = true;
226                                 }
227                                 xmlFree(key);
228                                 key = NULL;
229                         } else {
230                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_PITCH_SUPPORT);
231                         }
232                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_TEXT_SIZE)) {
233                         isTextsize = true;
234                         xmlChar *key = xmlNodeGetContent(cur);
235                         if (NULL != key) {
236                                 temp->text_size = atoi((char*)key);
237                                 xmlFree(key);
238                         } else {
239                                 SLOG(LOG_INFO, TAG_TTSCONFIG, "[INFO] text size is unlimited.");
240                                 temp->text_size = 0;
241                         }
242                 }
243                 cur = cur->next;
244         }
245
246         if (false == isTextsize) {
247                 temp->text_size = TTS_MAX_TEXT_SIZE;
248         }
249
250         if (NULL != doc) {
251                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] doc path(%s, %p)", path, doc);
252                 xmlFreeDoc(doc);
253                 doc = NULL;
254         }
255
256         if (NULL == temp->uuid) {
257                 /* Invalid engine */
258                 SECURE_SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Invalid engine : %s", path);
259                 tts_parser_free_engine_info(temp);
260                 return -1;
261         }
262
263         *engine_info = temp;
264
265         return 0;
266 }
267
268 int tts_parser_free_engine_info(tts_engine_info_s* engine_info)
269 {
270         if (NULL == engine_info) {
271                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
272                 return -1;
273         }
274
275         if (NULL != engine_info->name) {
276                 free(engine_info->name);
277                 engine_info->name = NULL;
278         }
279         if (NULL != engine_info->uuid) {
280                 free(engine_info->uuid);
281                 engine_info->uuid = NULL;
282         }
283         if (NULL != engine_info->setting) {
284                 free(engine_info->setting);
285                 engine_info->setting = NULL;
286         }
287
288         GSList *iter = NULL;
289         if (g_slist_length(engine_info->voices) > 0) {
290                 iter = g_slist_nth(engine_info->voices, 0);
291                 while (NULL != iter) {
292                         tts_config_voice_s *temp_voice = (tts_config_voice_s*)iter->data;
293                         if (NULL != temp_voice) {
294                                 if (NULL != temp_voice->language) {
295                                         free(temp_voice->language);
296                                         temp_voice->language = NULL;
297                                 }
298                                 free(temp_voice);
299                                 temp_voice = NULL;
300                         }
301
302                         engine_info->voices = g_slist_delete_link(engine_info->voices, iter);
303                         iter = g_slist_nth(engine_info->voices, 0);
304                 }
305         }
306
307         if (NULL != engine_info) {
308                 free(engine_info);
309                 engine_info = NULL;
310         }
311
312         return 0;
313 }
314
315 int tts_parser_print_engine_info(tts_engine_info_s* engine_info)
316 {
317         if (NULL == engine_info) {
318                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
319                 return -1;
320         }
321
322         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "== get engine info ==");
323         SLOG(LOG_DEBUG, TAG_TTSCONFIG, " name : %s", engine_info->name);
324         SLOG(LOG_DEBUG, TAG_TTSCONFIG, " id   : %s", engine_info->uuid);
325         if (NULL != engine_info->setting)
326                 SLOG(LOG_DEBUG, TAG_TTSCONFIG, " setting : %s", engine_info->setting);
327
328         SLOG(LOG_DEBUG, TAG_TTSCONFIG, " voices");
329         GSList *iter = NULL;
330         tts_config_voice_s *temp_voice;
331
332         if (g_slist_length(engine_info->voices) > 0) {
333                 /* Get a first item */
334                 iter = g_slist_nth(engine_info->voices, 0);
335
336                 int i = 1;
337                 while (NULL != iter) {
338                         /*Get handle data from list*/
339                         temp_voice = iter->data;
340
341                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "  [%dth] type(%d) lang(%s)",
342                                 i, temp_voice->type, temp_voice->language);
343
344                         /*Get next item*/
345                         iter = g_slist_next(iter);
346                         i++;
347                 }
348         } else {
349                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "  Voice is NONE");
350         }
351
352         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@");
353
354         return 0;
355 }
356
357 int tts_parser_load_config(void)
358 {
359         xmlDocPtr doc = NULL;
360         xmlNodePtr cur = NULL;
361         bool is_default_open = false;
362
363         /* For Thread safety */
364         xmlInitParser();
365
366         if (0 != access(TTS_CONFIG, F_OK)) {
367                 doc = xmlParseFile(TTS_DEFAULT_CONFIG);
368                 if (doc == NULL) {
369                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", TTS_DEFAULT_CONFIG);
370                         xmlCleanupParser();
371                         return -1;
372                 }
373                 is_default_open = true;
374         } else {
375                 int retry_count = 0;
376
377                 while (NULL == doc) {
378                         doc = xmlParseFile(TTS_CONFIG);
379                         if (NULL != doc) {
380                                 break;
381                         }
382                         retry_count++;
383                         usleep(10000);
384
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);
388                                 if (NULL == doc) {
389                                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", TTS_DEFAULT_CONFIG);
390                                         xmlCleanupParser();
391                                         return -1;
392                                 }
393                                 is_default_open = true;
394                                 break;
395                         }
396                 }
397         }
398
399         cur = xmlDocGetRootElement(doc);
400         if (cur == NULL) {
401                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document(%p)", doc);
402                 xmlFreeDoc(doc);
403                 doc = NULL;
404                 xmlCleanupParser();
405                 return -1;
406         }
407
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);
410                 xmlFreeDoc(doc);
411                 doc = NULL;
412                 xmlCleanupParser();
413                 return -1;
414         }
415
416         cur = cur->xmlChildrenNode;
417         if (cur == NULL) {
418                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document(%p)", doc);
419                 xmlFreeDoc(doc);
420                 doc = NULL;
421                 xmlCleanupParser();
422                 return -1;
423         }
424
425         /* alloc engine info */
426         tts_config_s* temp;
427         temp = (tts_config_s*)calloc(1, sizeof(tts_config_s));
428         if (NULL == temp) {
429                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Out of memory(%p)", doc);
430                 xmlFreeDoc(doc);
431                 doc = NULL;
432                 xmlCleanupParser();
433                 return -1;
434         }
435
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));
439
440         temp->engine_id = g_engine_id;
441         temp->setting = g_setting;
442         temp->language = g_language;
443
444         while (cur != NULL) {
445                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_ID)) {
446                         if (is_default_open) {
447                                 char* engine_id = vconf_get_str(TTS_ENGINE_DB_DEFAULT);
448                                 if (engine_id) {
449                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Set default engine id(%s)", engine_id);
450                                         strncpy(temp->engine_id, engine_id, sizeof(engine_id) - 1);
451                                         xmlNodeSetContent(cur, (const xmlChar *)engine_id);
452
453                                         free(engine_id);
454                                         engine_id = NULL;
455
456                                         cur = cur->next;
457                                         continue;
458                                 }
459                         }
460
461                         xmlChar *key = xmlNodeGetContent(cur);
462                         if (NULL != key) {
463                                 strncpy(temp->engine_id, (char*)key, sizeof(g_engine_id) - 1);
464                                 xmlFree(key);
465                                 key = NULL;
466                         } else {
467                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] engine id is NULL");
468                         }
469                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_SETTING)) {
470                         xmlChar *key = xmlNodeGetContent(cur);
471                         if (NULL != key) {
472                                 strncpy(temp->setting, (char*)key, sizeof(g_setting) - 1);
473                                 xmlFree(key);
474                                 key = NULL;
475                         } else {
476                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] setting path is NULL");
477                         }
478                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_AUTO_VOICE)) {
479                         xmlChar *key = xmlNodeGetContent(cur);
480                         if (NULL != key) {
481                                 if (0 == xmlStrcmp(key, (const xmlChar *)"on")) {
482                                         temp->auto_voice = true;
483                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)"off")) {
484                                         temp->auto_voice = false;
485                                 } else {
486                                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "Auto voice is wrong");
487                                         temp->auto_voice = true;
488                                 }
489
490                                 xmlFree(key);
491                                 key = NULL;
492                         } else {
493                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] voice type is NULL");
494                         }
495                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_VOICE_TYPE)) {
496                         xmlChar *key = xmlNodeGetContent(cur);
497                         if (NULL != key) {
498                                 if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
499                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
500                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
501                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
502                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
503                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
504                                 } else {
505                                         SLOG(LOG_WARN, TAG_TTSCONFIG, "Voice type is user defined");
506                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_USER_DEFINED;
507                                 }
508
509                                 xmlFree(key);
510                                 key = NULL;
511                         } else {
512                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] voice type is NULL");
513                         }
514                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
515                         xmlChar *key = xmlNodeGetContent(cur);
516                         if (NULL != key) {
517                                 strncpy(temp->language, (char*)key, sizeof(g_language) - 1);
518                                 xmlFree(key);
519                                 key = NULL;
520                         } else {
521                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] engine uuid is NULL");
522                         }
523
524                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_SPEECH_RATE)) {
525                         xmlChar *key = xmlNodeGetContent(cur);
526                         if (NULL != key) {
527                                 temp->speech_rate = atoi((char*)key);
528                                 xmlFree(key);
529                         } else {
530                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] speech rate is NULL");
531                         }
532                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_PITCH)) {
533                         xmlChar *key = xmlNodeGetContent(cur);
534                         if (NULL != key) {
535                                 temp->pitch = atoi((char*)key);
536                                 xmlFree(key);
537                                 key = NULL;
538                         } else {
539                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Pitch is NULL");
540                         }
541                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO)) {
542                         xmlChar *key = xmlNodeGetContent(cur);
543                         if (NULL != key) {
544                                 temp->bg_volume_ratio = atoi((char*)key) / VOLUME_BASE_VALUE;
545                                 xmlFree(key);
546                                 key = NULL;
547                         } else {
548                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Background volume ratio is NULL");
549                         }
550                 } else {
551
552                 }
553
554                 cur = cur->next;
555         }
556
557         pthread_mutex_lock(&g_config_info_mutex);
558         g_config_info = temp;
559         pthread_mutex_unlock(&g_config_info_mutex);
560         g_config_doc = doc;
561
562         if (true == is_default_open) {
563                 int retry_count = 0;
564                 int ret = -1;
565                 do {
566                         ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
567                         if (0 < ret)
568                                 break;
569                         retry_count++;
570                         usleep(10000);
571
572                         if (TTS_RETRY_COUNT == retry_count) {
573                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Save result : %d, err(%d)", ret, errno);
574                                 return -1;
575                         }
576                 } while (0 != ret);
577
578                 /* Set mode */
579                 if (0 > chmod(TTS_CONFIG, 0664)) {
580                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to change file mode : %d", ret);
581                 }
582
583                 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Default config is changed : pid(%d)", getpid());
584         }
585
586         return 0;
587 }
588
589 int tts_parser_unload_config(void)
590 {
591         if (NULL != g_config_doc) {
592                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Free g_config_doc(%p)", g_config_doc);
593                 xmlFreeDoc(g_config_doc);
594                 g_config_doc = NULL;
595         }
596         pthread_mutex_lock(&g_config_info_mutex);
597         if (NULL != g_config_info) {
598                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Free config_info(%p)", g_config_info);
599                 free(g_config_info);
600                 g_config_info = NULL;
601         }
602         pthread_mutex_unlock(&g_config_info_mutex);
603
604         xmlCleanupParser();
605         return 0;
606 }
607
608 int tts_parser_set_config_info(tts_config_s* config_info)
609 {
610         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Set config info");
611         if (NULL == config_info) {
612                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] config_info is NULL");
613                 return -1;
614         }
615         pthread_mutex_lock(&g_config_info_mutex);
616         if (NULL == g_config_info) {
617                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] g_config_info is NULL");
618                 pthread_mutex_unlock(&g_config_info_mutex);
619                 return -1;
620         }
621         memcpy(g_config_info, config_info, sizeof(tts_config_s));
622         pthread_mutex_unlock(&g_config_info_mutex);
623         return 0;
624 }
625
626 int tts_parser_get_config_info(tts_config_s* config_info)
627 {
628         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Get config info");
629         if (NULL == config_info) {
630                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] config_info is NULL");
631                 return -1;
632         }
633         pthread_mutex_lock(&g_config_info_mutex);
634         if (NULL == g_config_info) {
635                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] g_config_info is NULL");
636                 pthread_mutex_unlock(&g_config_info_mutex);
637                 return -1;
638         }
639         memcpy(config_info, g_config_info, sizeof(tts_config_s));
640         pthread_mutex_unlock(&g_config_info_mutex);
641         return 0;
642 }
643
644 int tts_parser_copy_xml(const char* original, const char* destination)
645 {
646         if (NULL == original || NULL == destination) {
647                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
648                 return -1;
649         }
650
651         xmlDocPtr doc = NULL;
652         if (0 == access(original, F_OK)) {
653                 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Success to access to %s", original);
654                 doc = xmlParseFile(original);
655                 if (doc == NULL) {
656                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", original);
657                         return -1;
658                 }
659         } else {
660                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to access to %s", original);
661                 return -1;
662         }
663
664         int ret = xmlSaveFile(destination, doc);
665         if (0 > ret) {
666                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Save result : %d", ret);
667         } else {
668                 static FILE* pFile;
669                 pFile = fopen(destination, "r");
670                 int fd = -1;
671                 if (NULL == pFile) {
672                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to open file %s", destination);
673                 } else {
674                         fd = fileno(pFile);
675                         fsync(fd);
676                         fclose(pFile);
677                         SLOG(LOG_INFO, TAG_TTSCONFIG, "[DEBUG] Success to fsync %s", destination);
678                 }
679                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Success to save %s", destination);
680         }
681
682         /* Set mode */
683         if (0 > chmod(destination, 0664)) {
684                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to change file mode : %d", ret);
685         }
686
687         if (NULL != doc) {
688                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] doc(%p)", doc);
689                 xmlFreeDoc(doc);
690                 doc = NULL;
691         }
692
693         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[SUCCESS] Copying xml");
694
695         return 0;
696 }
697
698 static int __set_value_into_configuration(const char* key, const char* value)
699 {
700         if(NULL == key || NULL == value) {
701                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Parameter is NULL");
702         }
703
704         xmlNodePtr cur = NULL;
705         cur = xmlDocGetRootElement(g_config_doc);
706         if (cur == NULL) {
707                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document");
708                 return -1;
709         }
710
711         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
712                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
713                 return -1;
714         }
715
716         cur = cur->xmlChildrenNode;
717         if (cur == NULL) {
718                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document");
719                 return -1;
720         }
721
722         while (cur != NULL) {
723                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)key)) {
724                         xmlNodeSetContent(cur, (const xmlChar *)value);
725
726                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Set key(%s) : value(%s)", key, value);
727                         break;
728                 }
729
730                 cur = cur->next;
731         }
732
733         return 0;
734 }
735
736 static void __save_configuration(xmlDocPtr config_doc)
737 {
738         int ret = xmlSaveFile(TTS_CONFIG, config_doc);
739         if (0 > ret) {
740                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Save result : file(%s), ret(%d)", TTS_CONFIG, ret);
741         } else {
742                 static FILE* pFile;
743                 pFile = fopen(TTS_CONFIG, "r");
744                 int fd = -1;
745                 if (NULL == pFile) {
746                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to open file %s", TTS_CONFIG);
747                 } else {
748                         fd = fileno(pFile);
749                         fsync(fd);
750                         fclose(pFile);
751                         SLOG(LOG_INFO, TAG_TTSCONFIG, "[DEBUG] Success to fsync %s", TTS_CONFIG);
752                 }
753                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Success to save %s", TTS_CONFIG);
754         }
755 }
756
757 static char* __convert_voice_type_into_char(tts_config_voice_type_e voice_type)
758 {
759         switch (voice_type) {
760         case TTS_CONFIG_VOICE_TYPE_MALE:
761                 return TTS_TAG_VOICE_TYPE_MALE;
762         case TTS_CONFIG_VOICE_TYPE_FEMALE:
763                 return TTS_TAG_VOICE_TYPE_FEMALE;
764         case TTS_CONFIG_VOICE_TYPE_CHILD:
765                 return TTS_TAG_VOICE_TYPE_CHILD;
766         default:
767                 return TTS_TAG_VOICE_TYPE_FEMALE;
768         }
769 }
770
771 int tts_parser_set_engine(const char* engine_id, const char* setting, const char* language, int type)
772 {
773         if (NULL == engine_id) {
774                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
775                 return -1;
776         }
777
778         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_ENGINE_ID, engine_id)) {
779                 return -1;
780         }
781
782         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_LANGUAGE, language)) {
783                 return -1;
784         }
785
786         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_ENGINE_SETTING, setting)) {
787                 return -1;
788         }
789
790         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_VOICE_TYPE, __convert_voice_type_into_char(type))) {
791                 return -1;
792         }
793
794         __save_configuration(g_config_doc);
795
796         return 0;
797 }
798
799 int tts_parser_set_voice(const char* language, int type)
800 {
801         if (NULL == language) {
802                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
803                 return -1;
804         }
805
806         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_LANGUAGE, language)) {
807                 return -1;
808         }
809
810         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_VOICE_TYPE, __convert_voice_type_into_char(type))) {
811                 return -1;
812         }
813
814         __save_configuration(g_config_doc);
815
816         return 0;
817 }
818
819 int tts_parser_set_auto_voice(bool value)
820 {
821         char* temp = value ? "on" : "off";
822         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_AUTO_VOICE, temp)) {
823                 return -1;
824         }
825
826         __save_configuration(g_config_doc);
827
828         return 0;
829 }
830
831 int tts_parser_set_speech_rate(int value)
832 {
833         char temp[10];
834         memset(temp, '\0', 10);
835         snprintf(temp, 10, "%d", value);
836
837         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_SPEECH_RATE, temp)) {
838                 return -1;
839         }
840
841         __save_configuration(g_config_doc);
842
843         return 0;
844 }
845
846 int tts_parser_set_pitch(int value)
847 {
848         char temp[10];
849         memset(temp, '\0', 10);
850         snprintf(temp, 10, "%d", value);
851
852         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_PITCH, temp)) {
853                 return -1;
854         }
855
856         __save_configuration(g_config_doc);
857
858         return 0;
859 }
860
861 int tts_parser_set_bg_volume_ratio(double value)
862 {
863         char temp[10];
864         memset(temp, '\0', 10);
865         snprintf(temp, 10, "%d", (int)(value * VOLUME_BASE_VALUE));
866
867         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO, temp)) {
868                 return -1;
869         }
870
871         __save_configuration(g_config_doc);
872
873         return 0;
874 }
875
876 int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voice, char** language, int* voice_type,
877                                    int* speech_rate, int* pitch, double* bg_volume_ratio)
878 {
879         if (NULL == engine || NULL == setting || NULL == language || NULL == voice_type || NULL == speech_rate) {
880                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
881                 return -1;
882         }
883
884         xmlDocPtr doc = NULL;
885         xmlNodePtr cur_new = NULL;
886         xmlNodePtr cur_old = NULL;
887
888         int retry_count = 0;
889         while (NULL == doc) {
890                 if (0 == access(TTS_CONFIG, F_OK)) {
891                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Success to access to %s", TTS_CONFIG);
892                         doc = xmlParseFile(TTS_CONFIG);
893                         if (NULL != doc) {
894                                 break;
895                         }
896                 }
897                 retry_count++;
898                 usleep(10000);
899
900                 if (TTS_RETRY_COUNT == retry_count) {
901                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
902                         return -1;
903                 }
904         }
905
906         cur_new = xmlDocGetRootElement(doc);
907         cur_old = xmlDocGetRootElement(g_config_doc);
908         if (cur_new == NULL || cur_old == NULL) {
909                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document(%p)", doc);
910                 xmlFreeDoc(doc);
911                 doc = NULL;
912                 return -1;
913         }
914
915         if (xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_BASE_TAG) ||
916         xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_BASE_TAG)) {
917                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] The wrong type, root node is NOT %s. doc(%p)", TTS_TAG_CONFIG_BASE_TAG, doc);
918                 xmlFreeDoc(doc);
919                 doc = NULL;
920                 return -1;
921         }
922
923         cur_new = cur_new->xmlChildrenNode;
924         cur_old = cur_old->xmlChildrenNode;
925         if (cur_new == NULL || cur_old == NULL) {
926                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document(%p)", doc);
927                 xmlFreeDoc(doc);
928                 doc = NULL;
929                 return -1;
930         }
931
932         while (cur_new != NULL && cur_old != NULL) {
933                 if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_ID)) {
934                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_ID)) {
935                                 xmlChar *key_old = xmlNodeGetContent(cur_old);
936                                 if (NULL != key_old) {
937                                         xmlChar *key_new = xmlNodeGetContent(cur_new);
938                                         if (NULL != key_new) {
939                                                 if (0 != xmlStrcmp(key_old, key_new)) {
940                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old engine id(%s), New engine(%s)",
941                                                                 (char*)key_old, (char*)key_new);
942                                                         if (NULL != *engine) {
943                                                                 free(*engine);
944                                                                 *engine = NULL;
945                                                         }
946                                                         *engine = strdup((char*)key_new);
947                                                 }
948                                                 xmlFree(key_new);
949                                                 key_new = NULL;
950                                         }
951                                         xmlFree(key_old);
952                                         key_old = NULL;
953                                 }
954                         } else {
955                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
956                         }
957                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_SETTING)) {
958                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_SETTING)) {
959                                 xmlChar *key_old = xmlNodeGetContent(cur_old);
960                                 if (NULL != key_old) {
961                                         xmlChar *key_new = xmlNodeGetContent(cur_new);
962                                         if (NULL != key_new) {
963                                                 if (0 != xmlStrcmp(key_old, key_new)) {
964                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old engine setting(%s), New engine setting(%s)",
965                                                                 (char*)key_old, (char*)key_new);
966                                                         if (NULL != *setting) {
967                                                                 free(*setting);
968                                                                 *setting = NULL;
969                                                         }
970                                                         *setting = strdup((char*)key_new);
971                                                 }
972                                                 xmlFree(key_new);
973                                                 key_new = NULL;
974                                         }
975                                         xmlFree(key_old);
976                                         key_old = NULL;
977                                 }
978                         } else {
979                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
980                         }
981                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_AUTO_VOICE)) {
982                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_AUTO_VOICE)) {
983                                 xmlChar *key_old = xmlNodeGetContent(cur_old);
984                                 if (NULL != key_old) {
985                                         xmlChar *key_new = xmlNodeGetContent(cur_new);
986                                         if (NULL != key_new) {
987                                                 if (0 != xmlStrcmp(key_old, key_new)) {
988                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old auto voice (%s), New auto voice(%s)",
989                                                                 (char*)key_old, (char*)key_new);
990                                                         if (0 == xmlStrcmp((const xmlChar*)"on", key_new)) {
991                                                                 *auto_voice = true;
992                                                         } else {
993                                                                 *auto_voice = false;
994                                                         }
995                                                 }
996                                                 xmlFree(key_new);
997                                                 key_new = NULL;
998                                         }
999                                         xmlFree(key_old);
1000                                         key_old = NULL;
1001                                 }
1002                         } else {
1003                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1004                         }
1005                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_LANGUAGE)) {
1006                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_LANGUAGE)) {
1007                                 xmlChar *key_old = xmlNodeGetContent(cur_old);
1008                                 if (NULL != key_old) {
1009                                         xmlChar *key_new = xmlNodeGetContent(cur_new);
1010                                         if (NULL != key_new) {
1011                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1012                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old language(%s), New language(%s)",
1013                                                                 (char*)key_old, (char*)key_new);
1014                                                         if (NULL != *language) {
1015                                                                 free(*language);
1016                                                                 *language = NULL;
1017                                                         }
1018                                                         *language = strdup((char*)key_new);
1019                                                 }
1020                                                 xmlFree(key_new);
1021                                                 key_new = NULL;
1022                                         }
1023                                         xmlFree(key_old);
1024                                         key_old = NULL;
1025                                 }
1026                         } else {
1027                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1028                         }
1029                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_VOICE_TYPE)) {
1030                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_VOICE_TYPE)) {
1031                                 xmlChar *key_old = xmlNodeGetContent(cur_old);
1032                                 if (NULL != key_old) {
1033                                         xmlChar *key_new = xmlNodeGetContent(cur_new);
1034                                         if (NULL != key_new) {
1035                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1036                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old voice type(%s), New voice type(%s)",
1037                                                                 (char*)key_old, (char*)key_new);
1038                                                         if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
1039                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
1040                                                         } else if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
1041                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
1042                                                         } else if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
1043                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
1044                                                         } else {
1045                                                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] New voice type is not valid");
1046                                                         }
1047                                                 }
1048                                                 xmlFree(key_new);
1049                                                 key_new = NULL;
1050                                         }
1051                                         xmlFree(key_old);
1052                                         key_old = NULL;
1053                                 }
1054                         } else {
1055                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1056                         }
1057                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_SPEECH_RATE)) {
1058                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_SPEECH_RATE)) {
1059                                 xmlChar *key_old = xmlNodeGetContent(cur_old);
1060                                 if (NULL != key_old) {
1061                                         xmlChar *key_new = xmlNodeGetContent(cur_new);
1062                                         if (NULL != key_new) {
1063                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1064                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old speech rate(%s), New speech rate(%s)",
1065                                                                 (char*)key_old, (char*)key_new);
1066                                                         *speech_rate = atoi((char*)key_new);
1067                                                 }
1068                                                 xmlFree(key_new);
1069                                                 key_new = NULL;
1070                                         }
1071                                         xmlFree(key_old);
1072                                         key_old = NULL;
1073                                 }
1074                         } else {
1075                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1076                         }
1077                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_PITCH)) {
1078                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_PITCH)) {
1079                                 xmlChar *key_old = xmlNodeGetContent(cur_old);
1080                                 if (NULL != key_old) {
1081                                         xmlChar *key_new = xmlNodeGetContent(cur_new);
1082                                         if (NULL != key_new) {
1083                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1084                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old pitch(%s), New pitch(%s)",
1085                                                                 (char*)key_old, (char*)key_new);
1086                                                         *pitch = atoi((char*)key_new);
1087                                                 }
1088                                                 xmlFree(key_new);
1089                                                 key_new = NULL;
1090                                         }
1091                                         xmlFree(key_old);
1092                                         key_old = NULL;
1093                                 }
1094                         } else {
1095                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1096                         }
1097                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO)) {
1098                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO)) {
1099                                 xmlChar *key_old = xmlNodeGetContent(cur_old);
1100                                 if (NULL != key_old) {
1101                                         xmlChar *key_new = xmlNodeGetContent(cur_new);
1102                                         if (NULL != key_new) {
1103                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1104                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old bg volume ratio(%s), New bg volume ratio(%s)",
1105                                                                 (char*)key_old, (char*)key_new);
1106                                                         *bg_volume_ratio = atoi((char*)key_new) / VOLUME_BASE_VALUE;
1107                                                 }
1108                                                 xmlFree(key_new);
1109                                                 key_new = NULL;
1110                                         }
1111                                         xmlFree(key_old);
1112                                         key_old = NULL;
1113                                 }
1114                         } else {
1115                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1116                         }
1117                 } else {
1118
1119                 }
1120
1121                 cur_new = cur_new->next;
1122                 cur_old = cur_old->next;
1123         }
1124
1125         if (NULL != g_config_doc) {
1126                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Free g_config_doc(%p)", g_config_doc);
1127                 xmlFreeDoc(g_config_doc);
1128                 g_config_doc = NULL;
1129         }
1130         g_config_doc = doc;
1131
1132         return 0;
1133 }
1134
1135 int tts_parser_reset()
1136 {
1137         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Reset g_config_doc as %s", TTS_DEFAULT_CONFIG);
1138
1139         if (NULL != g_config_doc) {
1140                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Free g_config_doc(%p)", g_config_doc);
1141                 xmlFreeDoc(g_config_doc);
1142                 g_config_doc = NULL;
1143         }
1144
1145         g_config_doc = xmlParseFile(TTS_DEFAULT_CONFIG);
1146         if (NULL == g_config_doc) {
1147                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse %s", TTS_DEFAULT_CONFIG);
1148                 return -1;
1149         }
1150
1151         char* engine_id = vconf_get_str(TTS_ENGINE_DB_DEFAULT);
1152         if (engine_id) {
1153                 int ret = __set_value_into_configuration(TTS_TAG_CONFIG_ENGINE_ID, engine_id);
1154                 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Set engine ID into xml. engine_id(%s), ret(%d/%s)", engine_id, ret, get_error_message(ret));
1155                 free(engine_id);
1156         }
1157         __save_configuration(g_config_doc);
1158
1159         return 0;
1160 }