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;
48 /* If engine is running */
49 static ttsd_synthesis_control_e g_synth_control;
54 int __data_show_list()
56 int vsize = g_app_list.size();
58 SLOG(LOG_DEBUG, tts_tag(), "----- client list -----");
60 for (int i=0; i < vsize; i++) {
61 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);
65 SLOG(LOG_DEBUG, tts_tag(), "No Client");
68 SLOG(LOG_DEBUG, tts_tag(), "-----------------------");
70 return TTSD_ERROR_NONE;
73 int __data_show_sound_list(int index)
75 SLOG(LOG_DEBUG, tts_tag(), "----- Sound list -----");
78 if (!g_app_list[index].m_wav_data.empty()) {
79 std::list<sound_data_s*>::iterator iter;
80 for (iter = g_app_list[index].m_wav_data.begin(); (NULL != *iter && iter != g_app_list[index].m_wav_data.end()); ++iter) {
81 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%d), uttid(%d), type(%d)",
82 i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
88 SLOG(LOG_DEBUG, tts_tag(), "No Sound Data");
91 SLOG(LOG_DEBUG, tts_tag(), "----------------------");
92 return TTSD_ERROR_NONE;
95 int __data_show_text_list(int index)
97 SLOG(LOG_DEBUG, tts_tag(), "----- Text list -----");
100 if (!g_app_list[index].m_speak_data.empty()) {
101 std::list<speak_data_s*>::iterator iter;
102 for (iter = g_app_list[index].m_speak_data.begin(); (NULL != *iter && iter != g_app_list[index].m_speak_data.end()); ++iter) {
103 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)",
104 i + 1, *iter, (*iter)->lang, (*iter)->vctype, (*iter)->speed, (*iter)->utt_id, (*iter)->text);
110 SLOG(LOG_DEBUG, tts_tag(), "No Text Data");
113 SLOG(LOG_DEBUG, tts_tag(), "---------------------");
114 return TTSD_ERROR_NONE;
117 int __data_show_used_voice_list(int index)
119 SLOG(LOG_DEBUG, tts_tag(), "----- Used voice list -----");
122 if (!g_app_list[index].m_used_voice.empty()) {
123 std::list<used_voice_s>::iterator iter;
124 for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end(); ++iter) {
125 SLOG(LOG_DEBUG, tts_tag(), "[%dth] lang(%s), vctype(%d)", i + 1, iter->lang, iter->vctype);
131 SLOG(LOG_DEBUG, tts_tag(), "No Voice Data");
134 SLOG(LOG_DEBUG, tts_tag(), "---------------------------");
135 return TTSD_ERROR_NONE;
139 * ttsd data functions
142 int ttsd_set_synth_control(ttsd_synthesis_control_e control)
144 g_synth_control = control;
148 ttsd_synthesis_control_e ttsd_get_synth_control()
150 return g_synth_control;
153 int ttsd_data_new_client(int pid, int uid)
155 if( -1 != ttsd_data_is_client(uid) ) {
156 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
157 return TTSD_ERROR_INVALID_PARAMETER;
163 app.utt_id_stopped = 0;
164 app.state = APP_STATE_READY;
166 g_app_list.insert(g_app_list.end(), app);
171 return TTSD_ERROR_NONE;
174 int ttsd_data_delete_client(int uid)
178 index = ttsd_data_is_client(uid);
181 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
185 if (0 != ttsd_data_clear_data(uid)) {
186 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] Fail to clear data");
190 g_app_list.erase(g_app_list.begin()+index);
195 return TTSD_ERROR_NONE;
198 int ttsd_data_is_client(int uid)
200 int vsize = g_app_list.size();
202 for (int i = 0; i < vsize; i++) {
203 if(g_app_list[i].uid == uid) {
211 int ttsd_data_get_client_count()
213 return g_app_list.size();
216 int ttsd_data_get_pid(int uid)
220 index = ttsd_data_is_client(uid);
223 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
224 return TTSD_ERROR_INVALID_PARAMETER;
227 return g_app_list[index].pid;
230 int ttsd_data_get_speak_data_size(int uid)
233 index = ttsd_data_is_client(uid);
236 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
237 return TTSD_ERROR_INVALID_PARAMETER;
240 /* mutex is locked */
241 pthread_mutex_lock(&g_speak_data_mutex);
242 int size = g_app_list[index].m_speak_data.size();
244 /* mutex is unlocked */
245 pthread_mutex_unlock(&g_speak_data_mutex);
250 int ttsd_data_set_used_voice(int uid, const char* lang, int type)
253 index = ttsd_data_is_client(uid);
256 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
257 return TTSD_ERROR_INVALID_PARAMETER;
261 std::list<used_voice_s>::iterator iter;
262 if (!g_app_list[index].m_used_voice.empty()) {
263 for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end();++iter) {
264 if (0 == strcmp(lang, iter->lang) && type == iter->vctype) {
265 SLOG(LOG_DEBUG, tts_tag(), "[DATA] The voice is already registered (%s)(%d)", lang, type);
272 used_voice_s used_voice;
273 used_voice.lang = strdup(lang);
274 used_voice.vctype = type;
277 iter = g_app_list[index].m_used_voice.insert(g_app_list[index].m_used_voice.end(), used_voice);
278 } catch (const std::bad_alloc&) {
279 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_used_voice (bad_alloc)");
282 SLOG(LOG_ERROR, tts_tag(), "[DATA] lang(%s), vctype(%d)", iter->lang, iter->vctype);
285 __data_show_used_voice_list(index);
288 return -1; /* Need to load voice*/
291 int ttsd_data_reset_used_voice(int uid, ttsd_used_voice_cb callback)
294 index = ttsd_data_is_client(uid);
297 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
298 return TTSD_ERROR_INVALID_PARAMETER;
301 if (NULL == callback) {
302 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] Used voice callback is NULL");
306 if (!g_app_list[index].m_used_voice.empty()) {
307 std::list<used_voice_s>::iterator iter;
309 for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end(); ++iter) {
310 if (NULL != callback) {
311 callback(iter->lang, iter->vctype);
314 if (NULL != iter->lang) {
320 g_app_list[index].m_used_voice.clear();
324 __data_show_used_voice_list(index);
327 return TTSD_ERROR_NONE;
330 int ttsd_data_add_speak_data(int uid, speak_data_s* data)
333 index = ttsd_data_is_client(uid);
336 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
337 return TTSD_ERROR_INVALID_PARAMETER;
340 /* mutex is locked */
341 pthread_mutex_lock(&g_speak_data_mutex);
343 std::list<speak_data_s*>::iterator iter;
346 iter = g_app_list[index].m_speak_data.insert(g_app_list[index].m_speak_data.end(), data);
347 } catch (const std::bad_alloc&) {
348 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_speak_data (bad_alloc)");
349 pthread_mutex_unlock(&g_speak_data_mutex);
351 return TTSD_ERROR_OUT_OF_MEMORY;
353 SLOG(LOG_ERROR, tts_tag(), "[DATA][%p] utt_id(%d), text(%s), lang(%s), vctype(%d), speed(%d)",
354 *iter, (*iter)->utt_id, (*iter)->text, (*iter)->lang, (*iter)->vctype, (*iter)->speed);
356 if (1 == data->utt_id)
357 g_app_list[index].utt_id_stopped = 0;
360 __data_show_text_list(index);
362 pthread_mutex_unlock(&g_speak_data_mutex);
364 return TTSD_ERROR_NONE;
367 int __get_speak_data(int index, speak_data_s** data)
369 if (0 == g_app_list[index].m_speak_data.size()) {
371 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] There is no speak data");
376 if (!g_app_list[index].m_speak_data.empty()) {
377 std::list<speak_data_s*>::iterator iter = g_app_list[index].m_speak_data.begin();
379 g_app_list[index].m_speak_data.pop_front();
383 __data_show_text_list(index);
388 int ttsd_data_get_speak_data(int uid, speak_data_s** data)
391 index = ttsd_data_is_client(uid);
394 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid(%d)", uid);
395 return TTSD_ERROR_INVALID_PARAMETER;
398 /* mutex is locked */
399 pthread_mutex_lock(&g_speak_data_mutex);
401 if (0 != __get_speak_data(index, data)) {
402 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] There is no speak data");
403 pthread_mutex_unlock(&g_speak_data_mutex);
407 pthread_mutex_unlock(&g_speak_data_mutex);
409 return TTSD_ERROR_NONE;
412 int ttsd_data_add_sound_data(int uid, sound_data_s* data)
415 index = ttsd_data_is_client(uid);
418 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
419 return TTSD_ERROR_INVALID_PARAMETER;
423 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] sound data is NULL");
424 return TTSD_ERROR_INVALID_PARAMETER;
426 /* mutex is locked */
427 pthread_mutex_lock(&g_sound_data_mutex);
429 std::list<sound_data_s*>::iterator iter;
432 iter = g_app_list[index].m_wav_data.insert(g_app_list[index].m_wav_data.end(), data);
433 } catch (const std::bad_alloc&) {
434 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_sound_data (bad_alloc)");
435 pthread_mutex_unlock(&g_sound_data_mutex);
437 return TTSD_ERROR_OUT_OF_MEMORY;
439 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);
442 __data_show_sound_list(index);
445 /* mutex is unlocked */
446 pthread_mutex_unlock(&g_sound_data_mutex);
448 return TTSD_ERROR_NONE;
451 int __get_sound_data(int index, sound_data_s** data)
453 if (0 == g_app_list[index].m_wav_data.size()) {
455 SLOG(LOG_DEBUG, tts_tag(), "[DATA] There is no wav data");
457 /* mutex is unlocked */
458 pthread_mutex_unlock(&g_sound_data_mutex);
462 if (!g_app_list[index].m_wav_data.empty()) {
463 std::list<sound_data_s*>::iterator iter = g_app_list[index].m_wav_data.begin();
465 g_app_list[index].m_wav_data.pop_front();
469 __data_show_sound_list(index);
474 int ttsd_data_get_sound_data(int uid, sound_data_s** data)
477 index = ttsd_data_is_client(uid);
479 SLOG(LOG_DEBUG, tts_tag(), "[DATA] sound_data_s: %p", *data);
482 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
483 return TTSD_ERROR_INVALID_PARAMETER;
486 /* mutex is locked */
487 pthread_mutex_lock(&g_sound_data_mutex);
489 if (0 != __get_sound_data(index, data)) {
490 SLOG(LOG_DEBUG, tts_tag(), "[DATA] There is no wav data");
491 /* mutex is unlocked */
492 pthread_mutex_unlock(&g_sound_data_mutex);
495 /* mutex is unlocked */
496 pthread_mutex_unlock(&g_sound_data_mutex);
498 return TTSD_ERROR_NONE;
501 int ttsd_data_get_sound_data_size(int uid)
505 index = ttsd_data_is_client(uid);
508 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
509 return TTSD_ERROR_INVALID_PARAMETER;
512 /* mutex is locked */
513 pthread_mutex_lock(&g_sound_data_mutex);
514 data_size = g_app_list[index].m_wav_data.size();
516 /* mutex is unlocked */
517 pthread_mutex_unlock(&g_sound_data_mutex);
522 int ttsd_data_clear_speak_data(int uid, speak_data_s** speak_data)
524 pthread_mutex_lock(&g_speak_data_mutex);
527 index = ttsd_data_is_client(uid);
529 if (!g_app_list[index].m_speak_data.empty()) {
530 if (NULL != *speak_data) {
531 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)",
532 (*speak_data)->utt_id, (*speak_data)->text, (*speak_data)->lang, (*speak_data)->vctype, (*speak_data)->speed);
534 if (NULL != (*speak_data)->text) {
535 free((*speak_data)->text);
536 (*speak_data)->text = NULL;
538 if (NULL != (*speak_data)->lang) {
539 free((*speak_data)->lang);
540 (*speak_data)->lang = NULL;
549 pthread_mutex_unlock(&g_speak_data_mutex);
551 return TTSD_ERROR_NONE;
554 int ttsd_data_clear_sound_data(int uid, sound_data_s** sound_data)
556 pthread_mutex_lock(&g_sound_data_mutex);
559 index = ttsd_data_is_client(uid);
561 if (!g_app_list[index].m_wav_data.empty()) {
562 if (NULL != *sound_data) {
563 SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] event(%d) data(%p) size(%d) rate(%d) utt(%d)",
564 (*sound_data), (*sound_data)->event, (*sound_data)->data, (*sound_data)->data_size, (*sound_data)->rate, (*sound_data)->utt_id);
566 if (NULL != (*sound_data)->data) {
567 free((*sound_data)->data);
568 (*sound_data)->data = NULL;
576 pthread_mutex_unlock(&g_sound_data_mutex);
578 return TTSD_ERROR_NONE;
581 int ttsd_data_clear_data(int uid)
585 index = ttsd_data_is_client(uid);
587 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
588 return TTSD_ERROR_INVALID_PARAMETER;
591 int removed_last_uttid = -1;
592 speak_data_s* temp_speak = NULL;
593 sound_data_s* temp_sound = NULL;
595 /* free allocated data */
596 pthread_mutex_lock(&g_speak_data_mutex);
598 if (0 != __get_speak_data(index, &temp_speak)) {
602 if (NULL != temp_speak) {
603 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)",
604 temp_speak->utt_id, temp_speak->text, temp_speak->lang, temp_speak->vctype, temp_speak->speed);
606 if (NULL != temp_speak->text) {
607 free(temp_speak->text);
608 temp_speak->text = NULL;
610 if (NULL != temp_speak->lang) {
611 free(temp_speak->lang);
612 temp_speak->lang = NULL;
614 removed_last_uttid = temp_speak->utt_id;
621 if (-1 != removed_last_uttid) {
622 g_app_list[index].utt_id_stopped = removed_last_uttid;
625 g_app_list[index].m_speak_data.clear();
626 pthread_mutex_unlock(&g_speak_data_mutex);
628 pthread_mutex_lock(&g_sound_data_mutex);
630 if (0 != __get_sound_data(index, &temp_sound)) {
634 if (NULL != temp_sound) {
635 SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] uid(%d), event(%d) data(%p) size(%d) rate(%d) utt(%d)",
636 temp_sound, uid, temp_sound->event, temp_sound->data, temp_sound->data_size, temp_sound->rate, temp_sound->utt_id);
638 if (NULL != temp_sound->data) {
639 free(temp_sound->data);
640 temp_sound->data = NULL;
648 g_app_list[index].m_wav_data.clear();
649 pthread_mutex_unlock(&g_sound_data_mutex);
651 return TTSD_ERROR_NONE;
654 int ttsd_data_get_client_state(int uid, app_tts_state_e* state)
658 index = ttsd_data_is_client(uid);
660 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
661 return TTSD_ERROR_INVALID_PARAMETER;
664 *state = g_app_list[index].state;
666 return TTSD_ERROR_NONE;
669 int ttsd_data_set_client_state(int uid, app_tts_state_e state)
673 index = ttsd_data_is_client(uid);
675 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
676 return TTSD_ERROR_INVALID_PARAMETER;
679 /* The client of playing state of all clients is only one. need to check state. */
680 if (APP_STATE_PLAYING == state) {
681 int vsize = g_app_list.size();
682 for (int i = 0; i < vsize; i++) {
683 if(g_app_list[i].state == APP_STATE_PLAYING) {
684 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] A playing client has already existed.");
690 g_app_list[index].state = state;
692 return TTSD_ERROR_NONE;
695 int ttsd_data_get_current_playing()
697 int vsize = g_app_list.size();
699 for (int i = 0; i < vsize; i++) {
700 if (APP_STATE_PLAYING == g_app_list[i].state) {
701 SLOG(LOG_DEBUG, tts_tag(), "[DATA] uid(%d) is playing", g_app_list[i].uid);
702 return g_app_list[i].uid;
709 int ttsd_data_foreach_clients(ttsd_data_get_client_cb callback, void* user_data)
711 if (NULL == callback) {
712 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] input data is NULL!!");
721 vector<app_data_s> temp_app_list;
722 int vsize = g_app_list.size();
725 for (i = 0;i < vsize;i++) {
727 app.pid = g_app_list[i].pid;
728 app.uid = g_app_list[i].uid;
729 app.utt_id_stopped = 0;
730 app.state = g_app_list[i].state;
732 temp_app_list.insert(temp_app_list.end(), app);
735 for (i = 0;i < vsize;i++) {
736 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);
737 if (false == callback(temp_app_list[i].pid, temp_app_list[i].uid, temp_app_list[i].state, user_data)) {
742 for (i = 0;i < vsize;i++) {
743 temp_app_list.erase(temp_app_list.begin());
749 bool ttsd_data_is_uttid_valid(int uid, int uttid)
753 index = ttsd_data_is_client(uid);
755 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
759 if (uttid < g_app_list[index].utt_id_stopped)
765 int ttsd_data_is_current_playing()
767 int vsize = g_app_list.size();
769 for (int i = 0; i < vsize; i++) {
770 if(g_app_list[i].state == APP_STATE_PLAYING) {
771 return g_app_list[i].uid;
778 int ttsd_data_get_same_pid_client_count(int pid)
780 int vsize = g_app_list.size();
783 for (int i = 0;i < vsize;i++) {
784 if(g_app_list[i].pid == pid) {
792 int ttsd_data_save_error_log(int uid, FILE* fp)
797 pid = ttsd_data_get_pid(uid);
799 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get pid");
801 fprintf(fp, "pid - %d", pid);
804 app_tts_state_e state;
805 ret = ttsd_data_get_client_state(uid, &state);
807 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get app state");
809 fprintf(fp, "app state - %d", state);
815 index = ttsd_data_is_client(uid);
817 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid client");
822 fprintf(fp, "----- Sound list -----");
825 if (!g_app_list[index].m_wav_data.empty()) {
826 std::list<sound_data_s*>::iterator iter;
827 for (iter = g_app_list[index].m_wav_data.begin(); (NULL != *iter && iter != g_app_list[index].m_wav_data.end()); ++iter) {
828 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%d), uttid(%d), type(%d)",
829 i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
834 fprintf(fp, "----------------------");
837 fprintf(fp, "----- Text list -----");
840 if (!g_app_list[index].m_speak_data.empty()) {
841 std::list<speak_data_s*>::iterator iter_speak;
842 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) {
843 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)",
844 i, *iter_speak, (*iter_speak)->lang, (*iter_speak)->vctype, (*iter_speak)->speed, (*iter_speak)->utt_id, (*iter_speak)->text);
848 fprintf(fp, "---------------------");