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.
18 #include "ttsd_main.h"
19 #include "ttsd_data.h"
36 std::list<speak_data_s*> m_speak_data;
37 std::list<sound_data_s*> m_wav_data;
39 std::list<used_voice_s> m_used_voice;
42 static vector<app_data_s> g_app_list;
44 static pthread_mutex_t g_speak_data_mutex = PTHREAD_MUTEX_INITIALIZER;
45 static pthread_mutex_t g_sound_data_mutex = PTHREAD_MUTEX_INITIALIZER;
50 int __data_show_list()
52 int vsize = g_app_list.size();
54 SLOG(LOG_DEBUG, tts_tag(), "----- client list -----");
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);
61 SLOG(LOG_DEBUG, tts_tag(), "No Client");
64 SLOG(LOG_DEBUG, tts_tag(), "-----------------------");
66 return TTSD_ERROR_NONE;
69 int __data_show_sound_list(int index)
71 SLOG(LOG_DEBUG, tts_tag(), "----- Sound list -----");
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(%d), uttid(%d), type(%d)",
77 i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
82 SLOG(LOG_DEBUG, tts_tag(), "No Sound Data");
85 SLOG(LOG_DEBUG, tts_tag(), "----------------------");
86 return TTSD_ERROR_NONE;
89 int __data_show_text_list(int index)
91 SLOG(LOG_DEBUG, tts_tag(), "----- Text list -----");
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);
102 SLOG(LOG_DEBUG, tts_tag(), "No Text Data");
105 SLOG(LOG_DEBUG, tts_tag(), "---------------------");
106 return TTSD_ERROR_NONE;
109 int __data_show_used_voice_list(int index)
111 SLOG(LOG_DEBUG, tts_tag(), "----- Used voice list -----");
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);
121 SLOG(LOG_DEBUG, tts_tag(), "No Voice Data");
124 SLOG(LOG_DEBUG, tts_tag(), "---------------------------");
125 return TTSD_ERROR_NONE;
129 * ttsd data functions
132 int ttsd_data_new_client(int pid, int uid)
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;
142 app.utt_id_stopped = 0;
143 app.state = APP_STATE_READY;
145 g_app_list.insert(g_app_list.end(), app);
150 return TTSD_ERROR_NONE;
153 int ttsd_data_delete_client(int uid)
157 index = ttsd_data_is_client(uid);
160 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
164 if (0 != ttsd_data_clear_data(uid)) {
165 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] Fail to clear data");
169 g_app_list.erase(g_app_list.begin()+index);
174 return TTSD_ERROR_NONE;
177 int ttsd_data_is_client(int uid)
179 int vsize = g_app_list.size();
181 for (int i = 0; i < vsize; i++) {
182 if(g_app_list[i].uid == uid) {
190 int ttsd_data_get_client_count()
192 return g_app_list.size();
195 int ttsd_data_get_pid(int uid)
199 index = ttsd_data_is_client(uid);
202 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
203 return TTSD_ERROR_INVALID_PARAMETER;
206 return g_app_list[index].pid;
209 int ttsd_data_get_speak_data_size(int uid)
212 index = ttsd_data_is_client(uid);
215 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
216 return TTSD_ERROR_INVALID_PARAMETER;
219 /* mutex is locked */
220 pthread_mutex_lock(&g_speak_data_mutex);
221 int size = g_app_list[index].m_speak_data.size();
223 /* mutex is unlocked */
224 pthread_mutex_unlock(&g_speak_data_mutex);
229 int ttsd_data_set_used_voice(int uid, const char* lang, int type)
232 index = ttsd_data_is_client(uid);
235 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
236 return TTSD_ERROR_INVALID_PARAMETER;
240 std::list<used_voice_s>::iterator iter;
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);
250 used_voice_s used_voice;
251 used_voice.lang = strdup(lang);
252 used_voice.vctype = type;
255 iter = g_app_list[index].m_used_voice.insert(g_app_list[index].m_used_voice.end(), used_voice);
256 } catch (const std::bad_alloc&) {
257 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_used_voice (bad_alloc)");
260 SLOG(LOG_ERROR, tts_tag(), "[DATA] lang(%s), vctype(%d)", iter->lang, iter->vctype);
263 __data_show_used_voice_list(index);
266 return -1; /* Need to load voice*/
269 int ttsd_data_reset_used_voice(int uid, ttsd_used_voice_cb callback)
272 index = ttsd_data_is_client(uid);
275 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
276 return TTSD_ERROR_INVALID_PARAMETER;
279 if (NULL == callback) {
280 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] Used voice callback is NULL");
284 std::list<used_voice_s>::iterator iter;
286 for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end(); ++iter) {
287 if (NULL != callback) {
288 callback(iter->lang, iter->vctype);
291 if (NULL != iter->lang) {
297 g_app_list[index].m_used_voice.clear();
300 __data_show_used_voice_list(index);
303 return TTSD_ERROR_NONE;
306 int ttsd_data_add_speak_data(int uid, speak_data_s* data)
309 index = ttsd_data_is_client(uid);
312 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
313 return TTSD_ERROR_INVALID_PARAMETER;
316 /* mutex is locked */
317 pthread_mutex_lock(&g_speak_data_mutex);
319 std::list<speak_data_s*>::iterator iter;
322 iter = g_app_list[index].m_speak_data.insert(g_app_list[index].m_speak_data.end(), data);
323 } catch (const std::bad_alloc&) {
324 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_speak_data (bad_alloc)");
325 pthread_mutex_unlock(&g_speak_data_mutex);
327 return TTSD_ERROR_OUT_OF_MEMORY;
329 SLOG(LOG_ERROR, tts_tag(), "[DATA][%p] utt_id(%d), text(%s), lang(%s), vctype(%d), speed(%d)",
330 *iter, (*iter)->utt_id, (*iter)->text, (*iter)->lang, (*iter)->vctype, (*iter)->speed);
332 if (1 == data->utt_id)
333 g_app_list[index].utt_id_stopped = 0;
336 __data_show_text_list(index);
338 pthread_mutex_unlock(&g_speak_data_mutex);
340 return TTSD_ERROR_NONE;
343 int ttsd_data_get_speak_data(int uid, speak_data_s** data)
346 index = ttsd_data_is_client(uid);
349 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid(%d)", uid);
350 return TTSD_ERROR_INVALID_PARAMETER;
353 /* mutex is locked */
354 pthread_mutex_lock(&g_speak_data_mutex);
356 if (0 == g_app_list[index].m_speak_data.size()) {
358 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] There is no speak data");
360 pthread_mutex_unlock(&g_speak_data_mutex);
364 std::list<speak_data_s*>::iterator iter = g_app_list[index].m_speak_data.begin();
366 if (!g_app_list[index].m_speak_data.empty())
367 g_app_list[index].m_speak_data.pop_front();
370 __data_show_text_list(index);
372 pthread_mutex_unlock(&g_speak_data_mutex);
374 return TTSD_ERROR_NONE;
377 int ttsd_data_add_sound_data(int uid, sound_data_s* data)
380 index = ttsd_data_is_client(uid);
383 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
384 return TTSD_ERROR_INVALID_PARAMETER;
388 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] sound data is NULL");
389 return TTSD_ERROR_INVALID_PARAMETER;
391 /* mutex is locked */
392 pthread_mutex_lock(&g_sound_data_mutex);
394 std::list<sound_data_s*>::iterator iter;
397 iter = g_app_list[index].m_wav_data.insert(g_app_list[index].m_wav_data.end(), data);
398 } catch (const std::bad_alloc&) {
399 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_sound_data (bad_alloc)");
400 pthread_mutex_unlock(&g_sound_data_mutex);
402 return TTSD_ERROR_OUT_OF_MEMORY;
404 SLOG(LOG_ERROR, tts_tag(), "[DATA][%p] utt_id(%d), data(%p)", *iter, (*iter)->utt_id, (*iter)->data);
407 __data_show_sound_list(index);
410 /* mutex is unlocked */
411 pthread_mutex_unlock(&g_sound_data_mutex);
413 return TTSD_ERROR_NONE;
416 int ttsd_data_get_sound_data(int uid, sound_data_s** data)
419 index = ttsd_data_is_client(uid);
422 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
423 return TTSD_ERROR_INVALID_PARAMETER;
426 /* mutex is locked */
427 pthread_mutex_lock(&g_sound_data_mutex);
429 if (0 == g_app_list[index].m_wav_data.size()) {
431 SLOG(LOG_DEBUG, tts_tag(), "[DATA] There is no wav data");
433 /* mutex is unlocked */
434 pthread_mutex_unlock(&g_sound_data_mutex);
438 std::list<sound_data_s*>::iterator iter = g_app_list[index].m_wav_data.begin();
440 if (!g_app_list[index].m_wav_data.empty())
441 g_app_list[index].m_wav_data.pop_front();
444 __data_show_sound_list(index);
447 /* mutex is unlocked */
448 pthread_mutex_unlock(&g_sound_data_mutex);
450 return TTSD_ERROR_NONE;
453 int ttsd_data_get_sound_data_size(int uid)
457 index = ttsd_data_is_client(uid);
460 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
461 return TTSD_ERROR_INVALID_PARAMETER;
464 /* mutex is locked */
465 pthread_mutex_lock(&g_sound_data_mutex);
466 data_size = g_app_list[index].m_wav_data.size();
468 /* mutex is unlocked */
469 pthread_mutex_unlock(&g_sound_data_mutex);
474 int ttsd_data_clear_data(int uid)
478 index = ttsd_data_is_client(uid);
480 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
481 return TTSD_ERROR_INVALID_PARAMETER;
484 int removed_last_uttid = -1;
485 speak_data_s* temp_speak = NULL;
486 sound_data_s* temp_sound = NULL;
488 /* free allocated data */
490 if (0 != ttsd_data_get_speak_data(uid, &temp_speak)) {
494 if (NULL != temp_speak) {
495 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)",
496 temp_speak->utt_id, temp_speak->text, temp_speak->lang, temp_speak->vctype, temp_speak->speed);
498 if (NULL != temp_speak->text) {
499 free(temp_speak->text);
500 temp_speak->text = NULL;
502 if (NULL != temp_speak->lang) {
503 free(temp_speak->lang);
504 temp_speak->lang = NULL;
506 removed_last_uttid = temp_speak->utt_id;
513 if (-1 != removed_last_uttid) {
514 g_app_list[index].utt_id_stopped = removed_last_uttid;
518 if (0 != ttsd_data_get_sound_data(uid, &temp_sound)) {
522 if (NULL != temp_sound) {
523 SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] uid(%d), event(%d) data(%p) size(%d) rate(%d) utt(%d)",
524 temp_sound, uid, temp_sound->event, temp_sound->data, temp_sound->data_size, temp_sound->rate, temp_sound->utt_id);
526 if (NULL != temp_sound->data) {
527 free(temp_sound->data);
528 temp_sound->data = NULL;
536 pthread_mutex_lock(&g_speak_data_mutex);
537 g_app_list[index].m_speak_data.clear();
538 pthread_mutex_unlock(&g_speak_data_mutex);
540 pthread_mutex_lock(&g_sound_data_mutex);
541 g_app_list[index].m_wav_data.clear();
542 pthread_mutex_unlock(&g_sound_data_mutex);
544 return TTSD_ERROR_NONE;
547 int ttsd_data_get_client_state(int uid, app_state_e* state)
551 index = ttsd_data_is_client(uid);
553 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
554 return TTSD_ERROR_INVALID_PARAMETER;
557 *state = g_app_list[index].state;
559 return TTSD_ERROR_NONE;
562 int ttsd_data_set_client_state(int uid, app_state_e state)
566 index = ttsd_data_is_client(uid);
568 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
569 return TTSD_ERROR_INVALID_PARAMETER;
572 /* The client of playing state of all clients is only one. need to check state. */
573 if (APP_STATE_PLAYING == state) {
574 int vsize = g_app_list.size();
575 for (int i = 0; i < vsize; i++) {
576 if(g_app_list[i].state == APP_STATE_PLAYING) {
577 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] A playing client has already existed.");
583 g_app_list[index].state = state;
585 return TTSD_ERROR_NONE;
588 int ttsd_data_get_current_playing()
590 int vsize = g_app_list.size();
592 for (int i = 0; i < vsize; i++) {
593 if (APP_STATE_PLAYING == g_app_list[i].state) {
594 SLOG(LOG_DEBUG, tts_tag(), "[DATA] uid(%d) is playing", g_app_list[i].uid);
595 return g_app_list[i].uid;
602 int ttsd_data_foreach_clients(ttsd_data_get_client_cb callback, void* user_data)
604 if (NULL == callback) {
605 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] input data is NULL!!");
614 vector<app_data_s> temp_app_list;
615 int vsize = g_app_list.size();
618 for (i = 0;i < vsize;i++) {
620 app.pid = g_app_list[i].pid;
621 app.uid = g_app_list[i].uid;
622 app.utt_id_stopped = 0;
623 app.state = g_app_list[i].state;
625 temp_app_list.insert(temp_app_list.end(), app);
628 for (i = 0;i < vsize;i++) {
629 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);
630 if (false == callback(temp_app_list[i].pid, temp_app_list[i].uid, temp_app_list[i].state, user_data)) {
635 for (i = 0;i < vsize;i++) {
636 temp_app_list.erase(temp_app_list.begin());
642 bool ttsd_data_is_uttid_valid(int uid, int uttid)
646 index = ttsd_data_is_client(uid);
648 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
649 return TTSD_ERROR_INVALID_PARAMETER;
652 if (uttid < g_app_list[index].utt_id_stopped)
658 int ttsd_data_is_current_playing()
660 int vsize = g_app_list.size();
662 for (int i = 0; i < vsize; i++) {
663 if(g_app_list[i].state == APP_STATE_PLAYING) {
664 return g_app_list[i].uid;
671 int ttsd_data_get_same_pid_client_count(int pid)
673 int vsize = g_app_list.size();
676 for (int i = 0;i < vsize;i++) {
677 if(g_app_list[i].pid == pid) {
685 int ttsd_data_save_error_log(int uid, FILE* fp)
690 pid = ttsd_data_get_pid(uid);
692 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get pid");
694 fprintf(fp, "pid - %d", pid);
698 ret = ttsd_data_get_client_state(uid, &state);
700 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get app state");
702 fprintf(fp, "app state - %d", state);
708 index = ttsd_data_is_client(uid);
710 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid client");
715 fprintf(fp, "----- Sound list -----");
718 std::list<sound_data_s*>::iterator iter;
719 for (iter = g_app_list[index].m_wav_data.begin(); iter != g_app_list[index].m_wav_data.end(); ++iter) {
720 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%d), uttid(%d), type(%d)",
721 i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
725 fprintf(fp, "----------------------");
728 fprintf(fp, "----- Text list -----");
731 std::list<speak_data_s*>::iterator iter_speak;
732 for (iter_speak = g_app_list[index].m_speak_data.begin(); iter_speak != g_app_list[index].m_speak_data.end(); ++iter_speak) {
733 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)",
734 i, *iter_speak, (*iter_speak)->lang, (*iter_speak)->vctype, (*iter_speak)->speed, (*iter_speak)->utt_id, (*iter_speak)->text);
737 fprintf(fp, "---------------------");