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