2 * Copyright (c) 2012 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.
19 #include "tts_client.h"
22 #define MAX_TEXT_COUNT 1000
24 static bool g_is_daemon_started = false;
26 /* Function definition */
27 static int __tts_check_tts_daemon();
28 static Eina_Bool __tts_notify_state_changed(void *data);
29 static Eina_Bool __tts_notify_error(void *data);
31 int tts_create(tts_h* tts)
33 SLOG(LOG_DEBUG, TAG_TTSC, "===== Create TTS");
37 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
38 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
39 SLOG(LOG_DEBUG, TAG_TTSC, " ");
40 return TTS_ERROR_INVALID_PARAMETER;
43 if (0 == tts_client_get_size()) {
44 if (0 != tts_dbus_open_connection()) {
45 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open dbus connection");
46 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
47 SLOG(LOG_DEBUG, TAG_TTSC, " ");
48 return TTS_ERROR_OPERATION_FAILED;
52 if (0 != tts_client_new(tts)) {
53 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create client!!!!!");
54 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
55 SLOG(LOG_DEBUG, TAG_TTSC, " ");
56 return TTS_ERROR_OUT_OF_MEMORY;
59 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
60 SLOG(LOG_DEBUG, TAG_TTSC, " ");
62 return TTS_ERROR_NONE;
65 int tts_destroy(tts_h tts)
67 SLOG(LOG_DEBUG, TAG_TTSC, "===== Destroy TTS");
70 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
71 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
72 SLOG(LOG_DEBUG, TAG_TTSC, " ");
73 return TTS_ERROR_INVALID_PARAMETER;
76 tts_client_s* client = tts_client_get(tts);
80 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
81 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
82 SLOG(LOG_DEBUG, TAG_TTSC, " ");
83 return TTS_ERROR_INVALID_PARAMETER;
89 switch (client->current_state) {
90 case TTS_STATE_PAUSED:
91 case TTS_STATE_PLAYING:
93 /* Request Finalize */
94 ret = tts_dbus_request_finalize(client->uid);
96 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request finalize");
98 case TTS_STATE_CREATED:
100 tts_client_destroy(tts);
104 if (0 == tts_client_get_size()) {
105 if (0 != tts_dbus_close_connection()) {
106 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection");
110 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
111 SLOG(LOG_DEBUG, TAG_TTSC, " ");
113 return TTS_ERROR_NONE;
116 static Eina_Bool __tts_connect_daemon(void *data)
118 SLOG(LOG_DEBUG, TAG_TTSC, "===== Connect daemon");
120 tts_h tts = (tts_h)data;
122 tts_client_s* client = tts_client_get(tts);
125 if (NULL == client) {
126 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
127 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
128 SLOG(LOG_DEBUG, TAG_TTSC, " ");
133 if (0 != tts_dbus_request_hello()) {
134 if (false == g_is_daemon_started) {
135 g_is_daemon_started = true;
136 __tts_check_tts_daemon();
141 /* do request initialize */
144 ret = tts_dbus_request_initialize(client->uid);
146 if (TTS_ERROR_ENGINE_NOT_FOUND == ret) {
147 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine not found");
149 client->reason = TTS_ERROR_ENGINE_NOT_FOUND;
152 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
155 } else if (TTS_ERROR_NONE != ret) {
156 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connection");
158 client->reason = TTS_ERROR_TIMED_OUT;
161 ecore_timer_add(0, __tts_notify_error, (void*)client->tts);
164 /* success to connect tts-daemon */
167 client->before_state = client->current_state;
168 client->current_state = TTS_STATE_READY;
170 ecore_timer_add(0, __tts_notify_state_changed, (void*)client->tts);
172 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] uid(%d)", client->uid);
174 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
175 SLOG(LOG_DEBUG, TAG_TTSC, " ");
181 int tts_prepare(tts_h tts)
183 SLOG(LOG_DEBUG, TAG_TTSC, "===== Prepare TTS");
185 tts_client_s* client = tts_client_get(tts);
188 if (NULL == client) {
189 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
190 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
191 SLOG(LOG_DEBUG, TAG_TTSC, " ");
192 return TTS_ERROR_INVALID_PARAMETER;
196 if (client->current_state != TTS_STATE_CREATED) {
197 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'CREATED'");
198 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
199 SLOG(LOG_DEBUG, TAG_TTSC, " ");
200 return TTS_ERROR_INVALID_STATE;
203 ecore_timer_add(0, __tts_connect_daemon, (void*)tts);
205 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
206 SLOG(LOG_DEBUG, TAG_TTSC, " ");
208 return TTS_ERROR_NONE;
211 int tts_unprepare(tts_h tts)
213 SLOG(LOG_DEBUG, TAG_TTSC, "===== Unprepare TTS");
215 tts_client_s* client = tts_client_get(tts);
218 if (NULL == client) {
219 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not available");
220 return TTS_ERROR_INVALID_PARAMETER;
224 if (client->current_state != TTS_STATE_READY) {
225 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid State: Current state is not 'READY'");
226 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
227 SLOG(LOG_DEBUG, TAG_TTSC, " ");
228 return TTS_ERROR_INVALID_STATE;
231 int ret = tts_dbus_request_finalize(client->uid);
233 SLOG(LOG_WARN, TAG_TTSC, "[ERROR] Fail to request finalize");
236 client->before_state = client->current_state;
237 client->current_state = TTS_STATE_CREATED;
239 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
241 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
242 SLOG(LOG_DEBUG, TAG_TTSC, " ");
244 return TTS_ERROR_NONE;
247 int tts_foreach_supported_voices(tts_h tts, tts_supported_voice_cb callback, void* user_data)
249 SLOG(LOG_DEBUG, TAG_TTSC, "===== Foreach supported voices");
251 if (NULL == tts || NULL == callback) {
252 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
253 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
254 SLOG(LOG_DEBUG, TAG_TTSC, " ");
255 return TTS_ERROR_INVALID_PARAMETER;
258 tts_client_s* client = tts_client_get(tts);
261 if (NULL == client) {
262 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
263 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
264 SLOG(LOG_DEBUG, TAG_TTSC, " ");
265 return TTS_ERROR_INVALID_PARAMETER;
268 if (TTS_STATE_READY != client->current_state) {
269 SLOG(LOG_ERROR, TAG_TTSC, "Current state is NOT 'READY'.");
270 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
271 SLOG(LOG_DEBUG, TAG_TTSC, " ");
272 return TTS_ERROR_INVALID_STATE;
276 ret = tts_dbus_request_get_support_voice(client->uid, client->tts, callback, user_data);
278 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
281 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
282 SLOG(LOG_DEBUG, TAG_TTSC, " ");
287 int tts_get_default_voice(tts_h tts, char** lang, tts_voice_type_e* vctype)
289 SLOG(LOG_DEBUG, TAG_TTSC, "===== Get default voice");
292 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
293 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
294 SLOG(LOG_DEBUG, TAG_TTSC, " ");
295 return TTS_ERROR_INVALID_PARAMETER;
298 tts_client_s* client = tts_client_get(tts);
300 if (NULL == client) {
301 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
302 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
303 SLOG(LOG_DEBUG, TAG_TTSC, " ");
304 return TTS_ERROR_INVALID_PARAMETER;
307 if (TTS_STATE_READY != client->current_state) {
308 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is NOT 'READY'. ");
309 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
310 SLOG(LOG_DEBUG, TAG_TTSC, " ");
311 return TTS_ERROR_INVALID_STATE;
314 /* Request call remote method */
316 ret = tts_dbus_request_get_default_voice(client->uid, lang, vctype );
319 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
322 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
323 SLOG(LOG_DEBUG, TAG_TTSC, " ");
328 int tts_get_max_text_count(tts_h tts, int* count)
330 if (NULL == tts || NULL == count) {
331 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Input parameter is null");
332 return TTS_ERROR_INVALID_PARAMETER;
335 tts_client_s* client = tts_client_get(tts);
337 if (NULL == client) {
338 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : A handle is not valid");
339 return TTS_ERROR_INVALID_PARAMETER;
342 if (TTS_STATE_READY != client->current_state) {
343 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get max text count : Current state is NOT 'READY'.");
344 return TTS_ERROR_INVALID_STATE;
347 *count = MAX_TEXT_COUNT;
349 SLOG(LOG_DEBUG, TAG_TTSC, "[Suceess] Get max text count");
350 return TTS_ERROR_NONE;
353 int tts_get_state(tts_h tts, tts_state_e* state)
355 if (NULL == tts || NULL == state) {
356 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : Input parameter is null");
357 return TTS_ERROR_INVALID_PARAMETER;
360 tts_client_s* client = tts_client_get(tts);
362 if (NULL == client) {
363 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get state : A handle is not valid");
364 return TTS_ERROR_INVALID_PARAMETER;
367 *state = client->current_state;
370 case TTS_STATE_CREATED: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Created'"); break;
371 case TTS_STATE_READY: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Ready'"); break;
372 case TTS_STATE_PLAYING: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Playing'"); break;
373 case TTS_STATE_PAUSED: SLOG(LOG_DEBUG, TAG_TTSC, "Current state is 'Paused'"); break;
376 return TTS_ERROR_NONE;
379 int tts_add_text(tts_h tts, const char* text, const char* language, tts_voice_type_e voice_type, tts_speed_e speed, int* utt_id)
381 SLOG(LOG_DEBUG, TAG_TTSC, "===== Add text");
383 if (NULL == tts || NULL == utt_id) {
384 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is null");
385 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
386 SLOG(LOG_DEBUG, TAG_TTSC, " ");
387 return TTS_ERROR_INVALID_PARAMETER;
390 tts_client_s* client = tts_client_get(tts);
392 if (NULL == client) {
393 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
394 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
395 SLOG(LOG_DEBUG, TAG_TTSC, " ");
396 return TTS_ERROR_INVALID_PARAMETER;
399 if (TTS_STATE_CREATED == client->current_state) {
400 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'.");
401 return TTS_ERROR_INVALID_STATE;
404 /* change default language value */
407 if (NULL == language)
408 temp = strdup("default");
410 temp = strdup(language);
412 client->current_utt_id ++;
413 if (client->current_utt_id == 10000) {
414 client->current_utt_id = 1;
419 ret = tts_dbus_request_add_text(client->uid, text, temp, voice_type, speed, client->current_utt_id);
421 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
424 *utt_id = client->current_utt_id;
429 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
430 SLOG(LOG_DEBUG, TAG_TTSC, " ");
435 int tts_play(tts_h tts)
437 SLOG(LOG_DEBUG, TAG_TTSC, "===== Play tts");
440 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null.");
441 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
442 SLOG(LOG_DEBUG, TAG_TTSC, " ");
443 return TTS_ERROR_INVALID_PARAMETER;
446 tts_client_s* client = tts_client_get(tts);
448 if (NULL == client) {
449 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid.");
450 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
451 SLOG(LOG_DEBUG, TAG_TTSC, " ");
452 return TTS_ERROR_INVALID_PARAMETER;
455 if (TTS_STATE_PLAYING == client->current_state || TTS_STATE_CREATED == client->current_state) {
456 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid.");
457 return TTS_ERROR_INVALID_STATE;
461 ret = tts_dbus_request_play(client->uid);
463 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Request play : result(%d)", ret);
464 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
465 SLOG(LOG_DEBUG, TAG_TTSC, " ");
469 client->before_state = client->current_state;
470 client->current_state = TTS_STATE_PLAYING;
472 if (NULL != client->state_changed_cb) {
473 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
475 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
478 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
479 SLOG(LOG_DEBUG, TAG_TTSC, " ");
481 return TTS_ERROR_NONE;
485 int tts_stop(tts_h tts)
487 SLOG(LOG_DEBUG, TAG_TTSC, "===== Stop tts");
490 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
491 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
492 SLOG(LOG_DEBUG, TAG_TTSC, " ");
493 return TTS_ERROR_INVALID_PARAMETER;
496 tts_client_s* client = tts_client_get(tts);
498 if (NULL == client) {
499 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
500 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
501 SLOG(LOG_DEBUG, TAG_TTSC, " ");
502 return TTS_ERROR_INVALID_PARAMETER;
505 if (TTS_STATE_CREATED == client->current_state) {
506 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Current state is 'CREATED'.");
507 return TTS_ERROR_INVALID_STATE;
511 ret = tts_dbus_request_stop(client->uid);
513 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
514 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
515 SLOG(LOG_DEBUG, TAG_TTSC, " ");
519 client->before_state = client->current_state;
520 client->current_state = TTS_STATE_READY;
522 if (NULL != client->state_changed_cb) {
523 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
525 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
528 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
529 SLOG(LOG_DEBUG, TAG_TTSC, " ");
531 return TTS_ERROR_NONE;
535 int tts_pause(tts_h tts)
537 SLOG(LOG_DEBUG, TAG_TTSC, "===== Pause tts");
540 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
541 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
542 SLOG(LOG_DEBUG, TAG_TTSC, " ");
543 return TTS_ERROR_INVALID_PARAMETER;
546 tts_client_s* client = tts_client_get(tts);
548 if (NULL == client) {
549 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
550 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
551 SLOG(LOG_DEBUG, TAG_TTSC, " ");
552 return TTS_ERROR_INVALID_PARAMETER;
555 if (TTS_STATE_PLAYING != client->current_state) {
556 SLOG(LOG_ERROR, TAG_TTSC, "[Error] The Current state is NOT 'playing'. So this request should be not running.");
557 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
558 SLOG(LOG_DEBUG, TAG_TTSC, " ");
559 return TTS_ERROR_INVALID_STATE;
563 ret = tts_dbus_request_pause(client->uid);
565 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Request pause : result(%d)", ret);
566 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
567 SLOG(LOG_DEBUG, TAG_TTSC, " ");
571 client->before_state = client->current_state;
572 client->current_state = TTS_STATE_PAUSED;
574 if (NULL != client->state_changed_cb) {
575 ecore_timer_add(0, __tts_notify_state_changed, (void*)tts);
577 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
580 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
581 SLOG(LOG_DEBUG, TAG_TTSC, " ");
583 return TTS_ERROR_NONE;
586 static Eina_Bool __tts_notify_error(void *data)
588 tts_h tts = (tts_h)data;
590 tts_client_s* client = tts_client_get(tts);
593 if (NULL == client) {
594 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify error msg : A handle is not valid");
598 if (NULL != client->error_cb) {
599 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of error");
600 tts_client_use_callback(client);
601 client->error_cb(client->tts, client->utt_id, client->reason, client->error_user_data );
602 tts_client_not_use_callback(client);
604 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
610 int __tts_cb_error(int uid, tts_error_e reason, int utt_id)
612 tts_client_s* client = tts_client_get_by_uid(uid);
614 if (NULL == client) {
615 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
616 return TTS_ERROR_INVALID_PARAMETER;
619 client->utt_id = utt_id;
620 client->reason = reason;
622 /* call callback function */
623 if (NULL != client->error_cb) {
624 ecore_timer_add(0, __tts_notify_error, client->tts);
626 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error ");
632 static Eina_Bool __tts_notify_state_changed(void *data)
634 tts_h tts = (tts_h)data;
636 tts_client_s* client = tts_client_get(tts);
639 if (NULL == client) {
640 SLOG(LOG_WARN, TAG_TTSC, "Fail to notify state changed : A handle is not valid");
644 if (NULL != client->state_changed_cb) {
645 tts_client_use_callback(client);
646 client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data);
647 tts_client_not_use_callback(client);
648 SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called");
650 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
656 int __tts_cb_set_state(int uid, int state)
658 tts_client_s* client = tts_client_get_by_uid(uid);
659 if( NULL == client ) {
660 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] The handle is not valid");
664 tts_state_e state_from_daemon = (tts_state_e)state;
666 if (client->current_state == state_from_daemon) {
667 SLOG(LOG_DEBUG, TAG_TTSC, "Current state has already been %d", client->current_state);
671 if (NULL != client->state_changed_cb) {
672 ecore_timer_add(0, __tts_notify_state_changed, client->tts);
674 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] State changed callback is null");
677 client->before_state = client->current_state;
678 client->current_state = state_from_daemon;
683 static Eina_Bool __tts_notify_utt_started(void *data)
685 tts_h tts = (tts_h)data;
687 tts_client_s* client = tts_client_get(tts);
690 if (NULL == client) {
691 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to notify utt started : A handle is not valid");
695 if (NULL != client->utt_started_cb) {
696 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance started ");
697 tts_client_use_callback(client);
698 client->utt_started_cb(client->tts, client->utt_id, client->utt_started_user_data);
699 tts_client_not_use_callback(client);
701 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started ");
707 int __tts_cb_utt_started(int uid, int utt_id)
709 tts_client_s* client = tts_client_get_by_uid(uid);
711 if (NULL == client) {
712 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
713 return TTS_ERROR_INVALID_PARAMETER;
716 SLOG(LOG_DEBUG, TAG_TTSC, "utterance started : utt id(%d) ", utt_id);
718 client->utt_id = utt_id;
720 /* call callback function */
721 if (NULL != client->utt_started_cb) {
722 ecore_timer_add(0, __tts_notify_utt_started, client->tts);
724 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance started ");
730 static Eina_Bool __tts_notify_utt_completed(void *data)
732 tts_h tts = (tts_h)data;
734 tts_client_s* client = tts_client_get(tts);
737 if (NULL == client) {
738 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Fail to notify utt completed : A handle is not valid");
742 if (NULL != client->utt_completeted_cb) {
743 SLOG(LOG_DEBUG, TAG_TTSC, "Call callback function of utterance completed ");
744 tts_client_use_callback(client);
745 client->utt_completeted_cb(client->tts, client->utt_id, client->utt_completed_user_data);
746 tts_client_not_use_callback(client);
748 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed ");
754 int __tts_cb_utt_completed(int uid, int utt_id)
756 tts_client_s* client = tts_client_get_by_uid(uid);
758 if (NULL == client) {
759 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
760 return TTS_ERROR_INVALID_PARAMETER;
763 SLOG(LOG_DEBUG, TAG_TTSC, "utterance completed : uttid(%d) ", utt_id);
765 client->utt_id = utt_id;
767 /* call callback function */
768 if (NULL != client->utt_completeted_cb) {
769 ecore_timer_add(0, __tts_notify_utt_completed, client->tts);
771 SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of utterance completed ");
777 int tts_set_state_changed_cb(tts_h tts, tts_state_changed_cb callback, void* user_data)
779 if (NULL == tts || NULL == callback) {
780 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Input parameter is null");
781 return TTS_ERROR_INVALID_PARAMETER;
784 tts_client_s* client = tts_client_get(tts);
786 if (NULL == client) {
787 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : A handle is not valid");
788 return TTS_ERROR_INVALID_PARAMETER;
791 if (TTS_STATE_CREATED != client->current_state) {
792 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set state changed cb : Current state is not 'Created'.");
793 return TTS_ERROR_INVALID_STATE;
796 client->state_changed_cb = callback;
797 client->state_changed_user_data = user_data;
799 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set state changed cb");
804 int tts_unset_state_changed_cb(tts_h tts)
807 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Input parameter is null");
808 return TTS_ERROR_INVALID_PARAMETER;
811 tts_client_s* client = tts_client_get(tts);
813 if (NULL == client) {
814 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : A handle is not valid");
815 return TTS_ERROR_INVALID_PARAMETER;
818 if (TTS_STATE_CREATED != client->current_state) {
819 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset state changed cb : Current state is not 'Created'.");
820 return TTS_ERROR_INVALID_STATE;
823 client->state_changed_cb = NULL;
824 client->state_changed_user_data = NULL;
826 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset state changed cb");
831 int tts_set_utterance_started_cb(tts_h tts, tts_utterance_started_cb callback, void* user_data)
833 if (NULL == tts || NULL == callback) {
834 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Input parameter is null");
835 return TTS_ERROR_INVALID_PARAMETER;
838 tts_client_s* client = tts_client_get(tts);
840 if (NULL == client) {
841 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : A handle is not valid");
842 return TTS_ERROR_INVALID_PARAMETER;
845 if (TTS_STATE_CREATED != client->current_state) {
846 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt started cb : Current state is not 'Created'.");
847 return TTS_ERROR_INVALID_STATE;
850 client->utt_started_cb = callback;
851 client->utt_started_user_data = user_data;
853 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt started cb");
858 int tts_unset_utterance_started_cb(tts_h tts)
861 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Input parameter is null");
862 return TTS_ERROR_INVALID_PARAMETER;
865 tts_client_s* client = tts_client_get(tts);
867 if (NULL == client) {
868 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : A handle is not valid");
869 return TTS_ERROR_INVALID_PARAMETER;
872 if (TTS_STATE_CREATED != client->current_state) {
873 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt started cb : Current state is not 'Created'.");
874 return TTS_ERROR_INVALID_STATE;
877 client->utt_started_cb = NULL;
878 client->utt_started_user_data = NULL;
880 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt started cb");
885 int tts_set_utterance_completed_cb(tts_h tts, tts_utterance_completed_cb callback, void* user_data)
887 if (NULL == tts || NULL == callback) {
888 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Input parameter is null");
889 return TTS_ERROR_INVALID_PARAMETER;
892 tts_client_s* client = tts_client_get(tts);
894 if (NULL == client) {
895 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : A handle is not valid");
896 return TTS_ERROR_INVALID_PARAMETER;
899 if (TTS_STATE_CREATED != client->current_state) {
900 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set utt completed cb : Current state is not 'Created'.");
901 return TTS_ERROR_INVALID_STATE;
904 client->utt_completeted_cb = callback;
905 client->utt_completed_user_data = user_data;
907 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set utt completed cb");
912 int tts_unset_utterance_completed_cb(tts_h tts)
915 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Input parameter is null");
916 return TTS_ERROR_INVALID_PARAMETER;
919 tts_client_s* client = tts_client_get(tts);
921 if (NULL == client) {
922 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : A handle is not valid");
923 return TTS_ERROR_INVALID_PARAMETER;
926 if (TTS_STATE_CREATED != client->current_state) {
927 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset utt completed cb : Current state is not 'Created'.");
928 return TTS_ERROR_INVALID_STATE;
931 client->utt_completeted_cb = NULL;
932 client->utt_completed_user_data = NULL;
934 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset utt completed cb");
938 int tts_set_error_cb(tts_h tts, tts_error_cb callback, void* user_data)
940 if (NULL == tts || NULL == callback) {
941 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Input parameter is null");
942 return TTS_ERROR_INVALID_PARAMETER;
945 tts_client_s* client = tts_client_get(tts);
947 if (NULL == client) {
948 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : A handle is not valid");
949 return TTS_ERROR_INVALID_PARAMETER;
952 if (TTS_STATE_CREATED != client->current_state) {
953 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Set error cb : Current state is not 'Created'.");
954 return TTS_ERROR_INVALID_STATE;
957 client->error_cb = callback;
958 client->error_user_data = user_data;
960 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set error cb");
965 int tts_unset_error_cb(tts_h tts)
968 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Input parameter is null");
969 return TTS_ERROR_INVALID_PARAMETER;
972 tts_client_s* client = tts_client_get(tts);
974 if (NULL == client) {
975 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : A handle is not valid");
976 return TTS_ERROR_INVALID_PARAMETER;
979 if (TTS_STATE_CREATED != client->current_state) {
980 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Unset error cb : Current state is not 'Created'.");
981 return TTS_ERROR_INVALID_STATE;
984 client->error_cb = NULL;
985 client->error_user_data = NULL;
987 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Unset error cb");
992 static bool _tts_is_alive()
998 memset(buff, '\0', sizeof(char) * 256);
999 memset(cmd, '\0', sizeof(char) * 256);
1001 if ((fp = popen("ps -eo \"cmd\"", "r")) == NULL) {
1002 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] popen error");
1006 while(fgets(buff, 255, fp)) {
1007 sscanf(buff, "%s", cmd);
1009 if (0 == strncmp(cmd, "[tts-daemon]", strlen("[tts-daemon]")) ||
1010 0 == strncmp(cmd, "tts-daemon", strlen("tts-daemon")) ||
1011 0 == strncmp(cmd, "/usr/bin/tts-daemon", strlen("/usr/bin/tts-daemon"))) {
1012 SLOG(LOG_DEBUG, TAG_TTSC, "tts-daemon is ALIVE !!");
1020 SLOG(LOG_DEBUG, TAG_TTSC, "THERE IS NO tts-daemon !!");
1026 static void __my_sig_child(int signo, siginfo_t *info, void *data)
1029 pid_t child_pid, child_pgid;
1031 child_pgid = getpgid(info->si_pid);
1032 SLOG(LOG_DEBUG, TAG_TTSC, "Signal handler: dead pid = %d, pgid = %d", info->si_pid, child_pgid);
1034 while (0 < (child_pid = waitpid(-1, &status, WNOHANG))) {
1035 if(child_pid == child_pgid)
1036 killpg(child_pgid, SIGKILL);
1042 static int __tts_check_tts_daemon()
1044 if (TRUE == _tts_is_alive())
1047 /* fork-exec tts-daemom */
1049 struct sigaction act, dummy;
1051 act.sa_handler = NULL;
1052 act.sa_sigaction = __my_sig_child;
1053 sigemptyset(&act.sa_mask);
1054 act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
1056 if (sigaction(SIGCHLD, &act, &dummy) < 0) {
1057 SLOG(LOG_ERROR, TAG_TTSC, "Cannot make a signal handler");
1065 SLOG(LOG_ERROR, TAG_TTSC, "Fail to create tts-daemon");
1070 for (i = 0;i < _NSIG;i++)
1073 execl("/usr/bin/tts-daemon", "/usr/bin/tts-daemon", NULL);