Implement internal API for synthesized PCM 45/298145/1
authorwn.jang <wn.jang@samsung.com>
Fri, 9 Dec 2022 09:39:39 +0000 (18:39 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Fri, 1 Sep 2023 07:15:25 +0000 (16:15 +0900)
Change-Id: I01563b86646952c6d55d3e111e910223a6b4c218

26 files changed:
client/tts.c
client/tts_client.c
client/tts_client.h
client/tts_core.c
client/tts_core.h
client/tts_dbus.c
client/tts_dbus.h
client/tts_ipc.c
client/tts_ipc.h
client/tts_tidl.c
client/tts_tidl.h
common/tts_defs.h
include/tts_internal.h
server/ttsd_data.cpp
server/ttsd_data.h
server/ttsd_dbus.c
server/ttsd_dbus.h
server/ttsd_dbus_server.c
server/ttsd_ipc.c
server/ttsd_ipc.h
server/ttsd_main.h
server/ttsd_server.c
server/ttsd_server.h
server/ttsd_tidl.c
server/ttsd_tidl.h
tidl/tts.tidl

index a7b67f3a72afa50e039dc85e03383ad21d8c78e5..191d2d46d39bd3dbac42a197df14854f9c840df7 100644 (file)
@@ -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);
index 551041fa01fd08759bf921b44c83e090186d2a89..77f21e4f98f682091287e0a10f59a821939bcaa8 100644 (file)
@@ -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)) {
index 1a7d04689b33489410b200c62ba592409b07ac33..1f90b245560a3eefac1a11e9cd30aa678939a789 100644 (file)
@@ -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);
 
index 3cf8791d306bd33da73cdfd2d9db40889676017d..e2a1ebe4a2ae83cfc8abef4a682d0ca2ebc90a9a 100644 (file)
@@ -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) {
index 75632e81929fcd01ef007715f59a76dcfa01dde4..c0c446b8d3479a9efd223a7eec7dd34e4acd90ba 100644 (file)
 #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);
index 6c3cfcb0a8829e11ffc356a15f26fd84f0c0f2c1..d4f9114ef5078ec21e95a3f90db071a2a39cecb9 100644 (file)
@@ -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, &registered_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, &registered_event_mask,
                        DBUS_TYPE_INVALID)) {
                dbus_message_unref(msg);
index a0eaeb70b0bd2b1050bef5e42115bfa0d947207b..59eeda58508fcdb4cd06a5b188e097a38821e8f6 100644 (file)
@@ -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);
 
index 9b4eb3662d7640d3ea0e66b78fdc9d77befa3ab4..2ec5e535e7eb132c63fb927e534efe3e37dc1c75 100644 (file)
@@ -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)
index 34bad752077e9f56c2a8908411db0f8b4bdef28d..956161ea4da37adecee50bf7d5893a1c55bf881f 100644 (file)
@@ -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);
 
index aef57d6b6d7c71ecb37c2c583db4db44b9ae50a9..f1e4f8c20539353be54ceb29e9bb15bf136a0987 100644 (file)
@@ -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);
index 19af39ded717aacb4e4cdb03888a6d58c2d99855..2b2d7bab9ff9235020c5849357b69c89b79e699c 100644 (file)
@@ -14,7 +14,8 @@
 #ifndef __TTS_TIDL_H_
 #define __TTS_TIDL_H_
 
-#include <tts.h>
+#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);
 
index 300b6ba0b3416711fa7d7a920cfeebc269a98864..00bfcfa3f73e4a7c2ae9b332dcb0f8991fcd1b23 100644 (file)
@@ -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"
 
 
 /******************************************************************************************
index 0aeee265f063cb7a8522ad12396b1896d75690c2..ef483338e743fc36846051ed7176bcf84e991a41 100644 (file)
@@ -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
index 08c4457fdcd7444f3f46abbd0dc1c52ba412bf2a..9e94c435a230bb56bc922db5cff550a2353f39e5 100644 (file)
@@ -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<speak_data_s*> 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<mutex> 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<mutex> 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<mutex> lock(g_app_data_mutex);
index 0b0d8ad137d1792b1a93640241a936e5815282d5..dc102c822490bd3ea15e661948eedee6a07f4d5c 100644 (file)
@@ -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);
index d709b605561bc5f30c5b4ef8024388a4620e2756..ce4260900e34a39ba349788d911adb2ba4c0a3b3 100644 (file)
@@ -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) {
index 48cc4f8021797a4db7fd96dee8a1f157a57c58df..ab8d93faa1610c4db09e5f375b6aa98766e45710 100644 (file)
@@ -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
 }
index 93a44bd31a9b8256851076233fa5e0920dd34c85..746583fab9a380c2883adbb5e5213e8922fb3e70 100644 (file)
@@ -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, &registered_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, &registered_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;
index 72646a48cac9048147e4678255d531be4270ace3..b88ec99e144bd55dffd084fe20a664b4bc971e17 100644 (file)
 
 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
index c6eb6b7fcbf721e19c02969322c4b474a520a704..5d16cfdb56ed38485243d1e8a575e9e2a8fcd1a7 100644 (file)
@@ -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
 }
index 40e886c3e31599d392eb154e69b5c1b78b3ccf41..c39559ab5968e0fdb5f771efdb3450be7a9e3da4 100644 (file)
@@ -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' */
index 050486d93c2ab1e592fc8b41352d11635289e983..2c1428254dd9f49bd2c5688aa1f04d5c9f1b197b 100644 (file)
 #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;
        }
index a40f9eb20a62eece4de0d2cdcc29664e76d4b5a1..1a31e72c5aa1f7a44a202a02b47ebaf5b6bf9cab 100644 (file)
@@ -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);
 
index 0cb8403c00e99d33e8779bce75b489f084ffebdd..22a382be844c00b45a04014d4816ab65de2ed56c 100644 (file)
@@ -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;
+}
index 4aafb628525b0bd150432f9df075d8ed6e6f83e3..89dac1a1facaf80d4a2f23dea894284106c26deb 100644 (file)
@@ -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
index 1d09a7be482edd03287b5cde444a4ca33a4e3b5a..daa2871b017d23bf385ef98da448f3e56eb99308 100644 (file)
@@ -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);