Initialize type of app data
[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 <mutex>
17 #include <vector>
18 #include <atomic>
19
20 #include "ttsd_data.h"
21
22 using namespace std;
23
24 typedef struct
25 {
26         char*   lang;
27         int     vctype;
28 }used_voice_s;
29
30 typedef struct
31 {
32         int             pid;
33         unsigned int            uid;
34         int             utt_id_stopped;
35         app_tts_state_e state;
36         tts_app_play_type_e type;
37         ttsd_mode_e     mode;
38         ttse_result_event_e result_event;
39
40         std::list<speak_data_s*> m_speak_data;
41         std::list<sound_data_s*> m_wav_data;
42         bool paused_data_existing;
43
44         std::list<used_voice_s> m_used_voice;
45         tts_ipc_method_e ipc_method;
46
47         char* credential;
48 } app_data_s;
49
50 static vector<app_data_s> g_app_list;
51
52 static mutex g_app_data_mutex;
53
54 /* If engine is running */
55 static atomic<ttsd_synthesis_control_e> g_synth_control;
56
57 #ifdef DATA_DEBUG
58 static void __data_show_list()
59 {
60         SLOG(LOG_DEBUG, tts_tag(), "----- client list -----");
61
62         unsigned int i = 0;
63         for (auto& appData : g_app_list) {
64                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[%dth] pid(%d), uid(%u), state(%d)", i, appData.pid, appData.uid, appData.state);
65                 i++;
66         }
67
68         if (0 == i) {
69                 SLOG(LOG_DEBUG, tts_tag(), "No Client");
70         }
71
72         SLOG(LOG_DEBUG, tts_tag(), "-----------------------");
73 }
74
75 static void __data_show_sound_list(app_data_s& app_data)
76 {
77         SLOG(LOG_DEBUG, tts_tag(), "----- Sound list -----");
78
79         unsigned int i = 0;
80         for (auto& wavData : app_data.m_wav_data) {
81                 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%d), uttid(%d), type(%d)",
82                                 i + 1, wavData, wavData->data, wavData->data_size, wavData->utt_id, wavData->audio_type);
83                 i++;
84         }
85
86         if (0 == i) {
87                 SLOG(LOG_DEBUG, tts_tag(), "No Sound Data");
88         }
89
90         SLOG(LOG_DEBUG, tts_tag(), "----------------------");
91 }
92
93 static void __data_show_text_list(app_data_s& app_data)
94 {
95         SLOG(LOG_DEBUG, tts_tag(), "----- Text list -----");
96
97         unsigned int i = 0;
98         for (auto& speakData : app_data.m_speak_data) {
99                 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)",
100                                 i + 1, speakData, speakData->lang, speakData->vctype, speakData->speed, speakData->utt_id, speakData->text);
101                 i++;
102         }
103
104         if (0 == i) {
105                 SLOG(LOG_DEBUG, tts_tag(), "No Text Data");
106         }
107
108         SLOG(LOG_DEBUG, tts_tag(), "---------------------");
109 }
110
111 static void __data_show_used_voice_list(app_data_s& app_data)
112 {
113         SLOG(LOG_DEBUG, tts_tag(), "----- Used voice list -----");
114
115         unsigned int i = 0;
116         for (auto& usedVoice : app_data.m_used_voice) {
117                 SLOG(LOG_DEBUG, tts_tag(), "[%dth] lang(%s), vctype(%d)", i + 1, usedVoice.lang, usedVoice.vctype);
118                 i++;
119         }
120
121         if (0 == i) {
122                 SLOG(LOG_DEBUG, tts_tag(), "No Voice Data");
123         }
124
125         SLOG(LOG_DEBUG, tts_tag(), "---------------------------");
126 }
127 #endif
128
129 /*
130 * ttsd data functions
131 */
132
133 int ttsd_data_set_synth_control(ttsd_synthesis_control_e control)
134 {
135         SLOG(LOG_INFO, tts_tag(), "[DATA INFO] set synth_control(%d)", control);
136         g_synth_control = control;
137         return 0;
138 }
139
140 ttsd_synthesis_control_e ttsd_data_get_synth_control()
141 {
142         return g_synth_control.load();
143 }
144
145 static app_data_s* __get_client_app_data(unsigned int uid)
146 {
147         for (auto& app_data : g_app_list) {
148                 if (app_data.uid == uid) {
149                         return &app_data;
150                 }
151         }
152
153         return nullptr;
154 }
155
156 int ttsd_data_new_client(int pid, unsigned int uid)
157 {
158         lock_guard<mutex> lock(g_app_data_mutex);
159         if(nullptr != __get_client_app_data(uid) ) {
160                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is already registered (%u)", uid);
161                 return TTSD_ERROR_INVALID_PARAMETER;
162         }
163
164         app_data_s app;
165         app.pid = pid;
166         app.uid = uid;
167         app.utt_id_stopped = 0;
168         app.state = APP_STATE_READY;
169         app.type = TTS_APP_PLAY_TYPE_SYNTH;
170         app.mode = TTSD_MODE_DEFAULT;
171         app.result_event = TTSE_RESULT_EVENT_FAIL;
172         app.ipc_method = TTS_IPC_METHOD_UNDEFINED;
173         app.credential = nullptr;
174         app.paused_data_existing = false;
175
176         g_app_list.push_back(app);
177
178 #ifdef DATA_DEBUG
179         __data_show_list();
180 #endif
181
182         SLOG(LOG_INFO, tts_tag(), "[DATA INFO] New client. pid(%d), uid(%u)", app.pid, app.uid);
183
184         return TTSD_ERROR_NONE;
185 }
186
187 static inline void __destroy_speak_data(speak_data_s* speak_data)
188 {
189         SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)",
190                         speak_data->utt_id, speak_data->text, speak_data->lang, speak_data->vctype, speak_data->speed);
191
192         free(speak_data->text);
193         free(speak_data->lang);
194
195         delete speak_data;
196 }
197
198 static inline void __destroy_sound_data(sound_data_s* sound_data)
199 {
200         SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] event(%d) data(%p) size(%d) rate(%d) utt(%d)",
201                         sound_data, sound_data->event, sound_data->data, sound_data->data_size, sound_data->rate, sound_data->utt_id);
202
203         delete[] sound_data->data;
204         delete sound_data;
205 }
206
207 static void __clean_data(app_data_s& app_data)
208 {
209         SLOG(LOG_ERROR, tts_tag(), "[INFO] Clean data. uid(%u)", app_data.uid);
210
211         int removed_last_uttid = -1;
212         for (auto& speak_data : app_data.m_speak_data) {
213                 if (nullptr == speak_data) {
214                         continue;
215                 }
216
217                 removed_last_uttid = speak_data->utt_id;
218
219                 __destroy_speak_data(speak_data);
220                 speak_data = nullptr;
221         }
222
223         if (-1 != removed_last_uttid) {
224                 app_data.utt_id_stopped = removed_last_uttid;
225         }
226
227         for (auto& sound_data : app_data.m_wav_data) {
228                 if (nullptr == sound_data) {
229                         continue;
230                 }
231
232                 __destroy_sound_data(sound_data);
233                 sound_data = nullptr;
234         }
235
236         app_data.m_speak_data.clear();
237         app_data.m_wav_data.clear();
238 }
239
240 int ttsd_data_delete_client(unsigned int uid)
241 {
242         lock_guard<mutex> lock(g_app_data_mutex);
243         int index = 0;
244         for (auto& app_data : g_app_list) {
245                 if (app_data.uid == uid) {
246                         break;
247                 }
248
249                 index++;
250         }
251
252         if (index >= (int)g_app_list.size()) {
253                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
254                 return TTSD_ERROR_INVALID_PARAMETER;
255         }
256
257         __clean_data(g_app_list[index]);
258
259         g_app_list.erase(g_app_list.begin() + index);
260
261 #ifdef DATA_DEBUG
262         __data_show_list();
263 #endif
264
265         SLOG(LOG_INFO, tts_tag(), "[DATA INFO] Client is deleted. uid(%u), index(%d)", uid, index);
266
267         return TTSD_ERROR_NONE;
268 }
269
270 int ttsd_data_is_client(unsigned int uid)
271 {
272         lock_guard<mutex> lock(g_app_data_mutex);
273         int vsize = g_app_list.size();
274         for (int i = 0; i < vsize; i++) {
275                 if(g_app_list[i].uid == uid) {
276                         return i;
277                 }
278         }
279
280         SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] There is no corresponding client. uid(%u)", uid);
281
282         return -1;
283 }
284
285 int ttsd_data_get_client_count()
286 {
287         int num_client = g_app_list.size();
288         SLOG(LOG_INFO, tts_tag(), "[DATA INFO] Number of clients(%d)", num_client);
289
290         return num_client;
291 }
292
293 int ttsd_data_get_pid(unsigned int uid)
294 {
295         lock_guard<mutex> lock(g_app_data_mutex);
296         app_data_s* app_data = __get_client_app_data(uid);
297         if (nullptr == app_data) {
298                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
299                 return -1;
300         }
301
302         SLOG(LOG_INFO, tts_tag(), "[DATA INFO] uid(%u), pid(%d)", uid, app_data->pid);
303
304         return app_data->pid;
305 }
306
307 int ttsd_data_set_ipc_method(unsigned int uid, tts_ipc_method_e method)
308 {
309         lock_guard<mutex> lock(g_app_data_mutex);
310         app_data_s* app_data = __get_client_app_data(uid);
311         if (nullptr == app_data) {
312                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
313                 return TTSD_ERROR_INVALID_PARAMETER;
314         }
315
316         app_data->ipc_method = method;
317
318         return TTSD_ERROR_NONE;
319 }
320
321 tts_ipc_method_e ttsd_data_get_ipc_method(unsigned int uid)
322 {
323         lock_guard<mutex> lock(g_app_data_mutex);
324         app_data_s* app_data = __get_client_app_data(uid);
325         if (nullptr == app_data) {
326                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
327                 return TTS_IPC_METHOD_UNDEFINED;
328         }
329
330         return app_data->ipc_method;
331 }
332
333 int ttsd_data_set_mode(unsigned int uid, ttsd_mode_e mode)
334 {
335         lock_guard<mutex> lock(g_app_data_mutex);
336         app_data_s* app_data = __get_client_app_data(uid);
337         if (nullptr == app_data) {
338                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
339                 return TTSD_ERROR_INVALID_PARAMETER;
340         }
341
342         app_data->mode = mode;
343
344         return TTSD_ERROR_NONE;
345 }
346
347 ttsd_mode_e ttsd_data_get_mode(unsigned int uid)
348 {
349         lock_guard<mutex> lock(g_app_data_mutex);
350         app_data_s* app_data = __get_client_app_data(uid);
351         if (nullptr == app_data) {
352                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
353                 return TTSD_MODE_DEFAULT;
354         }
355
356         return app_data->mode;
357 }
358
359 int ttsd_data_set_credential(unsigned int uid, const char* credential)
360 {
361         lock_guard<mutex> lock(g_app_data_mutex);
362         app_data_s* app_data = __get_client_app_data(uid);
363         if (nullptr == app_data) {
364                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
365                 return TTSD_ERROR_INVALID_PARAMETER;
366         }
367
368         free(app_data->credential);
369         app_data->credential = nullptr;
370
371         if (credential) {
372                 app_data->credential = strdup(credential);
373         }
374
375         return TTSD_ERROR_NONE;
376 }
377
378 char* ttsd_data_get_credential(unsigned int uid)
379 {
380         lock_guard<mutex> lock(g_app_data_mutex);
381         app_data_s* app_data = __get_client_app_data(uid);
382         if (nullptr == app_data) {
383                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
384                 return nullptr;
385         }
386
387         if (nullptr == app_data->credential) {
388                 return nullptr;
389         }
390
391         return strdup(app_data->credential);
392 }
393
394 int ttsd_data_get_speak_data_size(unsigned int uid)
395 {
396         lock_guard<mutex> lock(g_app_data_mutex);
397         app_data_s* app_data = __get_client_app_data(uid);
398         if (nullptr == app_data) {
399                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
400                 return TTSD_ERROR_INVALID_PARAMETER;
401         }
402
403         return app_data->m_speak_data.size();
404 }
405
406 int ttsd_data_set_used_voice(unsigned int uid, const char* lang, int type)
407 {
408         lock_guard<mutex> lock(g_app_data_mutex);
409         app_data_s* app_data = __get_client_app_data(uid);
410         if (nullptr == app_data) {
411                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
412                 return TTSD_ERROR_INVALID_PARAMETER;
413         }
414
415         /* Find voice */
416         list<used_voice_s>& usedVoices = app_data->m_used_voice;
417         for (auto& voice : usedVoices) {
418                 if (0 == strncmp(lang, voice.lang, strlen(lang)) && type == voice.vctype) {
419                         SLOG(LOG_DEBUG, tts_tag(), "[DATA] The voice is already registered (%s)(%d)", lang, type);
420                         return 0;
421                 }
422         }
423
424         /* Add voice */
425         used_voice_s used_voice;
426         used_voice.lang = strdup(lang);
427         used_voice.vctype = type;
428
429         try {
430                 usedVoices.push_back(used_voice);
431         } catch (const std::bad_alloc&) {
432                 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_used_voice (bad_alloc)");
433                 return -1;
434         }
435         SLOG(LOG_ERROR, tts_tag(), "[DATA] lang(%s), vctype(%d)", used_voice.lang, used_voice.vctype);
436
437 #ifdef DATA_DEBUG
438         __data_show_used_voice_list(*app_data);
439 #endif
440
441         return -1;      /* Need to load voice*/
442 }
443
444 int ttsd_data_reset_used_voice(unsigned int uid, ttsd_used_voice_cb callback)
445 {
446         unique_lock<mutex> lock(g_app_data_mutex);
447         app_data_s* app_data = __get_client_app_data(uid);
448         if (nullptr == app_data) {
449                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
450                 return TTSD_ERROR_INVALID_PARAMETER;
451         }
452
453         if (nullptr == callback) {
454                 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] Used voice callback is nullptr");
455         }
456
457         /* Find voice */
458         list<used_voice_s>& usedVoices = app_data->m_used_voice;
459         for (auto& voice : usedVoices) {
460                 if (nullptr != callback) {
461                         lock.unlock();
462                         callback(voice.lang, voice.vctype);
463                         lock.lock();
464                 }
465
466                 if (nullptr != voice.lang) {
467                         free(voice.lang);
468                         voice.lang = nullptr;
469                 }
470         }
471         usedVoices.clear();
472
473 #ifdef DATA_DEBUG
474         __data_show_used_voice_list(*app_data);
475 #endif
476
477         return TTSD_ERROR_NONE;
478 }
479
480 speak_data_s* ttsd_data_create_speak_data(const char* text, const char* language, int voice_type, int speed, int utt_id)
481 {
482         speak_data_s* speak_data = new speak_data_s();
483         if (nullptr == speak_data) {
484                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to allocate memory for speak_data_s");
485                 return nullptr;
486         }
487
488         speak_data->text = strdup(text);
489         speak_data->lang = strdup(language);
490
491         speak_data->vctype = voice_type;
492         speak_data->speed = speed;
493         speak_data->utt_id = utt_id;
494
495         return speak_data;
496 }
497
498 void ttsd_data_destroy_speak_data(speak_data_s* speak_data)
499 {
500         if (nullptr == speak_data) {
501                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[ERROR] data is nullptr");
502                 return;
503         }
504         __destroy_speak_data(speak_data);
505 }
506
507 int ttsd_data_add_speak_data(unsigned int uid, speak_data_s* data)
508 {
509         lock_guard<mutex> lock(g_app_data_mutex);
510         app_data_s* app_data = __get_client_app_data(uid);
511         if (nullptr == app_data) {
512                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
513                 return TTSD_ERROR_INVALID_PARAMETER;
514         }
515
516         SLOG(LOG_INFO, tts_tag(), "[DATA INFO] uid(%u)", uid);
517
518         try {
519                 list<speak_data_s*>& speakData = app_data->m_speak_data;
520                 SLOG(LOG_INFO, tts_tag(), "[DATA INFO] m_speak_data size(%zu)", speakData.size());
521                 speakData.push_back(data);
522         } catch (const std::bad_alloc&) {
523                 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_speak_data (bad_alloc)");
524                 return TTSD_ERROR_OUT_OF_MEMORY;
525         }
526
527         SLOG(LOG_ERROR, tts_tag(), "[DATA][%p] utt_id(%d), text(%s), lang(%s), vctype(%d), speed(%d)",
528                         data, data->utt_id, data->text, data->lang, data->vctype, data->speed);
529
530         if (1 == data->utt_id)
531                 app_data->utt_id_stopped = 0;
532
533 #ifdef DATA_DEBUG
534         __data_show_text_list(*app_data);
535 #endif
536
537         return TTSD_ERROR_NONE;
538 }
539
540 static speak_data_s* __get_speak_data(app_data_s* app_data)
541 {
542         if (app_data->m_speak_data.empty()) {
543 #ifdef DATA_DEBUG
544                 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] There is no speak data");
545 #endif
546                 return nullptr;
547         }
548
549 #ifdef DATA_DEBUG
550         __data_show_text_list(*app_data);
551 #endif
552
553         return app_data->m_speak_data.front();
554 }
555
556 int ttsd_data_get_speak_data(unsigned int uid, speak_data_s** data)
557 {
558         lock_guard<mutex> lock(g_app_data_mutex);
559         app_data_s* app_data = __get_client_app_data(uid);
560         if (nullptr == app_data) {
561                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
562                 return TTSD_ERROR_INVALID_PARAMETER;
563         }
564
565         speak_data_s* speakData = __get_speak_data(app_data);
566         if (nullptr == speakData) {
567                 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] There is no speak data");
568                 return TTSD_ERROR_OPERATION_FAILED;
569         }
570
571         app_data->m_speak_data.pop_front();
572         *data = speakData;
573
574         return TTSD_ERROR_NONE;
575 }
576
577 sound_data_s* ttsd_data_create_sound_data(int utt_id, const void* data, unsigned int data_size, ttse_result_event_e event,
578                 ttse_audio_type_e audio_type, int rate, int channels)
579 {
580         /* add wav data */
581         sound_data_s* sound_data = new sound_data_s();
582         if (nullptr == sound_data) {
583                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to allocate memory for speak_data_s");
584                 return nullptr;
585         }
586
587         sound_data->data = nullptr;
588         sound_data->data_size = 0;
589
590         if (nullptr != data && 0 < data_size) {
591                 sound_data->data = new char[data_size];
592                 if (nullptr != sound_data->data) {
593                         memcpy(sound_data->data, data, data_size);
594                         sound_data->data_size = data_size;
595                         SLOG(LOG_INFO, tts_tag(), "[DEBUG][memcpy] event(%d) sound_data(%p) data(%p) size(%u)",
596                                 event, sound_data, sound_data->data, sound_data->data_size);
597                 } else {
598                         SLOG(LOG_ERROR, tts_tag(), "Fail to allocate memory");
599                 }
600         } else {
601                 SLOG(LOG_ERROR, tts_tag(), "Sound data is nullptr");
602         }
603
604         sound_data->utt_id = utt_id;
605         sound_data->event = event;
606         sound_data->audio_type = audio_type;
607         sound_data->rate = rate;
608         sound_data->channels = channels;
609         sound_data->played_data_size = 0;
610
611         return sound_data;
612 }
613
614 void ttsd_data_destroy_sound_data(sound_data_s* sound_data)
615 {
616         if (nullptr == sound_data) {
617                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[ERROR] data is nullptr");
618                 return;
619         }
620
621         __destroy_sound_data(sound_data);
622 }
623
624 int ttsd_data_add_sound_data(unsigned int uid, sound_data_s* data)
625 {
626         lock_guard<mutex> lock(g_app_data_mutex);
627         app_data_s* app_data = __get_client_app_data(uid);
628         if (nullptr == app_data) {
629                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
630                 return TTSD_ERROR_INVALID_PARAMETER;
631         }
632
633         if (nullptr == data) {
634                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] sound data is nullptr");
635                 return TTSD_ERROR_INVALID_PARAMETER;
636         }
637
638         SLOG(LOG_INFO, tts_tag(), "[DATA INFO] uid(%u)", uid);
639
640         try {
641                 list<sound_data_s*>& wavData = app_data->m_wav_data;
642                 SLOG(LOG_INFO, tts_tag(), "[DATA INFO] m_wav_data size(%zu)", wavData.size());
643                 wavData.push_back(data);
644         } catch (const std::bad_alloc&) {
645                 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_sound_data (bad_alloc)");
646                 return TTSD_ERROR_OUT_OF_MEMORY;
647         }
648         SLOG(LOG_ERROR, tts_tag(), "[DATA][%p] utt_id(%d), data(%p) data size(%d), type(%d)",
649                         data, data->utt_id, data->data, data->data_size, data->audio_type);
650
651 #ifdef DATA_DEBUG
652         __data_show_sound_list(*app_data);
653 #endif
654
655         return TTSD_ERROR_NONE;
656 }
657
658 static sound_data_s* __get_sound_data(app_data_s* app_data)
659 {
660         if (app_data->m_wav_data.empty()) {
661 #ifdef DATA_DEBUG
662                 SLOG(LOG_DEBUG, tts_tag(), "[DATA] There is no wav data");
663 #endif
664                 return nullptr;
665         }
666
667 #ifdef DATA_DEBUG
668         __data_show_sound_list(*app_data);
669 #endif
670
671         return app_data->m_wav_data.front();
672 }
673
674 sound_data_s* ttsd_data_get_first_sound_data(unsigned int uid)
675 {
676         lock_guard<mutex> lock(g_app_data_mutex);
677         app_data_s* app_data = __get_client_app_data(uid);
678         if (nullptr == app_data) {
679                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
680                 return nullptr;
681         }
682
683         return __get_sound_data(app_data);
684 }
685
686 int ttsd_data_pop_sound_data(unsigned int uid)
687 {
688         lock_guard<mutex> lock(g_app_data_mutex);
689         app_data_s* app_data = __get_client_app_data(uid);
690         if (nullptr == app_data) {
691                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
692                 return TTSD_ERROR_INVALID_PARAMETER;
693         }
694
695         if (app_data->m_wav_data.empty()) {
696                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] Sound data is empty (%u)", uid);
697                 return TTSD_ERROR_OPERATION_FAILED;
698         }
699
700         app_data->m_wav_data.pop_front();
701         return TTSD_ERROR_NONE;
702 }
703
704 int ttsd_data_get_sound_data_size(unsigned int uid)
705 {
706         lock_guard<mutex> lock(g_app_data_mutex);
707         app_data_s* app_data = __get_client_app_data(uid);
708         if (nullptr == app_data) {
709                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
710                 return -1;
711         }
712
713         return app_data->m_wav_data.size();
714 }
715
716 int ttsd_data_set_last_sound_result_event(unsigned int uid, ttse_result_event_e event)
717 {
718         lock_guard<mutex> lock(g_app_data_mutex);
719         app_data_s* app_data = __get_client_app_data(uid);
720         if (nullptr == app_data) {
721                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
722                 return TTSE_ERROR_INVALID_PARAMETER;
723         }
724
725         app_data->result_event = event;
726         return TTSE_ERROR_NONE;
727 }
728
729 ttse_result_event_e ttsd_data_get_last_sound_result_event(unsigned int uid)
730 {
731         lock_guard<mutex> lock(g_app_data_mutex);
732         app_data_s* app_data = __get_client_app_data(uid);
733         if (nullptr == app_data) {
734                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
735                 return TTSE_RESULT_EVENT_FAIL;
736         }
737
738         return app_data->result_event;
739 }
740
741 int ttsd_data_clear_data(unsigned int uid)
742 {
743         lock_guard<mutex> lock(g_app_data_mutex);
744         app_data_s* app_data = __get_client_app_data(uid);
745         if (nullptr == app_data) {
746                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
747                 return TTSD_ERROR_INVALID_PARAMETER;
748         }
749
750         __clean_data(*app_data);
751
752         return TTSD_ERROR_NONE;
753 }
754
755 app_tts_state_e ttsd_data_get_client_state(unsigned int uid)
756 {
757         lock_guard<mutex> lock(g_app_data_mutex);
758         app_data_s* app_data = __get_client_app_data(uid);
759         if (nullptr == app_data) {
760                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
761                 return APP_STATE_NONE;
762         }
763
764         return app_data->state;
765 }
766
767 static unsigned int __get_playing_app_uid()
768 {
769         for (auto& app : g_app_list) {
770                 if (APP_STATE_PLAYING == app.state) {
771                         return app.uid;
772                 }
773         }
774
775         return -1;
776 }
777
778 int ttsd_data_set_client_state(unsigned int uid, app_tts_state_e state)
779 {
780         lock_guard<mutex> lock(g_app_data_mutex);
781         app_data_s* app_data = __get_client_app_data(uid);
782         if (nullptr == app_data) {
783                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
784                 return TTSD_ERROR_INVALID_PARAMETER;
785         }
786
787         if (app_data->state == state) {
788                 SLOG(LOG_ERROR, tts_tag(), "[DATA] Already current state. (%d)", state);
789                 return TTSD_ERROR_NONE;
790         }
791
792         /* The client of playing state of all clients is only one. need to check state. */
793         int playing_uid = __get_playing_app_uid();
794         if (APP_STATE_PLAYING == state && 0 < playing_uid) {
795                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] A playing client has already existed. playing app uid(%u)", playing_uid);
796                 return TTSD_ERROR_OPERATION_FAILED;
797         }
798
799         app_data->state = state;
800
801         return TTSD_ERROR_NONE;
802 }
803
804 tts_app_play_type_e ttsd_data_get_play_type(unsigned int uid)
805 {
806         lock_guard<mutex> lock(g_app_data_mutex);
807         app_data_s* app_data = __get_client_app_data(uid);
808         if (nullptr == app_data) {
809                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
810                 return TTS_APP_PLAY_TYPE_SYNTH;
811         }
812
813         return app_data->type;
814 }
815
816 int ttsd_data_set_play_type(unsigned int uid, tts_app_play_type_e type)
817 {
818         lock_guard<mutex> lock(g_app_data_mutex);
819         app_data_s* app_data = __get_client_app_data(uid);
820         if (nullptr == app_data) {
821                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
822                 return TTSD_ERROR_INVALID_PARAMETER;
823         }
824
825         app_data->type = type;
826
827         return TTSD_ERROR_NONE;
828 }
829
830 int ttsd_data_set_paused_data_existing(unsigned int uid, bool is_paused_data_existing)
831 {
832         lock_guard<mutex> lock(g_app_data_mutex);
833         app_data_s* app_data = __get_client_app_data(uid);
834         if (nullptr == app_data) {
835                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
836                 return TTSD_ERROR_INVALID_PARAMETER;
837         }
838
839         app_data->paused_data_existing = is_paused_data_existing;
840         return TTSD_ERROR_NONE;
841 }
842
843 bool ttsd_data_is_paused_data_existing(unsigned int uid)
844 {
845         lock_guard<mutex> lock(g_app_data_mutex);
846         app_data_s* app_data = __get_client_app_data(uid);
847         if (nullptr == app_data) {
848                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
849                 return false;
850         }
851
852         return app_data->paused_data_existing;
853 }
854
855 unsigned int ttsd_data_get_current_playing()
856 {
857         lock_guard<mutex> lock(g_app_data_mutex);
858         unsigned int uid = __get_playing_app_uid();
859
860         SLOG(LOG_INFO, tts_tag(), "[DATA INFO] Current playing uid(%u)", uid);
861
862         return uid;
863 }
864
865 int ttsd_data_foreach_clients(ttsd_data_get_client_cb callback, void* user_data)
866 {
867         if (nullptr == callback) {
868                 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] input data is nullptr!!");
869                 return -1;
870         }
871
872 #ifdef DATA_DEBUG
873         __data_show_list();
874 #endif
875
876         /* Copy app info */
877         vector<app_data_s> temp_app_list;
878
879         unique_lock<mutex> lock(g_app_data_mutex);
880         int vsize = g_app_list.size();
881         for (int i = 0; i < vsize; i++) {
882                 app_data_s app = {0, };
883                 app.pid = g_app_list[i].pid;
884                 app.uid = g_app_list[i].uid;
885                 app.utt_id_stopped = 0;
886                 app.state = g_app_list[i].state;
887
888                 temp_app_list.push_back(app);
889         }
890         lock.unlock();
891
892         for (int i = 0; i < vsize; i++) {
893                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[%dth] pid(%d), uid(%u), state(%d)", i, temp_app_list[i].pid, temp_app_list[i].uid, temp_app_list[i].state);
894                 if (false == callback(temp_app_list[i].pid, temp_app_list[i].uid, temp_app_list[i].state, user_data)) {
895                         break;
896                 }
897         }
898
899         return 0;
900 }
901
902 bool ttsd_data_is_uttid_valid(unsigned int uid, int uttid)
903 {
904         lock_guard<mutex> lock(g_app_data_mutex);
905         app_data_s* app_data = __get_client_app_data(uid);
906         if (nullptr == app_data) {
907                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
908                 return false;
909         }
910
911         if (uttid < app_data->utt_id_stopped)
912                 return false;
913
914         return true;
915 }
916
917 int ttsd_data_get_same_pid_client_count(int pid)
918 {
919         lock_guard<mutex> lock(g_app_data_mutex);
920         int number = 0;
921         for (auto& appData : g_app_list) {
922                 if(appData.pid == pid) {
923                         number++;
924                 }
925         }
926
927         return number;
928 }
929
930 int ttsd_data_save_error_log(unsigned int uid, FILE* fp)
931 {
932         lock_guard<mutex> lock(g_app_data_mutex);
933         app_data_s* app_data = __get_client_app_data(uid);
934         if (nullptr == app_data) {
935                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid client");
936                 return -1;
937         }
938
939         /* pid */
940         fprintf(fp, "pid - %d", app_data->pid);
941
942         /* app state */
943         fprintf(fp, "app state - %d", app_data->state);
944
945         /* get sound data */
946         fprintf(fp, "----- Sound list -----");
947         unsigned int i = 0;
948         for (auto& wavData : app_data->m_wav_data) {
949                 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%d), uttid(%d), type(%d)",
950                                 i, wavData, wavData->data, wavData->data_size, wavData->utt_id, wavData->audio_type);
951                 i++;
952         }
953         fprintf(fp, "----------------------");
954
955         /* get speck data */
956         fprintf(fp, "----- Text list -----");
957
958         i = 0;
959         for (auto& speakData : app_data->m_speak_data) {
960                 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)",
961                                 i, speakData, speakData->lang, speakData->vctype, speakData->speed, speakData->utt_id, speakData->text);
962                 i++;
963         }
964         fprintf(fp, "---------------------");
965
966         return 0;
967 }