Add logic to check that list is empty
[platform/core/uifw/tts.git] / server / ttsd_data.cpp
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 <list>
15 #include <pthread.h>
16 #include <vector>
17
18 #include "ttsd_main.h"
19 #include "ttsd_data.h"
20
21 using namespace std;
22
23 typedef struct
24 {
25         char*   lang;
26         int     vctype;
27 }used_voice_s;
28
29 typedef struct
30 {
31         int             pid;
32         int             uid;
33         int             utt_id_stopped;
34         app_state_e     state;
35
36         std::list<speak_data_s*> m_speak_data;
37         std::list<sound_data_s*> m_wav_data;
38
39         std::list<used_voice_s> m_used_voice;
40 }app_data_s;
41
42 static vector<app_data_s> g_app_list;
43
44 static pthread_mutex_t g_speak_data_mutex = PTHREAD_MUTEX_INITIALIZER;
45 static pthread_mutex_t g_sound_data_mutex = PTHREAD_MUTEX_INITIALIZER;
46
47 /*
48 * functions for debug
49 */
50 int __data_show_list()
51 {
52         int vsize = g_app_list.size();
53
54         SLOG(LOG_DEBUG, tts_tag(), "----- client list -----");
55
56         for (int i=0; i < vsize; i++) {
57                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[%dth] pid(%d), uid(%d), state(%d)", i, g_app_list[i].pid, g_app_list[i].uid, g_app_list[i].state);
58         }
59
60         if (0 == vsize) {
61                 SLOG(LOG_DEBUG, tts_tag(), "No Client");
62         }
63
64         SLOG(LOG_DEBUG, tts_tag(), "-----------------------");
65
66         return TTSD_ERROR_NONE;
67 }
68
69 int __data_show_sound_list(int index)
70 {
71         SLOG(LOG_DEBUG, tts_tag(), "----- Sound list -----");
72
73         unsigned int i = 0;
74         std::list<sound_data_s*>::iterator iter;
75         for (iter = g_app_list[index].m_wav_data.begin(); iter != g_app_list[index].m_wav_data.end(); iter++) {
76                 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%ld), uttid(%d), type(%d)", 
77                         i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
78                 i++;
79         }
80
81         if (i == 0) {
82                 SLOG(LOG_DEBUG, tts_tag(), "No Sound Data");
83         }
84
85         SLOG(LOG_DEBUG, tts_tag(), "----------------------");
86         return TTSD_ERROR_NONE;
87 }
88
89 int __data_show_text_list(int index)
90 {
91         SLOG(LOG_DEBUG, tts_tag(), "----- Text list -----");
92
93         unsigned int i = 0;
94         std::list<speak_data_s*>::iterator iter;
95         for (iter = g_app_list[index].m_speak_data.begin(); iter != g_app_list[index].m_speak_data.end(); iter++) {
96                 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)", 
97                         i + 1, *iter, (*iter)->lang, (*iter)->vctype, (*iter)->speed, (*iter)->utt_id, (*iter)->text);
98                 i++;
99         }
100
101         if (0 == i) {
102                 SLOG(LOG_DEBUG, tts_tag(), "No Text Data");
103         }
104
105         SLOG(LOG_DEBUG, tts_tag(), "---------------------");
106         return TTSD_ERROR_NONE;
107 }
108
109 int __data_show_used_voice_list(int index)
110 {
111         SLOG(LOG_DEBUG, tts_tag(), "----- Used voice list -----");
112
113         unsigned int i = 0;
114         std::list<used_voice_s>::iterator iter;
115         for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end(); iter++) {
116                 SLOG(LOG_DEBUG, tts_tag(), "[%dth] lang(%s), vctype(%d)", i + 1, iter->lang, iter->vctype);
117                 i++;
118         }
119
120         if (0 == i) {
121                 SLOG(LOG_DEBUG, tts_tag(), "No Voice Data");
122         }
123
124         SLOG(LOG_DEBUG, tts_tag(), "---------------------------");
125         return TTSD_ERROR_NONE;
126 }
127
128 /*
129 * ttsd data functions
130 */
131
132 int ttsd_data_new_client(int pid, int uid)
133 {
134         if( -1 != ttsd_data_is_client(uid) ) {
135                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
136                 return TTSD_ERROR_INVALID_PARAMETER;
137         }
138
139         app_data_s app;
140         app.pid = pid;
141         app.uid = uid;
142         app.utt_id_stopped = 0;
143         app.state = APP_STATE_READY;
144
145         g_app_list.insert(g_app_list.end(), app);
146
147 #ifdef DATA_DEBUG
148         __data_show_list();
149 #endif
150         return TTSD_ERROR_NONE;
151 }
152
153 int ttsd_data_delete_client(int uid)
154 {
155         int index = 0;
156
157         index = ttsd_data_is_client(uid);
158
159         if (index < 0) {
160                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
161                 return -1;
162         }
163
164         if (0 != ttsd_data_clear_data(uid)) {
165                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] Fail to clear data");
166                 return -1;
167         }
168
169         g_app_list.erase(g_app_list.begin()+index);
170
171 #ifdef DATA_DEBUG
172         __data_show_list();
173 #endif
174         return TTSD_ERROR_NONE;
175 }
176
177 int ttsd_data_is_client(int uid)
178 {
179         int vsize = g_app_list.size();
180
181         for (int i = 0; i < vsize; i++) {
182                 if(g_app_list[i].uid == uid) {
183                         return i;
184                 }
185         }
186
187         return -1;
188 }
189
190 int ttsd_data_get_client_count()
191 {
192         return g_app_list.size();
193 }
194
195 int ttsd_data_get_pid(int uid)
196 {
197         int index;
198
199         index = ttsd_data_is_client(uid);
200
201         if (index < 0)  {
202                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
203                 return TTSD_ERROR_INVALID_PARAMETER;
204         }
205
206         return g_app_list[index].pid;
207 }
208
209 int ttsd_data_get_speak_data_size(int uid)
210 {
211         int index = 0;
212         index = ttsd_data_is_client(uid);
213
214         if (index < 0) {
215                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
216                 return TTSD_ERROR_INVALID_PARAMETER;
217         }
218
219         /* mutex is locked */
220         pthread_mutex_lock(&g_speak_data_mutex);
221         int size = g_app_list[index].m_speak_data.size();
222
223         /* mutex is unlocked */
224         pthread_mutex_unlock(&g_speak_data_mutex);
225
226         return size;
227 }
228
229 int ttsd_data_set_used_voice(int uid, const char* lang, int type)
230 {
231         int index = 0;
232         index = ttsd_data_is_client(uid);
233
234         if (index < 0) {
235                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
236                 return TTSD_ERROR_INVALID_PARAMETER;
237         }
238
239         /* Find voice */
240         std::list<used_voice_s>::iterator iter;
241
242         for (iter = g_app_list[index].m_used_voice.begin();iter != g_app_list[index].m_used_voice.end();iter++) {
243                 if (0 == strcmp(lang, iter->lang) && type == iter->vctype) {
244                         SLOG(LOG_DEBUG, tts_tag(), "[DATA] The voice is already registered (%s)(%d)", lang, type);
245                         return 0;
246                 }
247         }
248
249         /* Add voice */
250         used_voice_s used_voice;
251         used_voice.lang = strdup(lang);
252         used_voice.vctype = type;
253
254         g_app_list[index].m_used_voice.insert(g_app_list[index].m_used_voice.end(), used_voice);
255
256 #ifdef DATA_DEBUG
257         __data_show_used_voice_list(index);
258 #endif
259
260         return -1;      /* Need to load voice*/
261 }
262
263 int ttsd_data_reset_used_voice(int uid, ttsd_used_voice_cb callback)
264 {
265         int index = 0;
266         index = ttsd_data_is_client(uid);
267
268         if (index < 0) {
269                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
270                 return TTSD_ERROR_INVALID_PARAMETER;
271         }
272
273         if (NULL == callback) {
274                 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] Used voice callback is NULL");
275         }
276
277         /* Find voice */
278         std::list<used_voice_s>::iterator iter;
279
280         for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end(); iter++) {
281                 if (NULL != callback) {
282                         callback(iter->lang, iter->vctype);
283                 }
284
285                 if (NULL != iter->lang) {
286                         free(iter->lang);
287                 }
288         }
289
290         g_app_list[index].m_used_voice.clear();
291
292 #ifdef DATA_DEBUG
293         __data_show_used_voice_list(index);
294 #endif
295
296         return TTSD_ERROR_NONE;
297 }
298
299 int ttsd_data_add_speak_data(int uid, speak_data_s* data)
300 {
301         int index = 0;
302         index = ttsd_data_is_client(uid);
303
304         if (index < 0) {
305                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
306                 return TTSD_ERROR_INVALID_PARAMETER;
307         }
308
309         /* mutex is locked */
310         pthread_mutex_lock(&g_speak_data_mutex);
311
312         g_app_list[index].m_speak_data.insert(g_app_list[index].m_speak_data.end(), data);
313
314         if (1 == data->utt_id)
315                 g_app_list[index].utt_id_stopped = 0;
316
317 #ifdef DATA_DEBUG
318         __data_show_text_list(index);
319 #endif
320         pthread_mutex_unlock(&g_speak_data_mutex);
321
322         return TTSD_ERROR_NONE;
323 }
324
325 int ttsd_data_get_speak_data(int uid, speak_data_s** data)
326 {
327         int index = 0;
328         index = ttsd_data_is_client(uid);
329
330         if (index < 0) {
331                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid(%d)", uid);
332                 return TTSD_ERROR_INVALID_PARAMETER;
333         }
334
335         /* mutex is locked */
336         pthread_mutex_lock(&g_speak_data_mutex);
337
338         if (0 == g_app_list[index].m_speak_data.size()) {
339 #ifdef DATA_DEBUG
340                 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] There is no speak data");
341 #endif
342                 pthread_mutex_unlock(&g_speak_data_mutex);
343                 return -1;
344         }
345
346         std::list<speak_data_s*>::iterator iter = g_app_list[index].m_speak_data.begin();
347         *data = *iter;
348         if (!g_app_list[index].m_speak_data.empty())
349                 g_app_list[index].m_speak_data.pop_front();
350
351 #ifdef DATA_DEBUG
352         __data_show_text_list(index);
353 #endif
354         pthread_mutex_unlock(&g_speak_data_mutex);
355
356         return TTSD_ERROR_NONE;
357 }
358
359 int ttsd_data_add_sound_data(int uid, sound_data_s* data)
360 {
361         int index = 0;
362         index = ttsd_data_is_client(uid);
363
364         if(index < 0) {
365                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
366                 return TTSD_ERROR_INVALID_PARAMETER;
367         }
368
369         if (NULL == data) {
370                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] sound data is NULL");
371                 return TTSD_ERROR_INVALID_PARAMETER;
372         }
373         /* mutex is locked */
374         pthread_mutex_lock(&g_sound_data_mutex);
375
376         g_app_list[index].m_wav_data.insert(g_app_list[index].m_wav_data.end(), data);
377
378 #ifdef DATA_DEBUG
379         __data_show_sound_list(index);
380 #endif
381
382         /* mutex is unlocked */
383         pthread_mutex_unlock(&g_sound_data_mutex);
384
385         return TTSD_ERROR_NONE;
386 }
387
388 int ttsd_data_get_sound_data(int uid, sound_data_s** data)
389 {
390         int index = 0;
391         index = ttsd_data_is_client(uid);
392
393         if (index < 0)  {
394                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
395                 return TTSD_ERROR_INVALID_PARAMETER;
396         }
397
398         /* mutex is locked */
399         pthread_mutex_lock(&g_sound_data_mutex);
400
401         if (0 == g_app_list[index].m_wav_data.size()) {
402 #ifdef DATA_DEBUG
403                 SLOG(LOG_DEBUG, tts_tag(), "[DATA] There is no wav data");
404 #endif
405                 /* mutex is unlocked */
406                 pthread_mutex_unlock(&g_sound_data_mutex);
407                 return -1;
408         }
409
410         std::list<sound_data_s*>::iterator iter = g_app_list[index].m_wav_data.begin();
411         *data = *iter;
412         if (!g_app_list[index].m_wav_data.empty())
413                 g_app_list[index].m_wav_data.pop_front();
414
415 #ifdef DATA_DEBUG
416         __data_show_sound_list(index);
417 #endif
418
419         /* mutex is unlocked */
420         pthread_mutex_unlock(&g_sound_data_mutex);
421
422         return TTSD_ERROR_NONE;
423 }
424
425 int ttsd_data_get_sound_data_size(int uid)
426 {
427         int index = 0;
428         int data_size = 0;
429         index = ttsd_data_is_client(uid);
430
431         if (index < 0)  {
432                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
433                 return TTSD_ERROR_INVALID_PARAMETER;
434         }
435
436         /* mutex is locked */
437         pthread_mutex_lock(&g_sound_data_mutex);
438         data_size = g_app_list[index].m_wav_data.size();
439
440         /* mutex is unlocked */
441         pthread_mutex_unlock(&g_sound_data_mutex);
442
443         return data_size;
444 }
445
446 int ttsd_data_clear_data(int uid)
447 {
448         int index = 0;
449
450         index = ttsd_data_is_client(uid);
451         if (index < 0) {
452                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
453                 return TTSD_ERROR_INVALID_PARAMETER;
454         }
455
456         int removed_last_uttid = -1;
457         speak_data_s* temp_speak = NULL;
458         sound_data_s* temp_sound = NULL;
459
460         /* free allocated data */
461         while(1) {
462                 if (0 != ttsd_data_get_speak_data(uid, &temp_speak)) {
463                         break;
464                 }
465
466                 if (NULL != temp_speak) {
467                         SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)", 
468                                         temp_speak->utt_id, temp_speak->text, temp_speak->lang, temp_speak->vctype, temp_speak->speed);
469
470                         if (NULL != temp_speak->text) {
471                                 free(temp_speak->text);
472                                 temp_speak->text = NULL;
473                         }
474                         if (NULL != temp_speak->lang) {
475                                 free(temp_speak->lang);
476                                 temp_speak->lang = NULL;
477                         }
478                         removed_last_uttid = temp_speak->utt_id;
479
480                         free(temp_speak);
481                         temp_speak = NULL;
482                 }
483         }
484
485         if (-1 != removed_last_uttid) {
486                 g_app_list[index].utt_id_stopped = removed_last_uttid;
487         }
488
489         while(1) {
490                 if (0 != ttsd_data_get_sound_data(uid, &temp_sound)) {
491                         break;
492                 }
493
494                 if (NULL != temp_sound) {
495                         SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] uid(%d), event(%d) data(%p) size(%d) rate(%d) utt(%d)", 
496                                 temp_sound, uid, temp_sound->event, temp_sound->data, temp_sound->data_size, temp_sound->rate, temp_sound->utt_id);
497
498                         if (NULL != temp_sound->data) {
499                                 free(temp_sound->data);
500                                 temp_sound->data = NULL;
501                         }
502
503                         free(temp_sound);
504                         temp_sound = NULL;
505                 }
506         }
507
508         pthread_mutex_lock(&g_speak_data_mutex);
509         g_app_list[index].m_speak_data.clear();
510         pthread_mutex_unlock(&g_speak_data_mutex);
511
512         pthread_mutex_lock(&g_sound_data_mutex);
513         g_app_list[index].m_wav_data.clear();
514         pthread_mutex_unlock(&g_sound_data_mutex);
515
516         return TTSD_ERROR_NONE;
517 }
518
519 int ttsd_data_get_client_state(int uid, app_state_e* state)
520 {
521         int index = 0;
522
523         index = ttsd_data_is_client(uid);
524         if (index < 0)  {
525                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
526                 return TTSD_ERROR_INVALID_PARAMETER;
527         }
528
529         *state = g_app_list[index].state;
530
531         return TTSD_ERROR_NONE;
532 }
533
534 int ttsd_data_set_client_state(int uid, app_state_e state)
535 {
536         int index = 0;
537
538         index = ttsd_data_is_client(uid);
539         if (index < 0)  {
540                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
541                 return TTSD_ERROR_INVALID_PARAMETER;
542         }
543
544         /* The client of playing state of all clients is only one. need to check state. */
545         if (APP_STATE_PLAYING == state) {
546                 int vsize = g_app_list.size();
547                 for (int i = 0; i < vsize; i++) {
548                         if(g_app_list[i].state == APP_STATE_PLAYING) {
549                                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] A playing client has already existed.");
550                                 return -1;
551                         }
552                 }
553         }
554
555         g_app_list[index].state = state;
556
557         return TTSD_ERROR_NONE;
558 }
559
560 int ttsd_data_get_current_playing()
561 {
562         int vsize = g_app_list.size();
563
564         for (int i = 0; i < vsize; i++) {
565                 if (APP_STATE_PLAYING == g_app_list[i].state) {
566                         SLOG(LOG_DEBUG, tts_tag(), "[DATA] uid(%d) is playing", g_app_list[i].uid);
567                         return g_app_list[i].uid;
568                 }
569         }
570
571         return -1;
572 }
573
574 int ttsd_data_foreach_clients(ttsd_data_get_client_cb callback, void* user_data)
575 {
576         if (NULL == callback) {
577                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] input data is NULL!!");
578                 return -1;
579         }
580
581 #ifdef DATA_DEBUG
582         __data_show_list();
583 #endif
584
585         /* Copy app info */
586         vector<app_data_s> temp_app_list;
587         int vsize = g_app_list.size();
588
589         int i = 0;
590         for (i = 0;i < vsize;i++) {
591                 app_data_s app;
592                 app.pid = g_app_list[i].pid;
593                 app.uid = g_app_list[i].uid;
594                 app.utt_id_stopped = 0;
595                 app.state = g_app_list[i].state;
596
597                 temp_app_list.insert(temp_app_list.end(), app);
598         }
599
600         for (i = 0;i < vsize;i++) {
601                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[%dth] pid(%d), uid(%d), state(%d)", i, temp_app_list[i].pid, temp_app_list[i].uid, temp_app_list[i].state);
602                 if (false == callback(temp_app_list[i].pid, temp_app_list[i].uid, temp_app_list[i].state, user_data)) {
603                         break;
604                 }
605         }
606
607         for (i = 0;i < vsize;i++) {
608                 temp_app_list.erase(temp_app_list.begin());
609         }
610
611         return 0;
612 }
613
614 bool ttsd_data_is_uttid_valid(int uid, int uttid)
615 {
616         int index = 0;
617
618         index = ttsd_data_is_client(uid);
619         if (index < 0)  {
620                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
621                 return TTSD_ERROR_INVALID_PARAMETER;
622         }
623
624         if (uttid < g_app_list[index].utt_id_stopped)
625                 return false;
626
627         return true;
628 }
629
630 int ttsd_data_is_current_playing()
631 {
632         int vsize = g_app_list.size();
633
634         for (int i = 0; i < vsize; i++) {
635                 if(g_app_list[i].state == APP_STATE_PLAYING) {
636                         return g_app_list[i].uid;
637                 }
638         }
639
640         return -1;
641 }
642
643 int ttsd_data_get_same_pid_client_count(int pid)
644 {
645         int vsize = g_app_list.size();
646         int number = 0;
647
648         for (int i = 0;i < vsize;i++) {
649                 if(g_app_list[i].pid == pid) {
650                         number++;
651                 }
652         }
653
654         return number;
655 }
656
657 int ttsd_data_save_error_log(int uid, FILE* fp)
658 {
659         int ret;
660         int pid;
661         /* pid */
662         pid = ttsd_data_get_pid(uid);
663         if (0 > pid) {
664                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get pid");
665         } else {
666                 fprintf(fp, "pid - %d", pid);
667         }
668         /* app state */
669         app_state_e state;
670         ret = ttsd_data_get_client_state(uid, &state);
671         if (0 != ret) {
672                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get app state");
673         } else {
674                 fprintf(fp, "app state - %d", state);
675         }
676
677         int index = 0;
678         unsigned int i;
679
680         index = ttsd_data_is_client(uid);
681         if (0 > index) {
682                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid client");
683                 return -1;
684         }
685
686         /* get sound data */
687         fprintf(fp, "----- Sound list -----");
688
689         i = 0;
690         std::list<sound_data_s*>::iterator iter;
691         for (iter = g_app_list[index].m_wav_data.begin(); iter != g_app_list[index].m_wav_data.end(); iter++) {
692                 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%ld), uttid(%d), type(%d)",
693                         i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
694                 i++;
695         }
696
697         fprintf(fp, "----------------------");
698
699         /* get speck data */
700         fprintf(fp, "----- Text list -----");
701
702         i = 0;
703         std::list<speak_data_s*>::iterator iter_speak;
704         for (iter_speak = g_app_list[index].m_speak_data.begin(); iter_speak != g_app_list[index].m_speak_data.end(); iter_speak++) {
705                 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)",
706                         i, *iter_speak, (*iter_speak)->lang, (*iter_speak)->vctype, (*iter_speak)->speed, (*iter_speak)->utt_id, (*iter_speak)->text);
707                 i++;
708         }
709         fprintf(fp, "---------------------");
710
711         return 0;
712 }