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;
47 /* If engine is running */
48 static ttsd_synthesis_control_e g_synth_control;
53 int __data_show_list()
55 int vsize = g_app_list.size();
57 SLOG(LOG_DEBUG, tts_tag(), "----- client list -----");
59 for (int i=0; i < vsize; i++) {
60 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);
64 SLOG(LOG_DEBUG, tts_tag(), "No Client");
67 SLOG(LOG_DEBUG, tts_tag(), "-----------------------");
69 return TTSD_ERROR_NONE;
72 int __data_show_sound_list(int index)
74 SLOG(LOG_DEBUG, tts_tag(), "----- Sound list -----");
77 if (!g_app_list[index].m_wav_data.empty()) {
78 std::list<sound_data_s*>::iterator iter;
79 for (iter = g_app_list[index].m_wav_data.begin(); (NULL != *iter && iter != g_app_list[index].m_wav_data.end()); ++iter) {
80 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%d), uttid(%d), type(%d)",
81 i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
87 SLOG(LOG_DEBUG, tts_tag(), "No Sound Data");
90 SLOG(LOG_DEBUG, tts_tag(), "----------------------");
91 return TTSD_ERROR_NONE;
94 int __data_show_text_list(int index)
96 SLOG(LOG_DEBUG, tts_tag(), "----- Text list -----");
99 if (!g_app_list[index].m_speak_data.empty()) {
100 std::list<speak_data_s*>::iterator iter;
101 for (iter = g_app_list[index].m_speak_data.begin(); (NULL != *iter && iter != g_app_list[index].m_speak_data.end()); ++iter) {
102 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)",
103 i + 1, *iter, (*iter)->lang, (*iter)->vctype, (*iter)->speed, (*iter)->utt_id, (*iter)->text);
109 SLOG(LOG_DEBUG, tts_tag(), "No Text Data");
112 SLOG(LOG_DEBUG, tts_tag(), "---------------------");
113 return TTSD_ERROR_NONE;
116 int __data_show_used_voice_list(int index)
118 SLOG(LOG_DEBUG, tts_tag(), "----- Used voice list -----");
121 if (!g_app_list[index].m_used_voice.empty()) {
122 std::list<used_voice_s>::iterator iter;
123 for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end(); ++iter) {
124 SLOG(LOG_DEBUG, tts_tag(), "[%dth] lang(%s), vctype(%d)", i + 1, iter->lang, iter->vctype);
130 SLOG(LOG_DEBUG, tts_tag(), "No Voice Data");
133 SLOG(LOG_DEBUG, tts_tag(), "---------------------------");
134 return TTSD_ERROR_NONE;
138 * ttsd data functions
141 int ttsd_set_synth_control(ttsd_synthesis_control_e control)
143 g_synth_control = control;
147 ttsd_synthesis_control_e ttsd_get_synth_control()
149 return g_synth_control;
152 int ttsd_data_new_client(int pid, int uid)
154 if( -1 != ttsd_data_is_client(uid) ) {
155 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
156 return TTSD_ERROR_INVALID_PARAMETER;
162 app.utt_id_stopped = 0;
163 app.state = APP_STATE_READY;
165 g_app_list.insert(g_app_list.end(), app);
170 return TTSD_ERROR_NONE;
173 int ttsd_data_delete_client(int uid)
177 index = ttsd_data_is_client(uid);
180 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
184 if (0 != ttsd_data_clear_data(uid)) {
185 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] Fail to clear data");
189 g_app_list.erase(g_app_list.begin()+index);
194 return TTSD_ERROR_NONE;
197 int ttsd_data_is_client(int uid)
199 int vsize = g_app_list.size();
201 for (int i = 0; i < vsize; i++) {
202 if(g_app_list[i].uid == uid) {
210 int ttsd_data_get_client_count()
212 return g_app_list.size();
215 int ttsd_data_get_pid(int uid)
219 index = ttsd_data_is_client(uid);
222 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
223 return TTSD_ERROR_INVALID_PARAMETER;
226 return g_app_list[index].pid;
229 int ttsd_data_get_speak_data_size(int uid)
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;
239 /* mutex is locked */
240 pthread_mutex_lock(&g_speak_data_mutex);
241 int size = g_app_list[index].m_speak_data.size();
243 /* mutex is unlocked */
244 pthread_mutex_unlock(&g_speak_data_mutex);
249 int ttsd_data_set_used_voice(int uid, const char* lang, int type)
252 index = ttsd_data_is_client(uid);
255 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
256 return TTSD_ERROR_INVALID_PARAMETER;
260 std::list<used_voice_s>::iterator iter;
261 if (!g_app_list[index].m_used_voice.empty()) {
262 for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end();++iter) {
263 if (0 == strcmp(lang, iter->lang) && type == iter->vctype) {
264 SLOG(LOG_DEBUG, tts_tag(), "[DATA] The voice is already registered (%s)(%d)", lang, type);
271 used_voice_s used_voice;
272 used_voice.lang = strdup(lang);
273 used_voice.vctype = type;
276 iter = g_app_list[index].m_used_voice.insert(g_app_list[index].m_used_voice.end(), used_voice);
277 } catch (const std::bad_alloc&) {
278 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_used_voice (bad_alloc)");
281 SLOG(LOG_ERROR, tts_tag(), "[DATA] lang(%s), vctype(%d)", iter->lang, iter->vctype);
284 __data_show_used_voice_list(index);
287 return -1; /* Need to load voice*/
290 int ttsd_data_reset_used_voice(int uid, ttsd_used_voice_cb callback)
293 index = ttsd_data_is_client(uid);
296 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
297 return TTSD_ERROR_INVALID_PARAMETER;
300 if (NULL == callback) {
301 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] Used voice callback is NULL");
305 if (!g_app_list[index].m_used_voice.empty()) {
306 std::list<used_voice_s>::iterator iter;
308 for (iter = g_app_list[index].m_used_voice.begin(); iter != g_app_list[index].m_used_voice.end(); ++iter) {
309 if (NULL != callback) {
310 callback(iter->lang, iter->vctype);
313 if (NULL != iter->lang) {
319 g_app_list[index].m_used_voice.clear();
323 __data_show_used_voice_list(index);
326 return TTSD_ERROR_NONE;
329 int ttsd_data_add_speak_data(int uid, speak_data_s* data)
332 index = ttsd_data_is_client(uid);
335 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
336 return TTSD_ERROR_INVALID_PARAMETER;
339 /* mutex is locked */
340 pthread_mutex_lock(&g_speak_data_mutex);
342 std::list<speak_data_s*>::iterator iter;
345 iter = g_app_list[index].m_speak_data.insert(g_app_list[index].m_speak_data.end(), data);
346 } catch (const std::bad_alloc&) {
347 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_speak_data (bad_alloc)");
348 pthread_mutex_unlock(&g_speak_data_mutex);
350 return TTSD_ERROR_OUT_OF_MEMORY;
352 SLOG(LOG_ERROR, tts_tag(), "[DATA][%p] utt_id(%d), text(%s), lang(%s), vctype(%d), speed(%d)",
353 *iter, (*iter)->utt_id, (*iter)->text, (*iter)->lang, (*iter)->vctype, (*iter)->speed);
355 if (1 == data->utt_id)
356 g_app_list[index].utt_id_stopped = 0;
359 __data_show_text_list(index);
361 pthread_mutex_unlock(&g_speak_data_mutex);
363 return TTSD_ERROR_NONE;
366 int ttsd_data_get_speak_data(int uid, speak_data_s** data)
369 index = ttsd_data_is_client(uid);
372 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid(%d)", uid);
373 return TTSD_ERROR_INVALID_PARAMETER;
376 /* mutex is locked */
377 pthread_mutex_lock(&g_speak_data_mutex);
379 if (0 == g_app_list[index].m_speak_data.size()) {
381 SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] There is no speak data");
383 pthread_mutex_unlock(&g_speak_data_mutex);
387 if (!g_app_list[index].m_speak_data.empty()) {
388 std::list<speak_data_s*>::iterator iter = g_app_list[index].m_speak_data.begin();
390 g_app_list[index].m_speak_data.pop_front();
394 __data_show_text_list(index);
396 pthread_mutex_unlock(&g_speak_data_mutex);
398 return TTSD_ERROR_NONE;
401 int ttsd_data_add_sound_data(int uid, sound_data_s* data)
404 index = ttsd_data_is_client(uid);
407 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
408 return TTSD_ERROR_INVALID_PARAMETER;
412 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] sound data is NULL");
413 return TTSD_ERROR_INVALID_PARAMETER;
415 /* mutex is locked */
416 pthread_mutex_lock(&g_sound_data_mutex);
418 std::list<sound_data_s*>::iterator iter;
421 iter = g_app_list[index].m_wav_data.insert(g_app_list[index].m_wav_data.end(), data);
422 } catch (const std::bad_alloc&) {
423 SLOG(LOG_ERROR, tts_tag(), "[DATA][ERROR] Fail to insert m_sound_data (bad_alloc)");
424 pthread_mutex_unlock(&g_sound_data_mutex);
426 return TTSD_ERROR_OUT_OF_MEMORY;
428 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);
431 __data_show_sound_list(index);
434 /* mutex is unlocked */
435 pthread_mutex_unlock(&g_sound_data_mutex);
437 return TTSD_ERROR_NONE;
440 int ttsd_data_get_sound_data(int uid, sound_data_s** data)
443 index = ttsd_data_is_client(uid);
445 SLOG(LOG_DEBUG, tts_tag(), "[DATA] sound_data_s: %p", *data);
448 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
449 return TTSD_ERROR_INVALID_PARAMETER;
452 /* mutex is locked */
453 pthread_mutex_lock(&g_sound_data_mutex);
455 if (0 == g_app_list[index].m_wav_data.size()) {
457 SLOG(LOG_DEBUG, tts_tag(), "[DATA] There is no wav data");
459 /* mutex is unlocked */
460 pthread_mutex_unlock(&g_sound_data_mutex);
464 if (!g_app_list[index].m_wav_data.empty()) {
465 std::list<sound_data_s*>::iterator iter = g_app_list[index].m_wav_data.begin();
467 g_app_list[index].m_wav_data.pop_front();
471 __data_show_sound_list(index);
474 /* mutex is unlocked */
475 pthread_mutex_unlock(&g_sound_data_mutex);
477 return TTSD_ERROR_NONE;
480 int ttsd_data_get_sound_data_size(int uid)
484 index = ttsd_data_is_client(uid);
487 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
488 return TTSD_ERROR_INVALID_PARAMETER;
491 /* mutex is locked */
492 pthread_mutex_lock(&g_sound_data_mutex);
493 data_size = g_app_list[index].m_wav_data.size();
495 /* mutex is unlocked */
496 pthread_mutex_unlock(&g_sound_data_mutex);
501 int ttsd_data_clear_speak_data(speak_data_s** speak_data)
503 pthread_mutex_lock(&g_speak_data_mutex);
505 if (NULL != *speak_data) {
506 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)",
507 (*speak_data)->utt_id, (*speak_data)->text, (*speak_data)->lang, (*speak_data)->vctype, (*speak_data)->speed);
509 if (NULL != (*speak_data)->text) {
510 free((*speak_data)->text);
511 (*speak_data)->text = NULL;
513 if (NULL != (*speak_data)->lang) {
514 free((*speak_data)->lang);
515 (*speak_data)->lang = NULL;
522 pthread_mutex_unlock(&g_speak_data_mutex);
524 return TTSD_ERROR_NONE;
527 int ttsd_data_clear_sound_data(sound_data_s** sound_data)
529 pthread_mutex_lock(&g_sound_data_mutex);
531 if (NULL != *sound_data) {
532 SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] event(%d) data(%p) size(%d) rate(%d) utt(%d)",
533 (*sound_data), (*sound_data)->event, (*sound_data)->data, (*sound_data)->data_size, (*sound_data)->rate, (*sound_data)->utt_id);
535 if (NULL != (*sound_data)->data) {
536 free((*sound_data)->data);
537 (*sound_data)->data = NULL;
544 pthread_mutex_unlock(&g_sound_data_mutex);
546 return TTSD_ERROR_NONE;
549 int ttsd_data_clear_data(int uid)
553 index = ttsd_data_is_client(uid);
555 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
556 return TTSD_ERROR_INVALID_PARAMETER;
559 int removed_last_uttid = -1;
560 speak_data_s* temp_speak = NULL;
561 sound_data_s* temp_sound = NULL;
563 /* free allocated data */
565 if (0 != ttsd_data_get_speak_data(uid, &temp_speak)) {
569 pthread_mutex_lock(&g_speak_data_mutex);
570 if (NULL != temp_speak) {
571 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] utt(%d), text(%s), lang(%s), vctype(%d) speed(%d)",
572 temp_speak->utt_id, temp_speak->text, temp_speak->lang, temp_speak->vctype, temp_speak->speed);
574 if (NULL != temp_speak->text) {
575 free(temp_speak->text);
576 temp_speak->text = NULL;
578 if (NULL != temp_speak->lang) {
579 free(temp_speak->lang);
580 temp_speak->lang = NULL;
582 removed_last_uttid = temp_speak->utt_id;
587 pthread_mutex_unlock(&g_speak_data_mutex);
590 if (-1 != removed_last_uttid) {
591 g_app_list[index].utt_id_stopped = removed_last_uttid;
594 pthread_mutex_lock(&g_speak_data_mutex);
595 g_app_list[index].m_speak_data.clear();
596 pthread_mutex_unlock(&g_speak_data_mutex);
599 if (0 != ttsd_data_get_sound_data(uid, &temp_sound)) {
603 pthread_mutex_lock(&g_sound_data_mutex);
604 if (NULL != temp_sound) {
605 SLOG(LOG_ERROR, tts_tag(), "[DEBUG][%p] uid(%d), event(%d) data(%p) size(%d) rate(%d) utt(%d)",
606 temp_sound, uid, temp_sound->event, temp_sound->data, temp_sound->data_size, temp_sound->rate, temp_sound->utt_id);
608 if (NULL != temp_sound->data) {
609 free(temp_sound->data);
610 temp_sound->data = NULL;
616 pthread_mutex_unlock(&g_sound_data_mutex);
619 pthread_mutex_lock(&g_sound_data_mutex);
620 g_app_list[index].m_wav_data.clear();
621 pthread_mutex_unlock(&g_sound_data_mutex);
623 return TTSD_ERROR_NONE;
626 int ttsd_data_get_client_state(int uid, app_tts_state_e* state)
630 index = ttsd_data_is_client(uid);
632 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
633 return TTSD_ERROR_INVALID_PARAMETER;
636 *state = g_app_list[index].state;
638 return TTSD_ERROR_NONE;
641 int ttsd_data_set_client_state(int uid, app_tts_state_e state)
645 index = ttsd_data_is_client(uid);
647 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
648 return TTSD_ERROR_INVALID_PARAMETER;
651 /* The client of playing state of all clients is only one. need to check state. */
652 if (APP_STATE_PLAYING == state) {
653 int vsize = g_app_list.size();
654 for (int i = 0; i < vsize; i++) {
655 if(g_app_list[i].state == APP_STATE_PLAYING) {
656 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] A playing client has already existed.");
662 g_app_list[index].state = state;
664 return TTSD_ERROR_NONE;
667 int ttsd_data_get_current_playing()
669 int vsize = g_app_list.size();
671 for (int i = 0; i < vsize; i++) {
672 if (APP_STATE_PLAYING == g_app_list[i].state) {
673 SLOG(LOG_DEBUG, tts_tag(), "[DATA] uid(%d) is playing", g_app_list[i].uid);
674 return g_app_list[i].uid;
681 int ttsd_data_foreach_clients(ttsd_data_get_client_cb callback, void* user_data)
683 if (NULL == callback) {
684 SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] input data is NULL!!");
693 vector<app_data_s> temp_app_list;
694 int vsize = g_app_list.size();
697 for (i = 0;i < vsize;i++) {
699 app.pid = g_app_list[i].pid;
700 app.uid = g_app_list[i].uid;
701 app.utt_id_stopped = 0;
702 app.state = g_app_list[i].state;
704 temp_app_list.insert(temp_app_list.end(), app);
707 for (i = 0;i < vsize;i++) {
708 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);
709 if (false == callback(temp_app_list[i].pid, temp_app_list[i].uid, temp_app_list[i].state, user_data)) {
714 for (i = 0;i < vsize;i++) {
715 temp_app_list.erase(temp_app_list.begin());
721 bool ttsd_data_is_uttid_valid(int uid, int uttid)
725 index = ttsd_data_is_client(uid);
727 SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%d)", uid);
731 if (uttid < g_app_list[index].utt_id_stopped)
737 int ttsd_data_is_current_playing()
739 int vsize = g_app_list.size();
741 for (int i = 0; i < vsize; i++) {
742 if(g_app_list[i].state == APP_STATE_PLAYING) {
743 return g_app_list[i].uid;
750 int ttsd_data_get_same_pid_client_count(int pid)
752 int vsize = g_app_list.size();
755 for (int i = 0;i < vsize;i++) {
756 if(g_app_list[i].pid == pid) {
764 int ttsd_data_save_error_log(int uid, FILE* fp)
769 pid = ttsd_data_get_pid(uid);
771 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get pid");
773 fprintf(fp, "pid - %d", pid);
776 app_tts_state_e state;
777 ret = ttsd_data_get_client_state(uid, &state);
779 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get app state");
781 fprintf(fp, "app state - %d", state);
787 index = ttsd_data_is_client(uid);
789 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid client");
794 fprintf(fp, "----- Sound list -----");
797 if (!g_app_list[index].m_wav_data.empty()) {
798 std::list<sound_data_s*>::iterator iter;
799 for (iter = g_app_list[index].m_wav_data.begin(); (NULL != *iter && iter != g_app_list[index].m_wav_data.end()); ++iter) {
800 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] data(%p) data size(%d), uttid(%d), type(%d)",
801 i, *iter, (*iter)->data, (*iter)->data_size, (*iter)->utt_id, (*iter)->audio_type);
806 fprintf(fp, "----------------------");
809 fprintf(fp, "----- Text list -----");
812 if (!g_app_list[index].m_speak_data.empty()) {
813 std::list<speak_data_s*>::iterator iter_speak;
814 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) {
815 SLOG(LOG_DEBUG, tts_tag(), "[%dth][%p] lang(%s), vctype(%d), speed(%d), uttid(%d), text(%s)",
816 i, *iter_speak, (*iter_speak)->lang, (*iter_speak)->vctype, (*iter_speak)->speed, (*iter_speak)->utt_id, (*iter_speak)->text);
820 fprintf(fp, "---------------------");