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.
15 #include "tts_client.h"
18 static const int MAX_HANDLE_NUM = 999;
19 static const int INVALID_HANDLE = -1;
21 /* allocated handle */
22 static unsigned int g_allocated_handle = 0;
24 static GList *g_client_list = NULL;
27 static pthread_mutex_t g_allocated_handle_mutex = PTHREAD_MUTEX_INITIALIZER;
28 static pthread_mutex_t g_client_list_mutex = PTHREAD_MUTEX_INITIALIZER;
31 static unsigned int __client_generate_uid(unsigned int pid)
33 pthread_mutex_lock(&g_allocated_handle_mutex);
36 if (g_allocated_handle > MAX_HANDLE_NUM) {
37 g_allocated_handle = 1;
40 /* generate uid, handle number should be smaller than 1000 */
41 unsigned int uid = pid * 1000u + g_allocated_handle;
42 pthread_mutex_unlock(&g_allocated_handle_mutex);
47 static inline void __set_state_changed_cb(tts_client_s* client, tts_state_changed_cb callback, void* user_data)
49 client->state_changed_cb = callback;
50 client->state_changed_user_data = user_data;
53 static inline void __set_utterance_started_cb(tts_client_s* client, tts_utterance_started_cb callback, void* user_data)
55 client->utt_started_cb = callback;
56 client->utt_started_user_data = user_data;
59 static inline void __set_utterance_completed_cb(tts_client_s* client, tts_utterance_completed_cb callback, void* user_data)
61 client->utt_completed_cb = callback;
62 client->utt_completed_user_data = user_data;
65 static inline void __set_error_cb(tts_client_s* client, tts_error_cb callback, void* user_data)
67 client->error_cb = callback;
68 client->error_user_data = user_data;
71 static inline void __set_default_voice_changed_cb(tts_client_s* client, tts_default_voice_changed_cb callback, void* user_data)
73 client->default_voice_changed_cb = callback;
74 client->default_voice_changed_user_data = user_data;
77 static inline void __set_engine_changed_cb(tts_client_s* client, tts_engine_changed_cb callback, void* user_data)
79 client->engine_changed_cb = callback;
80 client->engine_changed_user_data = user_data;
83 static inline void __set_screen_reader_changed_cb(tts_client_s* client, tts_screen_reader_changed_cb callback, void* user_data)
85 client->screen_reader_changed_cb = callback;
86 client->screen_reader_changed_user_data = user_data;
89 static inline void __set_supported_voice_cb(tts_client_s* client, tts_supported_voice_cb callback, void* user_data)
91 client->supported_voice_cb = callback;
92 client->supported_voice_user_data = user_data;
95 int tts_client_new(tts_h* tts)
97 tts_client_s* client = (tts_client_s*)calloc(1, sizeof(tts_client_s));
99 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to allocate memory");
100 return TTS_ERROR_OUT_OF_MEMORY;
103 tts_h temp = (tts_h)calloc(1, sizeof(struct tts_s));
105 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to allocate memory");
107 return TTS_ERROR_OUT_OF_MEMORY;
110 temp->handle = __client_generate_uid((unsigned int)getpid());
112 /* initialize client data */
114 client->pid = getpid();
115 client->uid = temp->handle;
117 pthread_mutex_lock(&g_client_list_mutex);
118 g_client_list = g_list_append(g_client_list, client);
119 pthread_mutex_unlock(&g_client_list_mutex);
123 SLOG(LOG_ERROR, TAG_TTSC, "[Success] Create client object : uid(%u)", client->uid);
125 return TTS_ERROR_NONE;
128 int tts_client_destroy(tts_h tts)
131 SLOG(LOG_ERROR, TAG_TTSC, "Input parameter is NULL");
132 return TTS_ERROR_INVALID_PARAMETER;
136 tts_client_s *data = NULL;
138 pthread_mutex_lock(&g_client_list_mutex);
139 /* if list have item */
140 if (g_list_length(g_client_list) > 0) {
141 /* Get a first item */
142 iter = g_list_first(g_client_list);
144 while (NULL != iter) {
146 if (tts->handle == data->tts->handle) {
147 tts->handle = TTS_INVALID_UID;
148 g_client_list = g_list_remove_link(g_client_list, iter);
150 while (0 != data->cb_ref_count) {
151 /* wait for release callback function */
154 unsigned int uid = data->uid;
157 free(data->credential);
158 free(data->text_repeat);
159 memset(data, 0, sizeof(tts_client_s));
169 pthread_mutex_unlock(&g_client_list_mutex);
170 SLOG(LOG_ERROR, TAG_TTSC, "Client destroy : uid(%u)", uid);
171 return TTS_ERROR_NONE;
175 iter = g_list_next(iter);
178 pthread_mutex_unlock(&g_client_list_mutex);
179 SLOG(LOG_ERROR, TAG_TTSC, "Fail to destroy client : handle is not valid");
181 return TTS_ERROR_INVALID_PARAMETER;
184 tts_client_s* tts_client_get(tts_h tts)
187 SLOG(LOG_ERROR, TAG_TTSC, "Input parameter is NULL");
192 tts_client_s *data = NULL;
194 pthread_mutex_lock(&g_client_list_mutex);
195 if (g_list_length(g_client_list) > 0) {
196 /* Get a first item */
197 iter = g_list_first(g_client_list);
199 while (NULL != iter) {
202 if (tts->handle == data->tts->handle) {
203 pthread_mutex_unlock(&g_client_list_mutex);
208 iter = g_list_next(iter);
212 pthread_mutex_unlock(&g_client_list_mutex);
213 SLOG(LOG_ERROR, TAG_TTSC, "handle is not valid");
218 tts_client_s* tts_client_get_by_uid(unsigned int uid)
220 if (uid == TTS_INVALID_UID) {
221 SLOG(LOG_ERROR, TAG_TTSC, "out of range : handle");
226 tts_client_s *data = NULL;
228 pthread_mutex_lock(&g_client_list_mutex);
229 if (g_list_length(g_client_list) > 0) {
230 /* Get a first item */
231 iter = g_list_first(g_client_list);
233 while (NULL != iter) {
235 if (uid == data->uid) {
236 pthread_mutex_unlock(&g_client_list_mutex);
241 iter = g_list_next(iter);
245 pthread_mutex_unlock(&g_client_list_mutex);
246 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] uid(%u) is not valid", uid);
251 bool tts_client_is_valid_uid(unsigned int uid)
253 if (NULL == tts_client_get_by_uid(uid)) {
254 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Uid is not valid");
261 bool tts_client_is_valid_client(tts_client_s* client)
263 if (NULL == client) {
264 SLOG(LOG_ERROR, TAG_TTSC, "[WARNING] Client is NULL");
268 pthread_mutex_lock(&g_client_list_mutex);
269 if (g_list_length(g_client_list) > 0) {
270 GList *iter = g_list_first(g_client_list);
271 while (NULL != iter) {
272 if (iter->data == client) {
273 pthread_mutex_unlock(&g_client_list_mutex);
277 iter = g_list_next(iter);
280 pthread_mutex_unlock(&g_client_list_mutex);
282 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client(%p) is not valid", client);
286 tts_h tts_client_get_handle(tts_client_s* client)
288 if (false == tts_client_is_valid_client(client)) {
295 unsigned int tts_client_get_size()
297 pthread_mutex_lock(&g_client_list_mutex);
298 unsigned int size = g_list_length(g_client_list);
299 pthread_mutex_unlock(&g_client_list_mutex);
304 int tts_client_use_callback(tts_client_s* client)
306 client->cb_ref_count++;
310 int tts_client_not_use_callback(tts_client_s* client)
312 client->cb_ref_count--;
316 int tts_client_get_use_callback(tts_client_s* client)
318 return client->cb_ref_count;
321 GList* tts_client_get_client_list()
323 GList* copy_list = NULL;
324 pthread_mutex_lock(&g_client_list_mutex);
325 copy_list = g_list_copy(g_client_list);
326 pthread_mutex_unlock(&g_client_list_mutex);
331 unsigned int tts_client_get_uid(tts_client_s* client)
333 if (NULL == client || false == tts_client_is_valid_client(client)) {
334 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Client(%p) is not valid", client);
335 return TTS_INVALID_UID;
341 void tts_client_set_current_state(tts_client_s* client, tts_state_e state)
343 if (false == tts_client_is_valid_client(client)) {
347 client->before_state = client->current_state;
348 client->current_state = state;
351 tts_state_e tts_client_get_current_state(tts_client_s* client)
353 if (false == tts_client_is_valid_client(client)) {
354 return TTS_STATE_INVALID;
357 return client->current_state;
360 void tts_client_set_start_listening(unsigned int uid, bool is_listening_started)
362 tts_client_s* client = tts_client_get_by_uid(uid);
363 if (NULL == client) {
367 client->start_listening = is_listening_started;
370 bool tts_client_is_listening_started(unsigned int uid)
372 tts_client_s* client = tts_client_get_by_uid(uid);
373 if (NULL == client) {
377 return client->start_listening;
380 void tts_client_set_reprepared(tts_client_s* client, bool is_reprepared)
382 if (false == tts_client_is_valid_client(client)) {
386 client->reprepared = is_reprepared;
389 bool tts_client_is_reprepared(tts_client_s* client)
391 if (false == tts_client_is_valid_client(client)) {
392 return INVALID_HANDLE;
395 return client->reprepared;
398 void tts_client_set_mode(tts_client_s* client, tts_mode_e mode)
400 if (false == tts_client_is_valid_client(client)) {
407 tts_mode_e tts_client_get_mode(tts_client_s* client)
409 if (false == tts_client_is_valid_client(client)) {
410 return INVALID_HANDLE;
416 void tts_client_set_repeat_text(tts_client_s* client, const char* text)
418 if (NULL == client || false == tts_client_is_valid_client(client)) {
422 if (NULL != client->text_repeat) {
423 free(client->text_repeat);
427 client->text_repeat = strdup(text);
429 client->text_repeat = NULL;
433 const char* tts_client_get_repeat_text(tts_client_s* client)
435 if (NULL == client || false == tts_client_is_valid_client(client)) {
439 return client->text_repeat;
442 int tts_client_new_utterance_id(tts_client_s* client)
444 if (NULL == client || false == tts_client_is_valid_client(client)) {
445 return INVALID_HANDLE;
448 client->current_utt_id++;
449 if (client->current_utt_id == 10000) {
450 client->current_utt_id = 1;
453 return client->current_utt_id;
456 void tts_client_set_error_message(tts_client_s* client, const char* error_message)
458 if (false == tts_client_is_valid_client(client)) {
462 if (NULL != client->err_msg) {
463 free(client->err_msg);
464 client->err_msg = NULL;
467 if (NULL != error_message) {
468 client->err_msg = strdup(error_message);
472 const char* tts_client_get_error_message(tts_client_s* client)
474 if (false == tts_client_is_valid_client(client)) {
478 return client->err_msg;
481 void tts_client_set_credential_key(tts_client_s* client, const char* credential_key)
483 if (false == tts_client_is_valid_client(client)) {
487 free(client->credential);
488 client->credential = NULL;
490 if (NULL != credential_key) {
491 client->credential = strdup(credential_key);
495 const char* tts_client_get_credential_key(tts_client_s* client)
497 if (false == tts_client_is_valid_client(client)) {
501 return client->credential;
504 void tts_client_set_state_changed_cb(tts_client_s* client, tts_state_changed_cb callback, void* user_data)
506 if (false == tts_client_is_valid_client(client)) {
510 if (NULL == callback) {
511 if (NULL != client->notify_state_timer) {
512 ecore_timer_del(client->notify_state_timer);
513 client->notify_state_timer = NULL;
516 __set_state_changed_cb(client, callback, user_data);
519 void tts_client_set_utterance_started_cb(tts_client_s* client, tts_utterance_started_cb callback, void* user_data)
521 if (false == tts_client_is_valid_client(client)) {
524 __set_utterance_started_cb(client, callback, user_data);
527 void tts_client_set_utterance_completed_cb(tts_client_s* client, tts_utterance_completed_cb callback, void* user_data)
529 if (false == tts_client_is_valid_client(client)) {
532 __set_utterance_completed_cb(client, callback, user_data);
535 void tts_client_set_error_cb(tts_client_s* client, tts_error_cb callback, void* user_data)
537 if (false == tts_client_is_valid_client(client)) {
541 if (NULL == callback) {
542 if (NULL != client->notify_error_timer) {
543 ecore_timer_del(client->notify_error_timer);
544 client->notify_error_timer = NULL;
547 __set_error_cb(client, callback, user_data);
550 void tts_client_set_default_voice_changed_cb(tts_client_s* client, tts_default_voice_changed_cb callback, void* user_data)
552 if (false == tts_client_is_valid_client(client)) {
555 __set_default_voice_changed_cb(client, callback, user_data);
558 void tts_client_set_engine_changed_cb(tts_client_s* client, tts_engine_changed_cb callback, void* user_data)
560 if (false == tts_client_is_valid_client(client)) {
563 __set_engine_changed_cb(client, callback, user_data);
566 void tts_client_set_screen_reader_changed_cb(tts_client_s* client, tts_screen_reader_changed_cb callback, void* user_data)
568 if (false == tts_client_is_valid_client(client)) {
571 __set_screen_reader_changed_cb(client, callback, user_data);
574 void tts_client_set_supported_voice_cb(tts_client_s* client, tts_supported_voice_cb callback, void* user_data)
576 if (false == tts_client_is_valid_client(client)) {
579 __set_supported_voice_cb(client, callback, user_data);
582 tts_state_changed_cb tts_client_get_state_changed_cb(tts_client_s* client)
584 if (false == tts_client_is_valid_client(client)) {
587 return client->state_changed_cb;
590 void* tts_client_get_state_changed_user_data(tts_client_s* client)
592 if (false == tts_client_is_valid_client(client)) {
595 return client->state_changed_user_data;
598 tts_utterance_started_cb tts_client_get_utterance_started_cb(tts_client_s* client)
600 if (false == tts_client_is_valid_client(client)) {
603 return client->utt_started_cb;
606 void* tts_client_get_utterance_started_user_data(tts_client_s* client)
608 if (false == tts_client_is_valid_client(client)) {
611 return client->utt_started_user_data;
614 tts_utterance_completed_cb tts_client_get_utterance_completed_cb(tts_client_s* client)
616 if (false == tts_client_is_valid_client(client)) {
619 return client->utt_completed_cb;
622 void* tts_client_get_utterance_completed_user_data(tts_client_s* client)
624 if (false == tts_client_is_valid_client(client)) {
627 return client->utt_completed_user_data;
630 tts_error_cb tts_client_get_error_cb(tts_client_s* client)
632 if (false == tts_client_is_valid_client(client)) {
635 return client->error_cb;
638 void* tts_client_get_error_user_data(tts_client_s* client)
640 if (false == tts_client_is_valid_client(client)) {
643 return client->error_user_data;
647 tts_default_voice_changed_cb tts_client_get_default_voice_changed_cb(tts_client_s* client)
649 if (false == tts_client_is_valid_client(client)) {
652 return client->default_voice_changed_cb;
655 void* tts_client_get_default_voice_changed_user_data(tts_client_s* client)
657 if (false == tts_client_is_valid_client(client)) {
660 return client->default_voice_changed_user_data;
663 tts_engine_changed_cb tts_client_get_engine_changed_cb(tts_client_s* client)
665 if (false == tts_client_is_valid_client(client)) {
668 return client->engine_changed_cb;
671 void* tts_client_get_engine_changed_user_data(tts_client_s* client)
673 if (false == tts_client_is_valid_client(client)) {
676 return client->engine_changed_user_data;
680 tts_screen_reader_changed_cb tts_client_get_screen_reader_changed_cb(tts_client_s* client)
682 if (false == tts_client_is_valid_client(client)) {
685 return client->screen_reader_changed_cb;
688 void* tts_client_get_screen_reader_changed_user_data(tts_client_s* client)
690 if (false == tts_client_is_valid_client(client)) {
693 return client->screen_reader_changed_user_data;
696 tts_supported_voice_cb tts_client_get_supported_voice_cb(tts_client_s* client)
698 if (false == tts_client_is_valid_client(client)) {
701 return client->supported_voice_cb;
704 void* tts_client_get_supported_voice_user_data(tts_client_s* client)
706 if (false == tts_client_is_valid_client(client)) {
709 return client->supported_voice_user_data;
712 void tts_client_unset_all_cb(tts_client_s* client)
714 if (false == tts_client_is_valid_client(client)) {
718 if (NULL != client->notify_state_timer) {
719 ecore_timer_del(client->notify_state_timer);
720 client->notify_state_timer = NULL;
723 if (NULL != client->notify_error_timer) {
724 ecore_timer_del(client->notify_error_timer);
725 client->notify_error_timer = NULL;
728 __set_state_changed_cb(client, NULL, NULL);
729 __set_utterance_started_cb(client, NULL, NULL);
730 __set_utterance_completed_cb(client, NULL, NULL);
731 __set_error_cb(client, NULL, NULL);
732 __set_default_voice_changed_cb(client, NULL, NULL);
733 __set_engine_changed_cb(client, NULL, NULL);
734 __set_supported_voice_cb(client, NULL, NULL);