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