From: wn.jang Date: Fri, 9 Dec 2022 09:39:39 +0000 (+0900) Subject: Implement internal API for synthesized PCM X-Git-Tag: accepted/tizen/7.0/unified/20230904.170929~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F45%2F298145%2F1;p=platform%2Fcore%2Fuifw%2Ftts.git Implement internal API for synthesized PCM Change-Id: I01563b86646952c6d55d3e111e910223a6b4c218 --- diff --git a/client/tts.c b/client/tts.c index a7b67f3a..191d2d46 100644 --- a/client/tts.c +++ b/client/tts.c @@ -430,6 +430,26 @@ int tts_get_mode(tts_h tts, tts_mode_e* mode) return TTS_ERROR_NONE; } +int tts_set_playing_mode(tts_h tts, tts_playing_mode_e mode) +{ + RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED); + + SLOG(LOG_INFO, TAG_TTSC, "@@@ Set TTS playing mode(%d)", mode); + + RETVM_IF(TTS_PLAYING_MODE_BY_SERVICE > mode || TTS_PLAYING_MODE_BY_CLIENT < mode, TTS_ERROR_INVALID_PARAMETER, "[ERROR] mode is not valid : %d", mode); + + tts_client_s* client = tts_client_get(tts); + RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts); + + tts_state_e current_state = tts_client_get_current_state(client); + RETVM_IF(TTS_STATE_CREATED != current_state, TTS_ERROR_INVALID_STATE, "[ERROR] The current state(%d) is invalid", current_state); + + tts_client_set_playing_mode(client, mode); + + SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); + return TTS_ERROR_NONE; +} + int tts_set_credential(tts_h tts, const char* credential) { RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED); diff --git a/client/tts_client.c b/client/tts_client.c index 551041fa..77f21e4f 100644 --- a/client/tts_client.c +++ b/client/tts_client.c @@ -479,6 +479,24 @@ tts_mode_e tts_client_get_mode(tts_client_s* client) return client->mode; } +void tts_client_set_playing_mode(tts_client_s* client, tts_playing_mode_e mode) +{ + if (false == tts_client_is_valid_client(client)) { + return; + } + + client->playing_mode = mode; +} + +tts_playing_mode_e tts_client_get_playing_mode(tts_client_s* client) +{ + if (false == tts_client_is_valid_client(client)) { + return INVALID_HANDLE; + } + + return client->playing_mode; +} + void tts_client_set_repeat_text(tts_client_s* client, const char* text) { if (NULL == client || false == tts_client_is_valid_client(client)) { diff --git a/client/tts_client.h b/client/tts_client.h index 1a7d0468..1f90b245 100644 --- a/client/tts_client.h +++ b/client/tts_client.h @@ -62,6 +62,7 @@ typedef struct { /* mode / state */ tts_mode_e mode; + tts_playing_mode_e playing_mode; tts_state_e before_state; tts_state_e current_state; @@ -126,6 +127,9 @@ bool tts_client_is_reprepared(tts_client_s* client); void tts_client_set_mode(tts_client_s* client, tts_mode_e mode); tts_mode_e tts_client_get_mode(tts_client_s* client); +void tts_client_set_playing_mode(tts_client_s* client, tts_playing_mode_e mode); +tts_playing_mode_e tts_client_get_playing_mode(tts_client_s* client); + void tts_client_set_repeat_text(tts_client_s* client, const char* text); char* tts_client_get_repeat_text(tts_client_s* client); diff --git a/client/tts_core.c b/client/tts_core.c index 3cf8791d..e2a1ebe4 100644 --- a/client/tts_core.c +++ b/client/tts_core.c @@ -427,8 +427,9 @@ static int __send_hello_msg(tts_client_s* client) unsigned int uid = tts_client_get_uid(client); tts_mode_e mode = tts_client_get_mode(client); + tts_playing_mode_e playing_mode = tts_client_get_playing_mode(client); int registered_callback_mask = tts_client_get_registered_event_mask(client); - SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%u), mode(%d)", tts_client_get_handle(client), client, uid, (int)mode); + SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts_h(%p), tts_client(%p), uid(%u), mode(%d), playing_mode(%d)", tts_client_get_handle(client), client, uid, (int)mode, (int)playing_mode); /* check service engine status */ bool is_launched = __is_engine_launched(); @@ -443,7 +444,7 @@ static int __send_hello_msg(tts_client_s* client) } } - if (0 != tts_ipc_request_hello(uid, mode, registered_callback_mask)) { + if (0 != tts_ipc_request_hello(uid, mode, playing_mode, registered_callback_mask)) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request hello !!"); //LCOV_EXCL_LINE } else { SLOG(LOG_INFO, TAG_TTSC, "@@@ Send Hello"); @@ -530,8 +531,9 @@ static int __prepare_sync_cb(tts_client_s* client) /* do request initialize */ bool credential_needed = false; tts_mode_e mode = tts_client_get_mode(client); + tts_playing_mode_e playing_mode = tts_client_get_playing_mode(client); int registered_callback_mask = tts_client_get_registered_event_mask(client); - int ret = tts_ipc_request_initialize(uid, mode, registered_callback_mask, &credential_needed); + int ret = tts_ipc_request_initialize(uid, mode, playing_mode, registered_callback_mask, &credential_needed); if (TTS_ERROR_ENGINE_NOT_FOUND == ret || TTS_ERROR_PERMISSION_DENIED == ret) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to initialize. ret(%d/%s)", ret, get_error_message(ret)); tts_core_notify_error_async(client, ret, -1, NULL); @@ -903,6 +905,28 @@ int tts_core_notify_service_state_changed(tts_client_s* client, tts_service_stat return TTS_ERROR_NONE; } +int tts_core_notify_synthesized_pcm(tts_client_s* client, int utt_id, tts_synthesized_pcm_event_e event, const char* pcm_data, int pcm_data_size, tts_audio_type_e audio_type, int sample_rate) +{ + RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid."); + RETVM_IF(NULL == pcm_data, TTS_ERROR_INVALID_PARAMETER, "[ERROR] pcm_data is NULL."); + + SLOG(LOG_DEBUG, TAG_TTSC, "Synthesized pcm data : utt_id(%d), pcm_data_size(%d)", utt_id, pcm_data_size); + + tts_synthesized_pcm_cb callback = tts_client_get_synthesized_pcm_cb(client); + void* user_data = tts_client_get_synthesized_pcm_user_data(client); + + if (NULL != callback) { + SLOG(LOG_DEBUG, TAG_TTSC, "Notify synthesized pcm comes"); + tts_client_use_callback(client); + callback(tts_client_get_handle(client), utt_id, event, pcm_data, pcm_data_size, audio_type, sample_rate, user_data); + tts_client_not_use_callback(client); + } else { + SLOG(LOG_WARN, TAG_TTSC, "No registered callback(synthesized_pcm)"); + } + + return TTS_ERROR_NONE; +} + bool tts_core_is_valid_text(const char* text) { if (NULL == text) { diff --git a/client/tts_core.h b/client/tts_core.h index 75632e81..c0c446b8 100644 --- a/client/tts_core.h +++ b/client/tts_core.h @@ -15,12 +15,13 @@ #ifndef __TTS_CORE_H_ #define __TTS_CORE_H_ +#include "tts_client.h" +#include "tts_internal.h" + #ifdef __cplusplus extern "C" { #endif -#include "tts_client.h" - // common function int tts_core_notify_state_changed(tts_client_s* client, tts_state_e current_state); int tts_core_notify_utt_started(tts_client_s* client, int utt_id); @@ -30,6 +31,7 @@ int tts_core_notify_default_voice_changed(tts_client_s* client, const char* befo int tts_core_notify_engine_changed(tts_client_s* client, const char* engine_id, const char* language, int voice_type, bool need_credential); int tts_core_notify_screen_reader_changed(tts_client_s* client, bool value); int tts_core_notify_service_state_changed(tts_client_s* client, tts_service_state_e before_state, tts_service_state_e current_state); +int tts_core_notify_synthesized_pcm(tts_client_s* client, int utt_id, tts_synthesized_pcm_event_e event, const char* pcm_data, int pcm_data_size, tts_audio_type_e audio_type, int sample_rate); bool tts_core_is_valid_text(const char* text); bool tts_core_check_screen_reader(tts_client_s* client); diff --git a/client/tts_dbus.c b/client/tts_dbus.c index 6c3cfcb0..d4f9114e 100644 --- a/client/tts_dbus.c +++ b/client/tts_dbus.c @@ -199,6 +199,34 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle } } /* TTSD_METHOD_SET_SERVICE_STATE */ + else if (dbus_message_is_signal(msg, if_name, TTSD_METHOD_SEND_PCM)) { + unsigned int uid = 0; + int uttid = -1; + int event = -1; + char* pcm_data = NULL; + int pcm_data_size = -1; + int audio_type = -1; + int sample_rate = 0; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_INT32, &uttid, + DBUS_TYPE_INT32, &event, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pcm_data, &pcm_data_size, + DBUS_TYPE_INT32, &audio_type, + DBUS_TYPE_INT32, &sample_rate, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get arguments error (%s)", err.message); + dbus_error_free(&err); + } + + if (0 == tts_core_notify_synthesized_pcm(tts_client_get_by_uid(uid), uttid, event, pcm_data, pcm_data_size, audio_type, sample_rate)) { + SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts send pcm : uid(%u) uttid(%d) event(%d) pcm_data_size(%d) audio_type(%d) sample_rate(%d)", uid, uttid, event, pcm_data_size, audio_type, sample_rate); + } + } + else if (dbus_message_is_signal(msg, if_name, TTSD_METHOD_ERROR)) { unsigned int uid; int uttid; @@ -438,7 +466,7 @@ DBusMessage* __tts_dbus_make_message(unsigned int uid, const char* method) return msg; } -int tts_dbus_request_hello(unsigned int uid, tts_mode_e mode, int registered_event_mask) +int tts_dbus_request_hello(unsigned int uid, tts_mode_e mode, tts_playing_mode_e playing_mode, int registered_event_mask) { DBusError err; dbus_error_init(&err); @@ -461,6 +489,7 @@ int tts_dbus_request_hello(unsigned int uid, tts_mode_e mode, int registered_eve DBUS_TYPE_INT32, &pid, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INT32, &mode, + DBUS_TYPE_INT32, &playing_mode, DBUS_TYPE_INT32, ®istered_event_mask, DBUS_TYPE_INVALID)) { dbus_message_unref(msg); @@ -524,7 +553,7 @@ int tts_dbus_request_hello_sync(unsigned int uid) return result; } -int tts_dbus_request_initialize(unsigned int uid, tts_mode_e mode, int registered_event_mask, bool* credential_needed) +int tts_dbus_request_initialize(unsigned int uid, tts_mode_e mode, tts_playing_mode_e playing_mode, int registered_event_mask, bool* credential_needed) { DBusMessage* msg; DBusError err; @@ -536,7 +565,7 @@ int tts_dbus_request_initialize(unsigned int uid, tts_mode_e mode, int registere SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts initialize : Fail to make message"); return TTS_ERROR_OPERATION_FAILED; } else { - SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts initialize : uid(%u)", uid); + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts initialize : uid(%u), mode(%d), playing_mode(%d)", uid, (int)mode, (int)playing_mode); } int pid = getpid(); @@ -544,6 +573,7 @@ int tts_dbus_request_initialize(unsigned int uid, tts_mode_e mode, int registere DBUS_TYPE_INT32, &pid, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INT32, &mode, + DBUS_TYPE_INT32, &playing_mode, DBUS_TYPE_INT32, ®istered_event_mask, DBUS_TYPE_INVALID)) { dbus_message_unref(msg); diff --git a/client/tts_dbus.h b/client/tts_dbus.h index a0eaeb70..59eeda58 100644 --- a/client/tts_dbus.h +++ b/client/tts_dbus.h @@ -16,6 +16,7 @@ #define __TTS_DBUS_H_ #include "tts.h" +#include "tts_internal.h" #ifdef __cplusplus extern "C" { @@ -27,11 +28,11 @@ int tts_dbus_close_connection(unsigned int uid); int tts_dbus_stop_listening(unsigned int uid); -int tts_dbus_request_hello(unsigned int uid, tts_mode_e mode, int registered_event_mask); +int tts_dbus_request_hello(unsigned int uid, tts_mode_e mode, tts_playing_mode_e playing_mode, int registered_event_mask); int tts_dbus_request_hello_sync(unsigned int uid); -int tts_dbus_request_initialize(unsigned int uid, tts_mode_e mode, int registered_event_mask, bool* credential_needed); +int tts_dbus_request_initialize(unsigned int uid, tts_mode_e mode, tts_playing_mode_e playing_mode, int registered_event_mask, bool* credential_needed); int tts_dbus_request_finalize(unsigned int uid); diff --git a/client/tts_ipc.c b/client/tts_ipc.c index 9b4eb366..2ec5e535 100644 --- a/client/tts_ipc.c +++ b/client/tts_ipc.c @@ -109,14 +109,14 @@ int tts_ipc_stop_listening(unsigned int uid) return g_vtable[STOP_LISTENING](uid); } -int tts_ipc_request_hello(unsigned int uid, tts_mode_e mode, int registered_event_mask) +int tts_ipc_request_hello(unsigned int uid, tts_mode_e mode, tts_playing_mode_e playing_mode, int registered_event_mask) { SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_hello"); RETVM_IF(false == tts_client_is_valid_uid(uid), TTS_ERROR_INVALID_PARAMETER, "Fail to get tts_client with uid(%u)", uid); RETVM_IF(NULL == g_vtable, TTS_ERROR_OPERATION_FAILED, "[ERROR] IPC method is not set"); - return g_vtable[REQUEST_HELLO](uid, mode, registered_event_mask); + return g_vtable[REQUEST_HELLO](uid, mode, playing_mode, registered_event_mask); } int tts_ipc_request_hello_sync(unsigned int uid) @@ -129,14 +129,14 @@ int tts_ipc_request_hello_sync(unsigned int uid) return g_vtable[REQUEST_HELLO_SYNC](uid); } -int tts_ipc_request_initialize(unsigned int uid, tts_mode_e mode, int registered_event_mask, bool* credential_needed) +int tts_ipc_request_initialize(unsigned int uid, tts_mode_e mode, tts_playing_mode_e playing_mode, int registered_event_mask, bool* credential_needed) { SLOG(LOG_INFO, TAG_TTSC, "[IPC] tts_ipc_request_initialize"); RETVM_IF(false == tts_client_is_valid_uid(uid), TTS_ERROR_INVALID_PARAMETER, "Fail to get tts_client with uid(%u)", uid); RETVM_IF(NULL == g_vtable, TTS_ERROR_OPERATION_FAILED, "[ERROR] IPC method is not set"); - return g_vtable[REQUEST_INITIALIZE](uid, mode, registered_event_mask, credential_needed); + return g_vtable[REQUEST_INITIALIZE](uid, mode, playing_mode, registered_event_mask, credential_needed); } int tts_ipc_request_finalize(unsigned int uid) diff --git a/client/tts_ipc.h b/client/tts_ipc.h index 34bad752..956161ea 100644 --- a/client/tts_ipc.h +++ b/client/tts_ipc.h @@ -30,11 +30,11 @@ int tts_ipc_close_connection(unsigned int uid); int tts_ipc_stop_listening(unsigned int uid); -int tts_ipc_request_hello(unsigned int uid, tts_mode_e mode, int registered_event_mask); +int tts_ipc_request_hello(unsigned int uid, tts_mode_e mode, tts_playing_mode_e playing_mode, int registered_event_mask); int tts_ipc_request_hello_sync(unsigned int uid); -int tts_ipc_request_initialize(unsigned int uid, tts_mode_e mode, int registered_event_mask, bool* credential_needed); +int tts_ipc_request_initialize(unsigned int uid, tts_mode_e mode, tts_playing_mode_e playing_mode, int registered_event_mask, bool* credential_needed); int tts_ipc_request_finalize(unsigned int uid); diff --git a/client/tts_tidl.c b/client/tts_tidl.c index aef57d6b..f1e4f8c2 100644 --- a/client/tts_tidl.c +++ b/client/tts_tidl.c @@ -118,6 +118,25 @@ static void __notify_cb(void *user_data, int pid, int uid, bundle *msg) if (before_state && current_state) { tts_core_notify_service_state_changed(client, (tts_service_state_e)atoi(before_state), (tts_service_state_e)atoi(current_state)); } + } else if (0 == strncmp(TTSD_METHOD_SEND_PCM, method, strlen(TTSD_METHOD_SEND_PCM))) { + char* uttid = NULL; + char* event = NULL; + void* pcm_data = NULL; + size_t pcm_data_size = 0; + char* audio_type = NULL; + char* sample_rate = NULL; + + bundle_get_str(msg, TTS_BUNDLE_UTTID, &uttid); + bundle_get_str(msg, TTS_BUNDLE_PCM_EVENT, &event); + bundle_get_byte(msg, TTS_BUNDLE_PCM_DATA, (void**)&pcm_data, &pcm_data_size); + bundle_get_str(msg, TTS_BUNDLE_PCM_AUDIO_TYPE, &audio_type); + bundle_get_str(msg, TTS_BUNDLE_PCM_SAMPLE_RATE, &sample_rate); + SLOG(LOG_DEBUG, TAG_TTSC, "uttid(%s) event(%s) pcm_data(%p) pcm_data_size(%d) audio_type(%s) sample_rate(%s)", uttid, event, pcm_data, (int)pcm_data_size, audio_type, sample_rate); + if (uttid && ((pcm_data && pcm_data_size > 0) || TTS_SYNTHESIZED_PCM_EVENT_FINISH == atoi(event))) { + tts_core_notify_synthesized_pcm(client, atoi(uttid), atoi(event), (const char*)pcm_data, (int)pcm_data_size, atoi(audio_type), atoi(sample_rate)); + } else { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get message(TTSD_METHOD_SEND_PCM). pid(%d) uid(%u)", pid, u_uid); + } } else if (0 == strncmp(TTSD_METHOD_ERROR, method, strlen(TTSD_METHOD_ERROR))) { char *uttid = NULL; char *reason = NULL; @@ -334,7 +353,7 @@ static int __create_notify_callback_handle(tts_tidl_info_s* info) return TTS_ERROR_NONE; } -static int __invoke_register_callback(int pid, tts_mode_e mode, int registered_event_mask, tts_tidl_info_s* info) +static int __invoke_register_callback(int pid, tts_mode_e mode, tts_playing_mode_e playing_mode, int registered_event_mask, tts_tidl_info_s* info) { if (info->register_callback_invoked) { SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Already register callback is invoked"); @@ -348,7 +367,7 @@ static int __invoke_register_callback(int pid, tts_mode_e mode, int registered_e } SLOG(LOG_ERROR, TAG_TTSC, ">>>>> Request register cb. uid(%d)", info->uid); - rpc_port_proxy_tts_invoke_register_cb(info->rpc_h, pid, info->uid, (int)mode, registered_event_mask, info->notify_cb_h); + rpc_port_proxy_tts_invoke_register_cb(info->rpc_h, pid, info->uid, (int)mode, (int)playing_mode, registered_event_mask, info->notify_cb_h); info->register_callback_invoked = true; return TTS_ERROR_NONE; } @@ -422,7 +441,7 @@ static int __check_and_prepare_rpc_port(tts_tidl_info_s* info) return __reset_rpc_port(info, engine_id); } -int tts_tidl_request_hello(unsigned int uid, tts_mode_e mode, int registered_event_mask) +int tts_tidl_request_hello(unsigned int uid, tts_mode_e mode, tts_playing_mode_e playing_mode, int registered_event_mask) { SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_hello"); @@ -444,7 +463,7 @@ int tts_tidl_request_hello(unsigned int uid, tts_mode_e mode, int registered_eve } SLOG(LOG_DEBUG, TAG_TTSC, ">>>>> TTS Hello"); - if (TTS_ERROR_NONE != __invoke_register_callback(client->pid, mode, registered_event_mask, info)) { + if (TTS_ERROR_NONE != __invoke_register_callback(client->pid, mode, playing_mode, registered_event_mask, info)) { SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to invoke register callback"); return TTS_ERROR_OPERATION_FAILED; } @@ -545,9 +564,9 @@ int tts_tidl_request_hello_sync(unsigned int uid) return TTS_ERROR_NONE; } -int tts_tidl_request_initialize(unsigned int uid, tts_mode_e mode, int registered_event_mask, bool* credential_needed) +int tts_tidl_request_initialize(unsigned int uid, tts_mode_e mode, tts_playing_mode_e playing_mode, int registered_event_mask, bool* credential_needed) { - SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_initialize"); + SLOG(LOG_DEBUG, TAG_TTSC, "[TIDL] tts_tidl_request_initialize : uid(%u), mode(%d), playing_mode(%d)", uid, (int)mode, (int)playing_mode); tts_client_s* client = tts_client_get_by_uid(uid); RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Fail to get client"); @@ -557,8 +576,8 @@ int tts_tidl_request_initialize(unsigned int uid, tts_mode_e mode, int registere RETVM_IF(!info->connected, TTS_ERROR_IO_ERROR, "[ERROR] Not Connected"); - bool temp; - int ret = rpc_port_proxy_tts_invoke_initialize(info->rpc_h, client->pid, uid, (int)mode, registered_event_mask, &temp); + bool temp = false; + int ret = rpc_port_proxy_tts_invoke_initialize(info->rpc_h, client->pid, uid, (int)mode, (int)playing_mode, registered_event_mask, &temp); int exception = get_last_result(); if (RPC_PORT_ERROR_NONE != exception) { ret = __convert_and_handle_tidl_error(exception, info); diff --git a/client/tts_tidl.h b/client/tts_tidl.h index 19af39de..2b2d7bab 100644 --- a/client/tts_tidl.h +++ b/client/tts_tidl.h @@ -14,7 +14,8 @@ #ifndef __TTS_TIDL_H_ #define __TTS_TIDL_H_ -#include +#include "tts.h" +#include "tts_internal.h" #ifdef __cplusplus extern "C" { @@ -26,11 +27,11 @@ int tts_tidl_close_connection(unsigned int uid); int tts_tidl_stop_listening(unsigned int uid); -int tts_tidl_request_hello(unsigned int uid, tts_mode_e mode, int registered_event_mask); +int tts_tidl_request_hello(unsigned int uid, tts_mode_e mode, tts_playing_mode_e playing_mode, int registered_event_mask); int tts_tidl_request_hello_sync(unsigned int uid); -int tts_tidl_request_initialize(unsigned int uid, tts_mode_e mode, int registered_event_mask, bool* credential_needed); +int tts_tidl_request_initialize(unsigned int uid, tts_mode_e mode, tts_playing_mode_e playing_mode, int registered_event_mask, bool* credential_needed); int tts_tidl_request_finalize(unsigned int uid); diff --git a/common/tts_defs.h b/common/tts_defs.h index 300b6ba0..00bfcfa3 100644 --- a/common/tts_defs.h +++ b/common/tts_defs.h @@ -62,6 +62,10 @@ extern "C" { #define TTS_BUNDLE_CREDENTIAL_NEEDED "credential_needed" #define TTS_BUNDLE_BEFORE_STATE "before_state" #define TTS_BUNDLE_CURRENT_STATE "current_state" +#define TTS_BUNDLE_PCM_EVENT "pcm_event" +#define TTS_BUNDLE_PCM_DATA "pcm_data" +#define TTS_BUNDLE_PCM_AUDIO_TYPE "pcm_audio_type" +#define TTS_BUNDLE_PCM_SAMPLE_RATE "pcm_sample_rate" #define TTS_METHOD_HELLO "tts_method_hello" #define TTS_METHOD_HELLO_SYNC "tts_method_hello_sync" @@ -88,6 +92,7 @@ extern "C" { #define TTSD_METHOD_ERROR "ttsd_method_error" #define TTSD_METHOD_SET_STATE "ttsd_method_set_state" #define TTSD_METHOD_SET_SERVICE_STATE "ttsd_method_set_service_state" +#define TTSD_METHOD_SEND_PCM "ttsd_method_send_pcm" /****************************************************************************************** diff --git a/include/tts_internal.h b/include/tts_internal.h index 0aeee265..ef483338 100644 --- a/include/tts_internal.h +++ b/include/tts_internal.h @@ -28,15 +28,35 @@ extern "C" #endif +/** + * @brief Enumeration for playing mode of TTS. + * @since_tizen 8.0 +*/ +typedef enum { + TTS_PLAYING_MODE_BY_SERVICE = 0, /**< Mode for TTS playing on TTS service */ + TTS_PLAYING_MODE_BY_CLIENT = 1, /**< Mode for TTS playing on TTS client */ +} tts_playing_mode_e; + + +/** + * @brief Enumeration for audio type. + * @since_tizen 8.0 + */ +typedef enum { + TTS_AUDIO_TYPE_RAW_S16 = 0, /**< Signed 16-bit audio type */ + TTS_AUDIO_TYPE_RAW_U8 /**< Unsigned 8-bit audio type */ +} tts_audio_type_e; + + /** * @brief Enumeration for synthesized pcm event. - * @since_tizen 7.5 + * @since_tizen 8.0 */ typedef enum { - TTS_SYNTHESIZED_PCM_EVENT_FAIL = -1, /**< 'Error' event */ - TTS_SYNTHESIZED_PCM_EVENT_START, /**< 'Started' event */ - TTS_SYNTHESIZED_PCM_EVENT_CONTINUE, /**< 'Finished' event */ - TTS_SYNTHESIZED_PCM_EVENT_FINISH, /**< 'Finished' event */ + TTS_SYNTHESIZED_PCM_EVENT_FAIL = -1, /**< Event when the synthesized PCM is failed */ + TTS_SYNTHESIZED_PCM_EVENT_START = 1, /**< Event when the synthesized PCM is received at first */ + TTS_SYNTHESIZED_PCM_EVENT_CONTINUE = 2, /**< Event when the synthesized PCM is received, not first and not last */ + TTS_SYNTHESIZED_PCM_EVENT_FINISH = 3 /**< Event when the synthesized PCM is received finally */ } tts_synthesized_pcm_event_e; @@ -48,18 +68,21 @@ typedef enum { /** * @brief Called when the synthesized pcm data is come from the engine. - * @since_tizen 7.5 + * @since_tizen 8.0 * @remarks The @a tts handle should not be destroyed in the callback. * @param[in] tts The TTS handle, the same handle for which the callback was set. + * @param[in] utt_id The utterance ID * @param[in] event The event type - * @param[in] buffer The synthesized pcm data - * @param[in] buffer_size The size of the buffer + * @param[in] pcm_data The synthesized pcm data. The @a pcm_data can be used only in the callback. To use outside, make a copy. + * @param[in] pcm_data_size The size of the pcm data + * @param[in] audio_type The audio type of pcm data + * @param[in] sample_rate The sampling rate of pcm data * @param[in] user_data The user data passed from the callback registration function * @pre An application registers this callback using tts_set_synthesized_pcm_cb() to get pcm data. * @see tts_set_synthesized_pcm_cb() * @see tts_unset_synthesized_pcm_cb() */ -typedef void (*tts_synthesized_pcm_cb)(tts_h tts, tts_synthesized_pcm_event_e event, char* buffer, int buffer_size, void *user_data); +typedef void (*tts_synthesized_pcm_cb)(tts_h tts, int utt_id, tts_synthesized_pcm_event_e event, const char* pcm_data, int pcm_data_size, tts_audio_type_e audio_type, int sample_rate, void *user_data); /** @@ -152,13 +175,31 @@ int tts_stop_pcm(tts_h tts); /** - * @brief Sets the default to be called when the synthesized pcm data is recieved. - * @since_tizen 7.5 + * @brief Sets the TTS playing mode. + * @since_tizen 8.0 * @param[in] tts The TTS handle - * @param callback The callback function to register - * @param user_data The user data to be passed to the callback function + * @param[in] mode The mode * @return @c 0 on success, - * otherwise a negative error value + * otherwise a negative error value + * @retval #TTS_ERROR_NONE Successful + * @retval #TTS_ERROR_NOT_SUPPORTED TTS NOT supported + * @retval #TTS_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #TTS_ERROR_INVALID_STATE Invalid state + * @pre The state should be #TTS_STATE_CREATED. + * @see tts_get_playing_mode() + * @see tts_play() + */ +int tts_set_playing_mode(tts_h tts, tts_playing_mode_e mode); + + +/** + * @brief Sets the callback function to receive the synthesized pcm data from the tts service. + * @since_tizen 8.0 + * @param[in] tts The TTS handle + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value * @retval #TTS_ERROR_NONE Successful * @retval #TTS_ERROR_NOT_SUPPORTED TTS NOT supported * @retval #TTS_ERROR_INVALID_PARAMETER Invalid parameter @@ -171,11 +212,11 @@ int tts_set_synthesized_pcm_cb(tts_h tts, tts_synthesized_pcm_cb callback, void* /** - * @brief Unsets the callback function. - * @since_tizen 7.5 - * @param tts The TTS handle + * @brief Unsets the callback function to receive synthesized PCM data from the tts service. + * @since_tizen 8.0 + * @param[in] tts The TTS handle * @return @c 0 on success, - * otherwise a negative error value + * otherwise a negative error value * @retval #TTS_ERROR_NONE Successful * @retval #TTS_ERROR_NOT_SUPPORTED TTS NOT supported * @retval #TTS_ERROR_INVALID_PARAMETER Invalid parameter diff --git a/server/ttsd_data.cpp b/server/ttsd_data.cpp index 08c4457f..9e94c435 100644 --- a/server/ttsd_data.cpp +++ b/server/ttsd_data.cpp @@ -37,6 +37,7 @@ typedef struct app_tts_state_e state; tts_app_play_type_e type; ttsd_mode_e mode; + ttsd_playing_mode_e playing_mode; ttse_result_event_e result_event; std::list m_speak_data; @@ -158,7 +159,7 @@ static app_data_s* __get_client_app_data(unsigned int uid) return nullptr; } -int ttsd_data_new_client(int pid, unsigned int uid, ttsd_mode_e mode, int registered_event_mask, tts_ipc_method_e method) +int ttsd_data_new_client(int pid, unsigned int uid, ttsd_mode_e mode, ttsd_playing_mode_e playing_mode, int registered_event_mask, tts_ipc_method_e method) { lock_guard lock(g_app_data_mutex); if(nullptr != __get_client_app_data(uid) ) { @@ -173,6 +174,7 @@ int ttsd_data_new_client(int pid, unsigned int uid, ttsd_mode_e mode, int regist app.state = APP_STATE_READY; app.type = TTS_APP_PLAY_TYPE_SYNTH; app.mode = mode; + app.playing_mode = playing_mode; app.result_event = TTSE_RESULT_EVENT_FAIL; app.ipc_method = method; app.credential = nullptr; @@ -337,6 +339,18 @@ ttsd_mode_e ttsd_data_get_mode(unsigned int uid) return app_data->mode; } +ttsd_playing_mode_e ttsd_data_get_playing_mode(unsigned int uid) +{ + lock_guard lock(g_app_data_mutex); + app_data_s* app_data = __get_client_app_data(uid); + if (nullptr == app_data) { + SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid); + return TTSD_PLAYING_MODE_BY_SERVICE; + } + + return app_data->playing_mode; +} + int ttsd_data_set_credential(unsigned int uid, const char* credential) { lock_guard lock(g_app_data_mutex); diff --git a/server/ttsd_data.h b/server/ttsd_data.h index 0b0d8ad1..dc102c82 100644 --- a/server/ttsd_data.h +++ b/server/ttsd_data.h @@ -70,7 +70,7 @@ ttsd_synthesis_control_e ttsd_data_get_synth_control(); typedef void (* ttsd_used_voice_cb)(const char* lang, int type); -int ttsd_data_new_client(int pid, unsigned int uid, ttsd_mode_e mode, int registered_event_mask, tts_ipc_method_e method); +int ttsd_data_new_client(int pid, unsigned int uid, ttsd_mode_e mode, ttsd_playing_mode_e playing_mode, int registered_event_mask, tts_ipc_method_e method); int ttsd_data_delete_client(unsigned int uid); @@ -84,6 +84,8 @@ tts_ipc_method_e ttsd_data_get_ipc_method(unsigned int uid); ttsd_mode_e ttsd_data_get_mode(unsigned int uid); +ttsd_playing_mode_e ttsd_data_get_playing_mode(unsigned int uid); + int ttsd_data_set_credential(unsigned int uid, const char* credential); char* ttsd_data_get_credential(unsigned int uid); diff --git a/server/ttsd_dbus.c b/server/ttsd_dbus.c index d709b605..ce426090 100644 --- a/server/ttsd_dbus.c +++ b/server/ttsd_dbus.c @@ -187,6 +187,51 @@ int ttsdc_dbus_send_set_service_state_message(int pid, unsigned int uid, int bef return TTSD_ERROR_NONE; } +int ttsdc_dbus_send_pcm(int pid, unsigned int uid, int uttid, int event, const void* pcm_data, int pcm_data_size, ttse_audio_type_e audio_type, int sample_rate) +{ + if (NULL == g_conn_sender) { + SLOG(LOG_ERROR, tts_tag(), "[Dbus ERROR] Dbus connection is not available"); + return -1; + } + + DBusMessage* msg = NULL; + + char target_if_name[64]; + snprintf(target_if_name, sizeof(target_if_name), "%s%d", TTS_CLIENT_SERVICE_INTERFACE, pid); + + /* create a message */ + msg = dbus_message_new_signal( + TTS_CLIENT_SERVICE_OBJECT_PATH, /* object name of the signal */ + target_if_name, /* interface name of the signal */ + TTSD_METHOD_SEND_PCM); /* name of the signal */ + + if (NULL == msg) { + SLOG(LOG_ERROR, tts_tag(), "[Dbus ERROR] Fail to create error message : uid(%u)", uid); + return -1; + } + + dbus_message_append_args(msg, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_INT32, &uttid, + DBUS_TYPE_INT32, &event, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pcm_data, pcm_data_size, + DBUS_TYPE_INT32, &audio_type, + DBUS_TYPE_INT32, &sample_rate, + DBUS_TYPE_INVALID); + + if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) { + SLOG(LOG_ERROR, tts_tag(), "[Dbus ERROR] Fail to Send"); + return TTSD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, tts_tag(), "[Dbus] SUCCESS Send"); + dbus_connection_flush(g_conn_sender); + } + + dbus_message_unref(msg); + + return 0; +} + int ttsdc_dbus_send_error_message(int pid, unsigned int uid, int uttid, int reason, char* err_msg) { if (NULL == g_conn_sender) { diff --git a/server/ttsd_dbus.h b/server/ttsd_dbus.h index 48cc4f80..ab8d93fa 100644 --- a/server/ttsd_dbus.h +++ b/server/ttsd_dbus.h @@ -15,6 +15,8 @@ #ifndef __TTSD_DBUS_h__ #define __TTSD_DBUS_h__ +#include "ttsd_main.h" + #ifdef __cplusplus extern "C" { #endif @@ -35,6 +37,8 @@ int ttsdc_dbus_send_set_state_message(int pid, unsigned int uid, int state); int ttsdc_dbus_send_set_service_state_message(int pid, unsigned int uid, int before_state, int current_state); +int ttsdc_dbus_send_pcm(int pid, unsigned int uid, int uttid, int event, const void* pcm_data, int pcm_data_size, ttse_audio_type_e audio_type, int sample_rate); + #ifdef __cplusplus } diff --git a/server/ttsd_dbus_server.c b/server/ttsd_dbus_server.c index 93a44bd3..746583fa 100644 --- a/server/ttsd_dbus_server.c +++ b/server/ttsd_dbus_server.c @@ -32,11 +32,13 @@ int ttsd_dbus_server_hello(DBusConnection* conn, DBusMessage* msg) int pid; unsigned int uid; int mode = 0; + int playing_mode = 0; int registered_event_mask = 0; dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INT32, &mode, + DBUS_TYPE_INT32, &playing_mode, DBUS_TYPE_INT32, ®istered_event_mask, DBUS_TYPE_INVALID); @@ -44,7 +46,7 @@ int ttsd_dbus_server_hello(DBusConnection* conn, DBusMessage* msg) SLOG(LOG_ERROR, tts_tag(), "[IN ERROR] ttsd Hello : get arguments error (%s)", err.message); dbus_error_free(&err); } else { - SLOG(LOG_INFO, tts_tag(), "[IN] ttsd hello : pid(%d), uid(%u), mode(%d)", pid, uid, mode); + SLOG(LOG_INFO, tts_tag(), "[IN] ttsd hello : pid(%d), uid(%u), mode(%d), playing_mode(%d)", pid, uid, mode, playing_mode); bool is_initialized = false; bool is_credential_needed = false; int credential_needed = 0; @@ -52,7 +54,7 @@ int ttsd_dbus_server_hello(DBusConnection* conn, DBusMessage* msg) ttsd_server_is_already_initialized(pid, uid, &is_initialized); if (false == is_initialized) { - ret = ttsd_server_initialize(pid, uid, (ttsd_mode_e)mode, registered_event_mask, TTS_IPC_METHOD_DBUS, &is_credential_needed); + ret = ttsd_server_initialize(pid, uid, (ttsd_mode_e)mode, (ttsd_playing_mode_e)playing_mode, registered_event_mask, TTS_IPC_METHOD_DBUS, &is_credential_needed); if (0 != ret) { SLOG(LOG_ERROR, tts_tag(), "[IN ERROR] ttsd Hello : server initialize, ret(%d)", ret); } @@ -104,6 +106,7 @@ int ttsd_dbus_server_initialize(DBusConnection* conn, DBusMessage* msg) unsigned int uid; bool credential_needed = 0; int mode = 0; + int playing_mode = 0; int registered_event_mask = 0; int ret = 0; @@ -111,6 +114,7 @@ int ttsd_dbus_server_initialize(DBusConnection* conn, DBusMessage* msg) DBUS_TYPE_INT32, &pid, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INT32, &mode, + DBUS_TYPE_INT32, &playing_mode, DBUS_TYPE_INT32, ®istered_event_mask, DBUS_TYPE_INVALID); @@ -121,8 +125,8 @@ int ttsd_dbus_server_initialize(DBusConnection* conn, DBusMessage* msg) dbus_error_free(&err); ret = TTSD_ERROR_OPERATION_FAILED; } else { - SECURE_SLOG(LOG_DEBUG, tts_tag(), "[IN] tts initialize : pid(%d), uid(%u), mode(%d)", pid, uid, mode); - ret = ttsd_server_initialize(pid, uid, (ttsd_mode_e)mode, registered_event_mask, TTS_IPC_METHOD_DBUS, &credential_needed); + SECURE_SLOG(LOG_DEBUG, tts_tag(), "[IN] tts initialize : pid(%d), uid(%u), mode(%d), playing_mode(%d)", pid, uid, mode, playing_mode); + ret = ttsd_server_initialize(pid, uid, (ttsd_mode_e)mode, (ttsd_playing_mode_e)playing_mode, registered_event_mask, TTS_IPC_METHOD_DBUS, &credential_needed); } DBusMessage* reply; diff --git a/server/ttsd_ipc.c b/server/ttsd_ipc.c index 72646a48..b88ec99e 100644 --- a/server/ttsd_ipc.c +++ b/server/ttsd_ipc.c @@ -19,10 +19,10 @@ static int(*ttsd_dbus_vtable[])() = {&ttsd_dbus_open_connection, &ttsd_dbus_close_connection, &ttsdc_dbus_send_utt_start_message, &ttsdc_dbus_send_utt_finish_message, &ttsdc_dbus_send_set_state_message, &ttsdc_dbus_send_error_message, - &ttsdc_dbus_send_set_service_state_message}; + &ttsdc_dbus_send_set_service_state_message, &ttsdc_dbus_send_pcm}; static int(*ttsd_tidl_vtable[])() = {&ttsd_tidl_open_connection, &ttsd_tidl_close_connection, &ttsdc_tidl_send_utt_start_message, &ttsdc_tidl_send_utt_finish_message, &ttsdc_tidl_send_set_state_message, &ttsdc_tidl_send_error_message, - &ttsdc_tidl_send_set_service_state_message}; + &ttsdc_tidl_send_set_service_state_message, &ttsdc_tidl_send_pcm}; int ttsd_ipc_open_connection() { @@ -187,3 +187,29 @@ int ttsdc_ipc_send_set_service_state_message(int pid, unsigned int uid, int befo return TTSD_ERROR_OPERATION_FAILED; } + +int ttsdc_ipc_send_pcm(int pid, unsigned int uid, int uttid, int event, const void* pcm_data, int pcm_data_size, ttse_audio_type_e audio_type, int sample_rate) +{ + SLOG(LOG_INFO, tts_tag(), "[IPC] ttsdc_ipc_send_pcm"); + + if (0 > ttsd_data_is_client(uid)) { + SLOG(LOG_ERROR, tts_tag(), "[ERROR] uid is not valid (%u)", uid); + return TTSD_ERROR_INVALID_PARAMETER; + } + + switch (ttsd_data_get_ipc_method(uid)) + { + case TTS_IPC_METHOD_DBUS: + SLOG(LOG_DEBUG, tts_tag(), "[IPC] ipc method : dbus"); + return ttsd_dbus_vtable[SEND_PCM](pid, uid, uttid, event, pcm_data, pcm_data_size, audio_type, sample_rate); + + case TTS_IPC_METHOD_TIDL: + SLOG(LOG_DEBUG, tts_tag(), "[IPC] ipc method : tidl"); + return ttsd_tidl_vtable[SEND_PCM](pid, uid, uttid, event, pcm_data, pcm_data_size, audio_type, sample_rate); + + default: + SLOG(LOG_ERROR, tts_tag(), "[ERROR] method is not valid"); + } + + return TTSD_ERROR_OPERATION_FAILED; +} \ No newline at end of file diff --git a/server/ttsd_ipc.h b/server/ttsd_ipc.h index c6eb6b7f..5d16cfdb 100644 --- a/server/ttsd_ipc.h +++ b/server/ttsd_ipc.h @@ -28,7 +28,8 @@ typedef enum { SEND_UTTERANCE_FINISH, SEND_SET_STATE, SEND_ERROR, - SEND_SET_SERVICE_STATE + SEND_SET_SERVICE_STATE, + SEND_PCM } ttsd_ipc_vtable_e; int ttsd_ipc_open_connection(); @@ -47,6 +48,7 @@ int ttsdc_ipc_send_set_state_message(int pid, unsigned int uid, int state); int ttsdc_ipc_send_set_service_state_message(int pid, unsigned int uid, int before_state, int current_state); +int ttsdc_ipc_send_pcm(int pid, unsigned int uid, int uttid, int event, const void* pcm_data, int pcm_data_size, ttse_audio_type_e audio_type, int sample_rate); #ifdef __cplusplus } diff --git a/server/ttsd_main.h b/server/ttsd_main.h index 40e886c3..c39559ab 100644 --- a/server/ttsd_main.h +++ b/server/ttsd_main.h @@ -60,6 +60,11 @@ typedef enum { TTSD_MODE_INTERRUPT /**< Interrupt mode */ } ttsd_mode_e; +typedef enum { + TTSD_PLAYING_MODE_BY_SERVICE = 0, /**< Mode for TTS playing on TTS service */ + TTSD_PLAYING_MODE_BY_CLIENT = 1, /**< Mode for TTS playing on TTS client */ +} ttsd_playing_mode_e; + typedef enum { TTSD_INTERRUPTED_PAUSED = 0, /**< Current state change 'Pause' */ TTSD_INTERRUPTED_STOPPED /**< Current state change 'Ready' */ diff --git a/server/ttsd_server.c b/server/ttsd_server.c index 050486d9..2c142825 100644 --- a/server/ttsd_server.c +++ b/server/ttsd_server.c @@ -32,11 +32,12 @@ #define TIME_DIFF(start, end) \ ((uint64_t)((end).tv_sec - (start).tv_sec) * 1000000 + (((end).tv_nsec - (start).tv_nsec) / 1000)) / 1000 -static struct timespec g_request_playing, g_start_playing; +static struct timespec g_request_playing, g_start_playing, g_finish_playing; static double g_avg_latency; static double g_min_latency; static double g_max_latency; static int g_file_num; +static int g_total_data_size; typedef struct { unsigned int uid; @@ -117,8 +118,8 @@ static void __synthesis(unsigned int uid) speak_data_s* speak_data = NULL; int ret = ttsd_data_get_speak_data(uid, &speak_data); if (TTSD_ERROR_NONE != ret || NULL == speak_data) { - SLOG(LOG_DEBUG, tts_tag(), "@@@ Fail to get speak data. ret(%d)", ret); - SLOG(LOG_DEBUG, tts_tag(), "@@@ SYNTHESIS END"); + SLOG(LOG_DEBUG, tts_tag(), "@@@ No speak data. ret(%d)", ret); + SLOG(LOG_INFO, tts_tag(), "@@@ SYNTHESIS END"); return; } @@ -213,6 +214,23 @@ int ttsd_send_error(ttse_error_e error, const char* msg) return 0; } +static int ttsd_convert_audio_type_to_bytes(ttse_audio_type_e audio_type) +{ + int ret = 0; + switch (audio_type) { + case TTSE_AUDIO_TYPE_RAW_S16: + ret = 2; // 16bit + break; + case TTSE_AUDIO_TYPE_RAW_U8: + ret = 1; // 8bit + break; + default: + ret = 2; // Default 16bit + break; + } + return ret; +} + int ttsd_send_result(ttse_result_event_e event, const void* data, unsigned int data_size, ttse_audio_type_e audio_type, int rate, void* user_data) { SLOG(LOG_DEBUG, tts_tag(), "@@@ SEND SYNTHESIS RESULT START"); @@ -269,27 +287,51 @@ int ttsd_send_result(ttse_result_event_e event, const void* data, unsigned int d g_min_latency = (d_latency < g_min_latency) ? d_latency : g_min_latency; g_max_latency = (d_latency > g_max_latency) ? d_latency : g_max_latency; g_file_num++; + g_total_data_size = 0; + g_total_data_size += data_size; SLOG(LOG_INFO, tts_tag(), "[Server] File num(%d), Avg Latency(%lf), Min(%lf), Max(%lf)", g_file_num, (g_avg_latency / (double)g_file_num), g_min_latency, g_max_latency); } else if (TTSE_RESULT_EVENT_FINISH == event) { SLOG(LOG_INFO, tts_tag(), "[SERVER] Event : TTSE_RESULT_EVENT_FINISH"); SECURE_SLOG(LOG_DEBUG, tts_tag(), "[SERVER] Result Info : uid(%u), utt(%d), data(%p), data size(%d) audiotype(%d) rate(%d)", uid, uttid, data, data_size, audio_type, rate); + + g_total_data_size += data_size; + int audio_type_bytes = ttsd_convert_audio_type_to_bytes(audio_type); + /* Calculate xRT */ + clock_gettime(CLOCK_MONOTONIC_RAW, &g_finish_playing); + long long int time_processing = (uint64_t)TIME_DIFF(g_request_playing, g_finish_playing); + long long int time_speech = (long long int)(1000 * g_total_data_size * sizeof(short) / (rate * audio_type_bytes)); + double xRT = (double)(time_processing) / (double)time_speech; + SLOG(LOG_INFO, tts_tag(), "[SERVER] time_processing : %lld, time_speech : %lld, total data size: %d", time_processing, time_speech, g_total_data_size); + SLOG(LOG_INFO, tts_tag(), "[SERVER] xRT : %lf", xRT); } else { /*if (TTSE_RESULT_EVENT_CONTINUE == event) SLOG(LOG_DEBUG, tts_tag(), "[SERVER] Event : TTSE_RESULT_EVENT_CONTINUE");*/ + g_total_data_size += data_size; } - /* add wav data */ - sound_data_s* sound_data = ttsd_data_create_sound_data(uttid, data, data_size, event, audio_type, rate, 0); - if (NULL == sound_data) { - SLOG(LOG_ERROR, tts_tag(), "[SERVER ERROR] Out of memory"); - return TTSD_ERROR_OUT_OF_MEMORY; - } + ttsd_playing_mode_e playing_mode = ttsd_data_get_playing_mode(uid); + SLOG(LOG_DEBUG, tts_tag(), "[SERVER] uid(%d), playing mode(%d)", uid, playing_mode); + if (TTSD_PLAYING_MODE_BY_SERVICE == playing_mode) { + /* add wav data */ + sound_data_s* sound_data = ttsd_data_create_sound_data(uttid, data, data_size, event, audio_type, rate, 0); + if (NULL == sound_data) { + SLOG(LOG_ERROR, tts_tag(), "[SERVER ERROR] Out of memory"); + return TTSD_ERROR_OUT_OF_MEMORY; + } - if (0 != ttsd_data_add_sound_data(uid, sound_data)) { - SECURE_SLOG(LOG_ERROR, tts_tag(), "[SERVER ERROR] Fail to add sound data : uid(%u)", uid); - ttsd_data_destroy_sound_data(sound_data); + if (0 != ttsd_data_add_sound_data(uid, sound_data)) { + SECURE_SLOG(LOG_ERROR, tts_tag(), "[SERVER ERROR] Fail to add sound data : uid(%u)", uid); + ttsd_data_destroy_sound_data(sound_data); - return TTSD_ERROR_OPERATION_FAILED; + return TTSD_ERROR_OPERATION_FAILED; + } + } else { /* TTSD_PLAYING_MODE_BY_CLIENT */ + /* send pcm data to client */ + int tmp_pid = ttsd_data_get_pid(uid); + if (0 != ttsdc_ipc_send_pcm(tmp_pid, uid, uttid, event, data, data_size, audio_type, rate)) { + SLOG(LOG_ERROR, tts_tag(), "[SERVER ERROR] Fail to send pcm data to client"); + return TTSD_ERROR_OPERATION_FAILED; + } } if (event == TTSE_RESULT_EVENT_FINISH) { @@ -790,7 +832,7 @@ static int __check_app_agreed(int pid, unsigned int uid, bool credential_needed) return TTSD_ERROR_NONE; } -int ttsd_server_initialize(int pid, unsigned int uid, ttsd_mode_e mode, int registered_event_mask, tts_ipc_method_e method, bool* credential_needed) +int ttsd_server_initialize(int pid, unsigned int uid, ttsd_mode_e mode, ttsd_playing_mode_e playing_mode, int registered_event_mask, tts_ipc_method_e method, bool* credential_needed) { SLOG(LOG_INFO, tts_tag(), "[Server] Server initialize"); @@ -799,7 +841,7 @@ int ttsd_server_initialize(int pid, unsigned int uid, ttsd_mode_e mode, int regi return TTSD_ERROR_NONE; } - if (TTSD_ERROR_NONE != ttsd_data_new_client(pid, uid, mode, registered_event_mask, method)) { + if (TTSD_ERROR_NONE != ttsd_data_new_client(pid, uid, mode, playing_mode, registered_event_mask, method)) { SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to add client info"); return TTSD_ERROR_OPERATION_FAILED; } diff --git a/server/ttsd_server.h b/server/ttsd_server.h index a40f9eb2..1a31e72c 100644 --- a/server/ttsd_server.h +++ b/server/ttsd_server.h @@ -49,7 +49,7 @@ int ttsd_set_activated_mode_changed_cb(ttse_activated_mode_changed_cb callback); int ttsd_server_is_already_initialized(int pid, unsigned int uid, bool* is_initialized); -int ttsd_server_initialize(int pid, unsigned int uid, ttsd_mode_e mode, int registered_event_mask, tts_ipc_method_e method, bool* credential_needed); +int ttsd_server_initialize(int pid, unsigned int uid, ttsd_mode_e mode, ttsd_playing_mode_e playing_mode, int registered_event_mask, tts_ipc_method_e method, bool* credential_needed); int ttsd_server_finalize(unsigned int uid); diff --git a/server/ttsd_tidl.c b/server/ttsd_tidl.c index 0cb8403c..22a382be 100644 --- a/server/ttsd_tidl.c +++ b/server/ttsd_tidl.c @@ -137,10 +137,10 @@ static void __destroy_client_cb(rpc_port_stub_tts_context_h context, void *user_ free(sender); } -static void __register_cb(rpc_port_stub_tts_context_h context, int pid, int uid, int mode, int registered_event_mask, rpc_port_stub_tts_notify_cb_h callback, void *user_data) +static void __register_cb(rpc_port_stub_tts_context_h context, int pid, int uid, int mode, int playing_mode, int registered_event_mask, rpc_port_stub_tts_notify_cb_h callback, void *user_data) { unsigned int u_uid = (unsigned int)uid; - SLOG(LOG_ERROR, tts_tag(), ">>>>> TTS REGISTER CALLBACK uid(%u), mode(%d), registered mask(%x)", u_uid, mode, registered_event_mask); + SLOG(LOG_ERROR, tts_tag(), ">>>>> TTS REGISTER CALLBACK uid(%u), mode(%d), playing_mode(%d), registered mask(%x)", u_uid, mode, playing_mode, registered_event_mask); bool is_initialized = false; ttsd_server_is_already_initialized(pid, u_uid, &is_initialized); @@ -149,7 +149,7 @@ static void __register_cb(rpc_port_stub_tts_context_h context, int pid, int uid, int credential_needed = 0; if (false == is_initialized) { bool is_credential_needed = false; - ret = ttsd_server_initialize(pid, u_uid, mode, registered_event_mask, TTS_IPC_METHOD_TIDL, &is_credential_needed); + ret = ttsd_server_initialize(pid, u_uid, mode, playing_mode, registered_event_mask, TTS_IPC_METHOD_TIDL, &is_credential_needed); if (0 != ret) { SLOG(LOG_ERROR, tts_tag(), "[IN ERROR] ttsd Hello : server initialize, ret(%d)", ret); } @@ -261,12 +261,12 @@ int ttsdc_tidl_send_hello(int pid, unsigned int uid, int ret, int credential_nee return TTSD_ERROR_NONE; } -static int __initialize_cb(rpc_port_stub_tts_context_h context, int pid, int uid, int mode, int registered_event_mask, bool *credential_needed, void *user_data) +static int __initialize_cb(rpc_port_stub_tts_context_h context, int pid, int uid, int mode, int playing_mode, int registered_event_mask, bool *credential_needed, void *user_data) { unsigned int u_uid = (unsigned int)uid; SECURE_SLOG(LOG_ERROR, tts_tag(), "[IN] tts initialize : pid(%d), uid(%u), mode(%d)", pid, u_uid, mode); - if (0 != ttsd_server_initialize(pid, u_uid, mode, registered_event_mask, TTS_IPC_METHOD_TIDL, credential_needed)) { + if (0 != ttsd_server_initialize(pid, u_uid, mode, playing_mode, registered_event_mask, TTS_IPC_METHOD_TIDL, credential_needed)) { return TTSD_ERROR_OPERATION_FAILED; } @@ -588,3 +588,31 @@ int ttsdc_tidl_send_error_message(int pid, unsigned int uid, int uttid, int reas bundle_free(msg); return TTSD_ERROR_NONE; } + +int ttsdc_tidl_send_pcm(int pid, unsigned int uid, int uttid, int event, const void* pcm_data, int pcm_data_size, ttse_audio_type_e audio_type, int sample_rate) +{ + SLOG(LOG_DEBUG, tts_tag(), "[TIDL] ttsdc_tidl_send_pcm"); + + char tmp_uttid[10] = {0, }; + char tmp_event[10] = {0, }; + char tmp_audio_type[10] = {0, }; + char tmp_sample_rate[10] = {0, }; + + bundle* msg = bundle_create(); + snprintf(tmp_uttid, 10, "%d", uttid); + snprintf(tmp_event, 10, "%d", event); + snprintf(tmp_audio_type, 10, "%d", audio_type); + snprintf(tmp_sample_rate, 10, "%d", sample_rate); + bundle_add_str(msg, TTS_BUNDLE_METHOD, TTSD_METHOD_SEND_PCM); + bundle_add_str(msg, TTS_BUNDLE_UTTID, tmp_uttid); + bundle_add_str(msg, TTS_BUNDLE_PCM_EVENT, tmp_event); + bundle_add_byte(msg, TTS_BUNDLE_PCM_DATA, pcm_data, (const size_t)pcm_data_size); + bundle_add_str(msg, TTS_BUNDLE_PCM_AUDIO_TYPE, tmp_audio_type); + bundle_add_str(msg, TTS_BUNDLE_PCM_SAMPLE_RATE, tmp_sample_rate); + + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTSD SEND PCM MSG"); + __send_msg(pid, uid, msg); + + bundle_free(msg); + return TTSD_ERROR_NONE; +} diff --git a/server/ttsd_tidl.h b/server/ttsd_tidl.h index 4aafb628..89dac1a1 100644 --- a/server/ttsd_tidl.h +++ b/server/ttsd_tidl.h @@ -35,6 +35,8 @@ int ttsdc_tidl_send_error_message(int pid, unsigned int uid, int uttid, int reas int ttsdc_tidl_send_set_service_state_message(int pid, unsigned int uid, int before_state, int current_state); +int ttsdc_tidl_send_pcm(int pid, unsigned int uid, int uttid, int event, const void* pcm_data, int pcm_data_size, ttse_audio_type_e audio_type, int sample_rate); + #ifdef __cplusplus } #endif diff --git a/tidl/tts.tidl b/tidl/tts.tidl index 1d09a7be..daa2871b 100644 --- a/tidl/tts.tidl +++ b/tidl/tts.tidl @@ -1,9 +1,9 @@ interface tts { void notify_cb(int pid, int uid, bundle msg) delegate; - void register_cb(int pid, int uid, int mode, int registered_event_mask, notify_cb callback) async; + void register_cb(int pid, int uid, int mode, int playing_mode, int registered_event_mask, notify_cb callback) async; int register_cb_sync(int pid, int uid, notify_cb callback); - int initialize(in int pid, in int uid, in int mode, in int registered_event_mask, out bool credential_needed); + int initialize(in int pid, in int uid, in int mode, in int playing_mode, in int registered_event_mask, out bool credential_needed); int finalize(in int uid); int add_text(int uid, string text, string lang, int vctype, int speed, int uttid, string credential); int stop(in int uid);