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"
34 app_tts_state_e state;
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 if (!g_app_list[index].m_wav_data.empty()) {
75 std::list<sound_data_s*>::iterator iter;
76 for (iter = g_app_list[index].m_wav_data.begin(); (NULL != *iter && iter != g_app_list[index].m_wav_data.end()); ++iter) {
77 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%d), uttid(%d), type(%d)",
78 i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
84 SLOG(LOG_DEBUG, tts_tag(), "No Sound Data");
87 SLOG(LOG_DEBUG, tts_tag(), "----------------------");
88 return TTSD_ERROR_NONE;
91 int __data_show_text_list(int index)
93 SLOG(LOG_DEBUG, tts_tag(), "----- Text list -----");
96 if (!g_app_list[index].m_speak_data.empty()) {
97 std::list<speak_data_s*>::iterator iter;
98 for (iter = g_app_list[index].m_speak_data.begin(); (NULL != *iter && iter != g_app_list[index].m_speak_data.end()); ++iter) {
99 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)",
100 i + 1, *iter, (*iter)->lang, (*iter)->vctype, (*iter)->speed, (*iter)->utt_id, (*iter)->text);
106 SLOG(LOG_DEBUG, tts_tag(), "No Text Data");
109 SLOG(LOG_DEBUG, tts_tag(), "---------------------");
110 return TTSD_ERROR_NONE;
113 int __data_show_used_voice_list(int index)
115 SLOG(LOG_DEBUG, tts_tag(), "----- Used voice list -----");
118 if (!g_app_list[index].m_used_voice.empty()) {
119 std::list<used_voice_s>::iterator iter;
120 for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end(); ++iter) {
121 SLOG(LOG_DEBUG, tts_tag(), "[%dth] lang(%s), vctype(%d)", i + 1, iter->lang, iter->vctype);
127 SLOG(LOG_DEBUG, tts_tag(), "No Voice Data");
130 SLOG(LOG_DEBUG, tts_tag(), "---------------------------");
131 return TTSD_ERROR_NONE;
135 * ttsd data functions
138 int ttsd_data_new_client(int pid, int uid)
140 if( -1 != ttsd_data_is_client(uid) ) {
141 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
142 return TTSD_ERROR_INVALID_PARAMETER;
148 app.utt_id_stopped = 0;
149 app.state = APP_STATE_READY;
151 g_app_list.insert(g_app_list.end(), app);
156 return TTSD_ERROR_NONE;
159 int ttsd_data_delete_client(int uid)
163 index = ttsd_data_is_client(uid);
166 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
170 if (0 != ttsd_data_clear_data(uid)) {
171 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] Fail to clear data");
175 g_app_list.erase(g_app_list.begin()+index);
180 return TTSD_ERROR_NONE;
183 int ttsd_data_is_client(int uid)
185 int vsize = g_app_list.size();
187 for (int i = 0; i < vsize; i++) {
188 if(g_app_list[i].uid == uid) {
196 int ttsd_data_get_client_count()
198 return g_app_list.size();
201 int ttsd_data_get_pid(int uid)
205 index = ttsd_data_is_client(uid);
208 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
209 return TTSD_ERROR_INVALID_PARAMETER;
212 return g_app_list[index].pid;
215 int ttsd_data_get_speak_data_size(int uid)
218 index = ttsd_data_is_client(uid);
221 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
222 return TTSD_ERROR_INVALID_PARAMETER;
225 /* mutex is locked */
226 pthread_mutex_lock(&g_speak_data_mutex);
227 int size = g_app_list[index].m_speak_data.size();
229 /* mutex is unlocked */
230 pthread_mutex_unlock(&g_speak_data_mutex);
235 int ttsd_data_set_used_voice(int uid, const char* lang, int type)
238 index = ttsd_data_is_client(uid);
241 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
242 return TTSD_ERROR_INVALID_PARAMETER;
246 std::list<used_voice_s>::iterator iter;
247 if (!g_app_list[index].m_used_voice.empty()) {
248 for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end();++iter) {
249 if (0 == strcmp(lang, iter->lang) && type == iter->vctype) {
250 SLOG(LOG_DEBUG, tts_tag(), "[DATA] The voice is already registered (%s)(%d)", lang, type);
257 used_voice_s used_voice;
258 used_voice.lang = strdup(lang);
259 used_voice.vctype = type;
262 iter = g_app_list[index].m_used_voice.insert(g_app_list[index].m_used_voice.end(), used_voice);
263 } catch (const std::bad_alloc&) {
264 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_used_voice (bad_alloc)");
267 SLOG(LOG_ERROR, tts_tag(), "[DATA] lang(%s), vctype(%d)", iter->lang, iter->vctype);
270 __data_show_used_voice_list(index);
273 return -1; /* Need to load voice*/
276 int ttsd_data_reset_used_voice(int uid, ttsd_used_voice_cb callback)
279 index = ttsd_data_is_client(uid);
282 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
283 return TTSD_ERROR_INVALID_PARAMETER;
286 if (NULL == callback) {
287 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] Used voice callback is NULL");
291 if (!g_app_list[index].m_used_voice.empty()) {
292 std::list<used_voice_s>::iterator iter;
294 for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end(); ++iter) {
295 if (NULL != callback) {
296 callback(iter->lang, iter->vctype);
299 if (NULL != iter->lang) {
305 g_app_list[index].m_used_voice.clear();
309 __data_show_used_voice_list(index);
312 return TTSD_ERROR_NONE;
315 int ttsd_data_add_speak_data(int uid, speak_data_s* data)
318 index = ttsd_data_is_client(uid);
321 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
322 return TTSD_ERROR_INVALID_PARAMETER;
325 /* mutex is locked */
326 pthread_mutex_lock(&g_speak_data_mutex);
328 std::list<speak_data_s*>::iterator iter;
331 iter = g_app_list[index].m_speak_data.insert(g_app_list[index].m_speak_data.end(), data);
332 } catch (const std::bad_alloc&) {
333 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_speak_data (bad_alloc)");
334 pthread_mutex_unlock(&g_speak_data_mutex);
336 return TTSD_ERROR_OUT_OF_MEMORY;
338 SLOG(LOG_ERROR, tts_tag(), "[DATA][%p] utt_id(%d), text(%s), lang(%s), vctype(%d), speed(%d)",
339 *iter, (*iter)->utt_id, (*iter)->text, (*iter)->lang, (*iter)->vctype, (*iter)->speed);
341 if (1 == data->utt_id)
342 g_app_list[index].utt_id_stopped = 0;
345 __data_show_text_list(index);
347 pthread_mutex_unlock(&g_speak_data_mutex);
349 return TTSD_ERROR_NONE;
352 int ttsd_data_get_speak_data(int uid, speak_data_s** data)
355 index = ttsd_data_is_client(uid);
358 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid(%d)", uid);
359 return TTSD_ERROR_INVALID_PARAMETER;
362 /* mutex is locked */
363 pthread_mutex_lock(&g_speak_data_mutex);
365 if (0 == g_app_list[index].m_speak_data.size()) {
367 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] There is no speak data");
369 pthread_mutex_unlock(&g_speak_data_mutex);
373 if (!g_app_list[index].m_speak_data.empty()) {
374 std::list<speak_data_s*>::iterator iter = g_app_list[index].m_speak_data.begin();
376 g_app_list[index].m_speak_data.pop_front();
380 __data_show_text_list(index);
382 pthread_mutex_unlock(&g_speak_data_mutex);
384 return TTSD_ERROR_NONE;
387 int ttsd_data_add_sound_data(int uid, sound_data_s* data)
390 index = ttsd_data_is_client(uid);
393 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
394 return TTSD_ERROR_INVALID_PARAMETER;
398 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] sound data is NULL");
399 return TTSD_ERROR_INVALID_PARAMETER;
401 /* mutex is locked */
402 pthread_mutex_lock(&g_sound_data_mutex);
404 std::list<sound_data_s*>::iterator iter;
407 iter = g_app_list[index].m_wav_data.insert(g_app_list[index].m_wav_data.end(), data);
408 } catch (const std::bad_alloc&) {
409 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_sound_data (bad_alloc)");
410 pthread_mutex_unlock(&g_sound_data_mutex);
412 return TTSD_ERROR_OUT_OF_MEMORY;
414 SLOG(LOG_ERROR, tts_tag(), "[DATA][%p] utt_id(%d), data(%p) data size(%d), type(%d)", *iter, (*iter)->utt_id, (*iter)->data, (*iter)->data_size, (*iter)->audio_type);
417 __data_show_sound_list(index);
420 /* mutex is unlocked */
421 pthread_mutex_unlock(&g_sound_data_mutex);
423 return TTSD_ERROR_NONE;
426 int ttsd_data_get_sound_data(int uid, sound_data_s** data)
429 index = ttsd_data_is_client(uid);
431 SLOG(LOG_DEBUG, tts_tag(), "[DATA] sound_data_s: %p", *data);
434 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
435 return TTSD_ERROR_INVALID_PARAMETER;
438 /* mutex is locked */
439 pthread_mutex_lock(&g_sound_data_mutex);
441 if (0 == g_app_list[index].m_wav_data.size()) {
443 SLOG(LOG_DEBUG, tts_tag(), "[DATA] There is no wav data");
445 /* mutex is unlocked */
446 pthread_mutex_unlock(&g_sound_data_mutex);
450 if (!g_app_list[index].m_wav_data.empty()) {
451 std::list<sound_data_s*>::iterator iter = g_app_list[index].m_wav_data.begin();
453 g_app_list[index].m_wav_data.pop_front();
457 __data_show_sound_list(index);
460 /* mutex is unlocked */
461 pthread_mutex_unlock(&g_sound_data_mutex);
463 return TTSD_ERROR_NONE;
466 int ttsd_data_get_sound_data_size(int uid)
470 index = ttsd_data_is_client(uid);
473 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
474 return TTSD_ERROR_INVALID_PARAMETER;
477 /* mutex is locked */
478 pthread_mutex_lock(&g_sound_data_mutex);
479 data_size = g_app_list[index].m_wav_data.size();
481 /* mutex is unlocked */
482 pthread_mutex_unlock(&g_sound_data_mutex);
487 int ttsd_data_clear_speak_data(speak_data_s** speak_data)
489 pthread_mutex_lock(&g_speak_data_mutex);
491 if (NULL != *speak_data) {
492 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)",
493 (*speak_data)->utt_id, (*speak_data)->text, (*speak_data)->lang, (*speak_data)->vctype, (*speak_data)->speed);
495 if (NULL != (*speak_data)->text) {
496 free((*speak_data)->text);
497 (*speak_data)->text = NULL;
499 if (NULL != (*speak_data)->lang) {
500 free((*speak_data)->lang);
501 (*speak_data)->lang = NULL;
508 pthread_mutex_unlock(&g_speak_data_mutex);
510 return TTSD_ERROR_NONE;
513 int ttsd_data_clear_sound_data(sound_data_s** sound_data)
515 pthread_mutex_lock(&g_sound_data_mutex);
517 if (NULL != *sound_data) {
518 SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] event(%d) data(%p) size(%d) rate(%d) utt(%d)",
519 (*sound_data), (*sound_data)->event, (*sound_data)->data, (*sound_data)->data_size, (*sound_data)->rate, (*sound_data)->utt_id);
521 if (NULL != (*sound_data)->data) {
522 free((*sound_data)->data);
523 (*sound_data)->data = NULL;
530 pthread_mutex_unlock(&g_sound_data_mutex);
532 return TTSD_ERROR_NONE;
535 int ttsd_data_clear_data(int uid)
539 index = ttsd_data_is_client(uid);
541 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
542 return TTSD_ERROR_INVALID_PARAMETER;
545 int removed_last_uttid = -1;
546 speak_data_s* temp_speak = NULL;
547 sound_data_s* temp_sound = NULL;
549 /* free allocated data */
551 if (0 != ttsd_data_get_speak_data(uid, &temp_speak)) {
555 pthread_mutex_lock(&g_speak_data_mutex);
556 if (NULL != temp_speak) {
557 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)",
558 temp_speak->utt_id, temp_speak->text, temp_speak->lang, temp_speak->vctype, temp_speak->speed);
560 if (NULL != temp_speak->text) {
561 free(temp_speak->text);
562 temp_speak->text = NULL;
564 if (NULL != temp_speak->lang) {
565 free(temp_speak->lang);
566 temp_speak->lang = NULL;
568 removed_last_uttid = temp_speak->utt_id;
573 pthread_mutex_unlock(&g_speak_data_mutex);
576 if (-1 != removed_last_uttid) {
577 g_app_list[index].utt_id_stopped = removed_last_uttid;
580 pthread_mutex_lock(&g_speak_data_mutex);
581 g_app_list[index].m_speak_data.clear();
582 pthread_mutex_unlock(&g_speak_data_mutex);
585 if (0 != ttsd_data_get_sound_data(uid, &temp_sound)) {
589 pthread_mutex_lock(&g_sound_data_mutex);
590 if (NULL != temp_sound) {
591 SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] uid(%d), event(%d) data(%p) size(%d) rate(%d) utt(%d)",
592 temp_sound, uid, temp_sound->event, temp_sound->data, temp_sound->data_size, temp_sound->rate, temp_sound->utt_id);
594 if (NULL != temp_sound->data) {
595 free(temp_sound->data);
596 temp_sound->data = NULL;
602 pthread_mutex_unlock(&g_sound_data_mutex);
605 pthread_mutex_lock(&g_sound_data_mutex);
606 g_app_list[index].m_wav_data.clear();
607 pthread_mutex_unlock(&g_sound_data_mutex);
609 return TTSD_ERROR_NONE;
612 int ttsd_data_get_client_state(int uid, app_tts_state_e* state)
616 index = ttsd_data_is_client(uid);
618 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
619 return TTSD_ERROR_INVALID_PARAMETER;
622 *state = g_app_list[index].state;
624 return TTSD_ERROR_NONE;
627 int ttsd_data_set_client_state(int uid, app_tts_state_e state)
631 index = ttsd_data_is_client(uid);
633 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
634 return TTSD_ERROR_INVALID_PARAMETER;
637 /* The client of playing state of all clients is only one. need to check state. */
638 if (APP_STATE_PLAYING == state) {
639 int vsize = g_app_list.size();
640 for (int i = 0; i < vsize; i++) {
641 if(g_app_list[i].state == APP_STATE_PLAYING) {
642 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] A playing client has already existed.");
648 g_app_list[index].state = state;
650 return TTSD_ERROR_NONE;
653 int ttsd_data_get_current_playing()
655 int vsize = g_app_list.size();
657 for (int i = 0; i < vsize; i++) {
658 if (APP_STATE_PLAYING == g_app_list[i].state) {
659 SLOG(LOG_DEBUG, tts_tag(), "[DATA] uid(%d) is playing", g_app_list[i].uid);
660 return g_app_list[i].uid;
667 int ttsd_data_foreach_clients(ttsd_data_get_client_cb callback, void* user_data)
669 if (NULL == callback) {
670 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] input data is NULL!!");
679 vector<app_data_s> temp_app_list;
680 int vsize = g_app_list.size();
683 for (i = 0;i < vsize;i++) {
685 app.pid = g_app_list[i].pid;
686 app.uid = g_app_list[i].uid;
687 app.utt_id_stopped = 0;
688 app.state = g_app_list[i].state;
690 temp_app_list.insert(temp_app_list.end(), app);
693 for (i = 0;i < vsize;i++) {
694 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);
695 if (false == callback(temp_app_list[i].pid, temp_app_list[i].uid, temp_app_list[i].state, user_data)) {
700 for (i = 0;i < vsize;i++) {
701 temp_app_list.erase(temp_app_list.begin());
707 bool ttsd_data_is_uttid_valid(int uid, int uttid)
711 index = ttsd_data_is_client(uid);
713 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
717 if (uttid < g_app_list[index].utt_id_stopped)
723 int ttsd_data_is_current_playing()
725 int vsize = g_app_list.size();
727 for (int i = 0; i < vsize; i++) {
728 if(g_app_list[i].state == APP_STATE_PLAYING) {
729 return g_app_list[i].uid;
736 int ttsd_data_get_same_pid_client_count(int pid)
738 int vsize = g_app_list.size();
741 for (int i = 0;i < vsize;i++) {
742 if(g_app_list[i].pid == pid) {
750 int ttsd_data_save_error_log(int uid, FILE* fp)
755 pid = ttsd_data_get_pid(uid);
757 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get pid");
759 fprintf(fp, "pid - %d", pid);
762 app_tts_state_e state;
763 ret = ttsd_data_get_client_state(uid, &state);
765 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get app state");
767 fprintf(fp, "app state - %d", state);
773 index = ttsd_data_is_client(uid);
775 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid client");
780 fprintf(fp, "----- Sound list -----");
783 if (!g_app_list[index].m_wav_data.empty()) {
784 std::list<sound_data_s*>::iterator iter;
785 for (iter = g_app_list[index].m_wav_data.begin(); (NULL != *iter && iter != g_app_list[index].m_wav_data.end()); ++iter) {
786 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%d), uttid(%d), type(%d)",
787 i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
792 fprintf(fp, "----------------------");
795 fprintf(fp, "----- Text list -----");
798 if (!g_app_list[index].m_speak_data.empty()) {
799 std::list<speak_data_s*>::iterator iter_speak;
800 for (iter_speak = g_app_list[index].m_speak_data.begin(); (NULL != *iter_speak && iter_speak != g_app_list[index].m_speak_data.end()); ++iter_speak) {
801 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)",
802 i, *iter_speak, (*iter_speak)->lang, (*iter_speak)->vctype, (*iter_speak)->speed, (*iter_speak)->utt_id, (*iter_speak)->text);
806 fprintf(fp, "---------------------");