From: Kwangyoun Kim Date: Tue, 18 Apr 2017 11:32:39 +0000 (+0900) Subject: Add internal method to play pcm data X-Git-Tag: accepted/tizen/unified/20170512.023656~1^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Ftts.git;a=commitdiff_plain;h=e1f07829e0af752017af94568b051a285912c114 Add internal method to play pcm data Change-Id: Ib37f104bdf4e1cee952ee3abe3437b9e00f01a7e --- diff --git a/client/tts.c b/client/tts.c old mode 100755 new mode 100644 index 1caaf58..18ca04d --- a/client/tts.c +++ b/client/tts.c @@ -2331,3 +2331,202 @@ int tts_unset_engine_changed_cb(tts_h tts) return 0; } +int tts_add_pcm(tts_h tts, int event, const void* data, unsigned int data_size, int audio_type, int rate) +{ + if (0 != __tts_get_feature_enabled()) { + return TTS_ERROR_NOT_SUPPORTED; + } + + SLOG(LOG_INFO, TAG_TTSC, "===== Add pcm tts"); + + if (NULL == tts) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null."); + SLOG(LOG_DEBUG, TAG_TTSC, "====="); + SLOG(LOG_DEBUG, TAG_TTSC, " "); + return TTS_ERROR_INVALID_PARAMETER; + } + + tts_client_s* client = tts_client_get(tts); + + if (NULL == client) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid."); + SLOG(LOG_DEBUG, TAG_TTSC, "====="); + SLOG(LOG_DEBUG, TAG_TTSC, " "); + return TTS_ERROR_INVALID_PARAMETER; + } + + if (TTS_STATE_PLAYING != client->current_state) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid."); + return TTS_ERROR_INVALID_STATE; + } + + if (false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode) { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Screen reader option is NOT available. Ignore this request"); + return TTS_ERROR_INVALID_STATE; + } + + int ret = -1; + int count = 0; + while (0 != ret) { + ret = tts_dbus_request_add_pcm(client->uid, event, data, data_size, audio_type, rate); + if (0 != ret) { + if (TTS_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry add pcm : %s", __tts_get_error_code(ret)); + usleep(10000); + count++; + if (TTS_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); + return ret; + } + } + } + } + + SLOG(LOG_DEBUG, TAG_TTSC, "====="); + SLOG(LOG_DEBUG, TAG_TTSC, " "); + + return TTS_ERROR_NONE; +} + +int tts_play_pcm(tts_h tts) +{ + if (0 != __tts_get_feature_enabled()) { + return TTS_ERROR_NOT_SUPPORTED; + } + + SLOG(LOG_INFO, TAG_TTSC, "===== Play pcm tts"); + + if (NULL == tts) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null."); + SLOG(LOG_DEBUG, TAG_TTSC, "====="); + SLOG(LOG_DEBUG, TAG_TTSC, " "); + return TTS_ERROR_INVALID_PARAMETER; + } + + tts_client_s* client = tts_client_get(tts); + + if (NULL == client) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid."); + SLOG(LOG_DEBUG, TAG_TTSC, "====="); + SLOG(LOG_DEBUG, TAG_TTSC, " "); + return TTS_ERROR_INVALID_PARAMETER; + } + + if (TTS_STATE_PLAYING == client->current_state || TTS_STATE_CREATED == client->current_state) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid."); + return TTS_ERROR_INVALID_STATE; + } + + if (false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode) { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Screen reader option is NOT available. Ignore this request"); + return TTS_ERROR_INVALID_STATE; + } + + int ret = -1; + int count = 0; + while (0 != ret) { + ret = tts_dbus_request_play_pcm(client->uid); + if (0 != ret) { + if (TTS_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry play pcm : %s", __tts_get_error_code(ret)); + usleep(10000); + count++; + if (TTS_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); + return ret; + } + } + } + } + + client->before_state = client->current_state; + client->current_state = TTS_STATE_PLAYING; + + if (NULL != client->state_changed_cb) { + tts_client_use_callback(client); + client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data); + tts_client_not_use_callback(client); + SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called"); + } + + SLOG(LOG_DEBUG, TAG_TTSC, "====="); + SLOG(LOG_DEBUG, TAG_TTSC, " "); + + return TTS_ERROR_NONE; +} + +int tts_stop_pcm(tts_h tts) +{ + if (0 != __tts_get_feature_enabled()) { + return TTS_ERROR_NOT_SUPPORTED; + } + + SLOG(LOG_INFO, TAG_TTSC, "===== Stop pcm tts"); + + if (NULL == tts) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null."); + SLOG(LOG_DEBUG, TAG_TTSC, "====="); + SLOG(LOG_DEBUG, TAG_TTSC, " "); + return TTS_ERROR_INVALID_PARAMETER; + } + + tts_client_s* client = tts_client_get(tts); + + if (NULL == client) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid."); + SLOG(LOG_DEBUG, TAG_TTSC, "====="); + SLOG(LOG_DEBUG, TAG_TTSC, " "); + return TTS_ERROR_INVALID_PARAMETER; + } + + if (TTS_STATE_PLAYING != client->current_state) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] The current state is invalid."); + return TTS_ERROR_INVALID_STATE; + } + + if (false == g_screen_reader && TTS_MODE_SCREEN_READER == client->mode) { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Screen reader option is NOT available. Ignore this request"); + return TTS_ERROR_INVALID_STATE; + } + + int ret = -1; + int count = 0; + while (0 != ret) { + ret = tts_dbus_request_stop_pcm(client->uid); + if (0 != ret) { + if (TTS_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %s", __tts_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] retry stop pcm : %s", __tts_get_error_code(ret)); + usleep(10000); + count++; + if (TTS_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to request"); + return ret; + } + } + } + } + + client->before_state = client->current_state; + client->current_state = TTS_STATE_READY; + + if (NULL != client->state_changed_cb) { + tts_client_use_callback(client); + client->state_changed_cb(client->tts, client->before_state, client->current_state, client->state_changed_user_data); + tts_client_not_use_callback(client); + SLOG(LOG_DEBUG, TAG_TTSC, "State changed callback is called"); + } + + SLOG(LOG_DEBUG, TAG_TTSC, "====="); + SLOG(LOG_DEBUG, TAG_TTSC, " "); + + return TTS_ERROR_NONE; +} diff --git a/client/tts_dbus.c b/client/tts_dbus.c index df39b69..c85edfb 100644 --- a/client/tts_dbus.c +++ b/client/tts_dbus.c @@ -936,3 +936,185 @@ int tts_dbus_request_pause(int uid) return result; } + +int tts_dbus_request_play_pcm(int uid) +{ + DBusMessage* msg; + DBusError err; + dbus_error_init(&err); + + msg = __tts_dbus_make_message(uid, TTS_METHOD_PLAY_PCM); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts play pcm : Fail to make message"); + return TTS_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_TTSC, ">>>> Request tts play pcm : uid(%d)", uid); + } + + if (true != dbus_message_append_args(msg, + DBUS_TYPE_INT32, &uid, + DBUS_TYPE_INVALID)) { + dbus_message_unref(msg); + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args"); + return TTS_ERROR_OPERATION_FAILED; + } + + DBusMessage* result_msg; + int result = TTS_ERROR_OPERATION_FAILED; + + result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, WAITING_TIME, &err); + dbus_message_unref(msg); + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Send error (%s)", err.message); + dbus_error_free(&err); + } + + if (NULL != result_msg) { + dbus_message_get_args(result_msg, &err, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_TTSC, "<<<< tts play pcm : Get arguments error (%s)", err.message); + dbus_error_free(&err); + result = TTS_ERROR_OPERATION_FAILED; + } + dbus_message_unref(result_msg); + + if (0 == result) { + SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts play pcm : result(%d)", result); + } else { + SLOG(LOG_ERROR, TAG_TTSC, "<<<< tts play pcm : result(%d)", result); + } + } else { + SLOG(LOG_ERROR, TAG_TTSC, "<<<< Result message is NULL "); + tts_dbus_reconnect(); + result = TTS_ERROR_TIMED_OUT; + } + + return result; +} + +int tts_dbus_request_stop_pcm(int uid) +{ + DBusMessage* msg; + DBusError err; + dbus_error_init(&err); + + msg = __tts_dbus_make_message(uid, TTS_METHOD_STOP_PCM); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts stop pcm : Fail to make message"); + return TTS_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_TTSC, ">>>> Request tts stop pcm : uid(%d)", uid); + } + + if (true != dbus_message_append_args(msg, + DBUS_TYPE_INT32, &uid, + DBUS_TYPE_INVALID)) { + dbus_message_unref(msg); + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args"); + return TTS_ERROR_OPERATION_FAILED; + } + + DBusMessage* result_msg; + int result = TTS_ERROR_OPERATION_FAILED; + + result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, WAITING_TIME, &err); + dbus_message_unref(msg); + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Send error (%s)", err.message); + dbus_error_free(&err); + } + + if (NULL != result_msg) { + dbus_message_get_args(result_msg, &err, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_TTSC, "<<<< tts stop pcm : Get arguments error (%s)", err.message); + dbus_error_free(&err); + result = TTS_ERROR_OPERATION_FAILED; + } + dbus_message_unref(result_msg); + + if (0 == result) { + SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts stop pcm : result(%d)", result); + } else { + SLOG(LOG_ERROR, TAG_TTSC, "<<<< tts stop pcm : result(%d)", result); + } + } else { + SLOG(LOG_ERROR, TAG_TTSC, "<<<< Result message is NULL "); + tts_dbus_reconnect(); + result = TTS_ERROR_TIMED_OUT; + } + + return result; +} + +int tts_dbus_request_add_pcm(int uid, int event, const char* data, int data_size, int audio_type, int rate) +{ + DBusMessage* msg; + DBusError err; + dbus_error_init(&err); + + msg = __tts_dbus_make_message(uid, TTS_METHOD_ADD_PCM); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts add pcm : Fail to make message"); + return TTS_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_TTSC, ">>>> Request tts add pcm : uid(%d)", uid); + } + + if (true != dbus_message_append_args(msg, + DBUS_TYPE_INT32, &uid, + DBUS_TYPE_INT32, &event, + DBUS_TYPE_INT32, &audio_type, + DBUS_TYPE_INT32, &rate, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, + &data, data_size, + DBUS_TYPE_INVALID)) { + dbus_message_unref(msg); + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args"); + return TTS_ERROR_OPERATION_FAILED; + } + + DBusMessage* result_msg; + int result = TTS_ERROR_OPERATION_FAILED; + + result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, WAITING_TIME, &err); + dbus_message_unref(msg); + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Send error (%s)", err.message); + dbus_error_free(&err); + } + + if (NULL != result_msg) { + dbus_message_get_args(result_msg, &err, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_TTSC, "<<<< tts add pcm : Get arguments error (%s)", err.message); + dbus_error_free(&err); + result = TTS_ERROR_OPERATION_FAILED; + } + dbus_message_unref(result_msg); + + if (0 == result) { + SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts add pcm : result(%d)", result); + } else { + SLOG(LOG_ERROR, TAG_TTSC, "<<<< tts add pcm : result(%d)", result); + } + } else { + SLOG(LOG_ERROR, TAG_TTSC, "<<<< Result message is NULL "); + tts_dbus_reconnect(); + result = TTS_ERROR_TIMED_OUT; + } + + return result; +} \ No newline at end of file diff --git a/client/tts_dbus.h b/client/tts_dbus.h index 429d8aa..227b4e5 100644 --- a/client/tts_dbus.h +++ b/client/tts_dbus.h @@ -46,6 +46,12 @@ int tts_dbus_request_set_private_data(int uid, const char* key, const char* data int tts_dbus_request_get_private_data(int uid, const char* key, char** data); +int tts_dbus_request_play_pcm(int uid); + +int tts_dbus_request_stop_pcm(int uid); + +int tts_dbus_request_add_pcm(int uid, int event, const char* data, int data_size, int audio_type, int rate); + #ifdef __cplusplus } #endif diff --git a/common/tts_defs.h b/common/tts_defs.h index 6e803ac..b9bd6e3 100644 --- a/common/tts_defs.h +++ b/common/tts_defs.h @@ -56,6 +56,9 @@ extern "C" { #define TTS_METHOD_PLAY "tts_method_play" #define TTS_METHOD_STOP "tts_method_stop" #define TTS_METHOD_PAUSE "tts_method_pause" +#define TTS_METHOD_PLAY_PCM "tts_method_play_pcm" +#define TTS_METHOD_STOP_PCM "tts_method_stop_pcm" +#define TTS_METHOD_ADD_PCM "tts_method_add_pcm" #define TTS_METHOD_SET_PRIVATE_DATA "tts_method_set_private_data" #define TTS_METHOD_GET_PRIVATE_DATA "tts_method_get_private_data" diff --git a/include/tts_internal.h b/include/tts_internal.h index 434b8da..1c02cb5 100644 --- a/include/tts_internal.h +++ b/include/tts_internal.h @@ -53,6 +53,67 @@ extern "C" */ int tts_set_server_tts(tts_h tts, const char* credential); +/** + * @brief Adds a sound stream to the queue. + * @since_tizen 4.0 + * + * @param[in] tts The TTS handle + * @param[in] event An event about pcm buffer (-1: error, 1: start, 2: continue, 3: finish) + * @param[in] data The pcm data buffer + * @param[in] data_size The data size of pcm data buffer + * @param[in] audio_type The audio type of pcm (0: signed 16-bit, 1: unsigned 8-bit) + * @param[in] rate The sampling rate of pcm + * @return @c 0 on success, + * otherwise a negative error value + * @retval #TTS_ERROR_NONE Successful + * @retval #TTS_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #TTS_ERROR_INVALID_STATE Invalid state + * @retval #TTS_ERROR_OPERATION_FAILED Operation failure + * @retval #TTS_ERROR_NOT_SUPPORTED TTS NOT supported + * @retval #TTS_ERROR_PERMISSION_DENIED Permission denied + * @pre The state should be #TTS_STATE_PLAYING. + * @see tts_play_pcm() + * @see tts_stop_pcm() +*/ +int tts_add_pcm(tts_h tts, int event, const void* data, unsigned int data_size, int audio_type, int rate); + +/** + * @brief Request to play pcm. + * @since_tizen 4.0 + * + * @param[in] tts The TTS handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #TTS_ERROR_NONE Successful + * @retval #TTS_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #TTS_ERROR_INVALID_STATE Invalid state + * @retval #TTS_ERROR_OPERATION_FAILED Operation failure + * @retval #TTS_ERROR_NOT_SUPPORTED TTS NOT supported + * @retval #TTS_ERROR_PERMISSION_DENIED Permission denied + * @pre The state should be #TTS_STATE_READY. + * @see tts_add_pcm() + * @see tts_stop_pcm() +*/ +int tts_play_pcm(tts_h tts); + +/** + * @brief Request to stop pcm. + * @since_tizen 4.0 + * + * @param[in] tts The TTS handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #TTS_ERROR_NONE Successful + * @retval #TTS_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #TTS_ERROR_INVALID_STATE Invalid state + * @retval #TTS_ERROR_OPERATION_FAILED Operation failure + * @retval #TTS_ERROR_NOT_SUPPORTED TTS NOT supported + * @retval #TTS_ERROR_PERMISSION_DENIED Permission denied + * @pre The state should be #TTS_STATE_PLAYING. + * @see tts_play_pcm() + * @see tts_add_pcm() +*/ +int tts_stop_pcm(tts_h tts); #ifdef __cplusplus } diff --git a/server/ttsd_dbus.c b/server/ttsd_dbus.c index 4b2ab38..026f0ea 100644 --- a/server/ttsd_dbus.c +++ b/server/ttsd_dbus.c @@ -270,6 +270,15 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle } else if (dbus_message_is_method_call(msg, g_service_interface, TTS_METHOD_GET_PRIVATE_DATA)) { ttsd_dbus_server_get_private_data(g_conn_listener, msg); + } else if (dbus_message_is_method_call(msg, g_service_interface, TTS_METHOD_PLAY_PCM)) { + ttsd_dbus_server_play_pcm(g_conn_listener, msg); + + } else if (dbus_message_is_method_call(msg, g_service_interface, TTS_METHOD_STOP_PCM)) { + ttsd_dbus_server_stop_pcm(g_conn_listener, msg); + + } else if (dbus_message_is_method_call(msg, g_service_interface, TTS_METHOD_ADD_PCM)) { + ttsd_dbus_server_add_pcm(g_conn_listener, msg); + } else { SLOG(LOG_DEBUG, tts_tag(), "Message is NOT valid"); /* Invalid method */ diff --git a/server/ttsd_dbus_server.c b/server/ttsd_dbus_server.c index fca0b6e..4f464f9 100644 --- a/server/ttsd_dbus_server.c +++ b/server/ttsd_dbus_server.c @@ -617,3 +617,168 @@ int ttsd_dbus_server_get_private_data(DBusConnection* conn, DBusMessage* msg) return 0; } + +int ttsd_dbus_server_play_pcm(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int uid; + int ret = 0; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &uid, + DBUS_TYPE_INVALID); + + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS PLAY PCM"); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, tts_tag(), "[IN ERROR] tts play pcm : Get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = TTSD_ERROR_OPERATION_FAILED; + } else { + SECURE_SLOG(LOG_DEBUG, tts_tag(), "[IN] tts play pcm : uid(%d)", uid); + ret = ttsd_server_play_pcm(uid); + } + + DBusMessage* reply; + reply = dbus_message_new_method_return(msg); + + if (NULL != reply) { + dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID); + + if (0 == ret) { + SLOG(LOG_DEBUG, tts_tag(), "[OUT] tts play pcm : result(%d)", ret); + } else { + SLOG(LOG_ERROR, tts_tag(), "[OUT ERROR] tts play pcm : result(%d)", ret); + } + + if (!dbus_connection_send(conn, reply, NULL)) { + SLOG(LOG_ERROR, tts_tag(), "[OUT ERROR] tts play pcm : Out Of Memory!"); + } + + dbus_connection_flush(conn); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, tts_tag(), "[OUT ERROR] tts play pcm : Fail to create reply message!!"); + } + + SLOG(LOG_DEBUG, tts_tag(), "<<<<<"); + SLOG(LOG_DEBUG, tts_tag(), " "); + + return 0; +} + +int ttsd_dbus_server_stop_pcm(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int uid; + int ret = 0; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &uid, + DBUS_TYPE_INVALID); + + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS STOP PCM"); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, tts_tag(), "[IN ERROR] tts stop pcm : Get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = TTSD_ERROR_OPERATION_FAILED; + } else { + SECURE_SLOG(LOG_DEBUG, tts_tag(), "[IN] tts stop pcm : uid(%d)", uid); + ret = ttsd_server_stop_pcm(uid); + } + + DBusMessage* reply; + reply = dbus_message_new_method_return(msg); + + if (NULL != reply) { + dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID); + + if (0 == ret) { + SLOG(LOG_DEBUG, tts_tag(), "[OUT] tts stop pcm : result(%d)", ret); + } else { + SLOG(LOG_ERROR, tts_tag(), "[OUT ERROR] tts stop pcm : result(%d)", ret); + } + + if (!dbus_connection_send(conn, reply, NULL)) { + SLOG(LOG_ERROR, tts_tag(), "[OUT ERROR] tts stop pcm : Out Of Memory!"); + } + + dbus_connection_flush(conn); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, tts_tag(), "[OUT ERROR] tts stop pcm : Fail to create reply message!!"); + } + + SLOG(LOG_DEBUG, tts_tag(), "<<<<<"); + SLOG(LOG_DEBUG, tts_tag(), " "); + + return 0; +} + +int ttsd_dbus_server_add_pcm(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int uid; + int event; + int audio_type; + int rate; + char* data = NULL; + int data_size; + int ret = 0; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &uid, + DBUS_TYPE_INT32, &event, + DBUS_TYPE_INT32, &audio_type, + DBUS_TYPE_INT32, &rate, + //DBUS_TYPE_STRING, &data, + //DBUS_TYPE_INT32, &data_size, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, + &data, &data_size, + DBUS_TYPE_INVALID); + + SLOG(LOG_DEBUG, tts_tag(), ">>>>> TTS ADD PCM"); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, tts_tag(), "[IN ERROR] tts add pcm : Get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = TTSD_ERROR_OPERATION_FAILED; + } else { + SECURE_SLOG(LOG_DEBUG, tts_tag(), "[IN] tts add pcm : uid(%d)", uid); + ret = ttsd_server_add_pcm(uid, event, (void*)data, data_size, audio_type, rate); + } + + DBusMessage* reply; + reply = dbus_message_new_method_return(msg); + + if (NULL != reply) { + dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID); + + if (0 == ret) { + SLOG(LOG_DEBUG, tts_tag(), "[OUT] tts add pcm : result(%d)", ret); + } else { + SLOG(LOG_ERROR, tts_tag(), "[OUT ERROR] tts add pcm : result(%d)", ret); + } + + if (!dbus_connection_send(conn, reply, NULL)) { + SLOG(LOG_ERROR, tts_tag(), "[OUT ERROR] tts add pcm : Out Of Memory!"); + } + + dbus_connection_flush(conn); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, tts_tag(), "[OUT ERROR] tts add pcm : Fail to create reply message!!"); + } + + SLOG(LOG_DEBUG, tts_tag(), "<<<<<"); + SLOG(LOG_DEBUG, tts_tag(), " "); + + return 0; +} diff --git a/server/ttsd_dbus_server.h b/server/ttsd_dbus_server.h index 47930c0..aa28525 100644 --- a/server/ttsd_dbus_server.h +++ b/server/ttsd_dbus_server.h @@ -47,6 +47,12 @@ int ttsd_dbus_server_set_private_data(DBusConnection* conn, DBusMessage* msg); int ttsd_dbus_server_get_private_data(DBusConnection* conn, DBusMessage* msg); +int ttsd_dbus_server_play_pcm(DBusConnection* conn, DBusMessage* msg); + +int ttsd_dbus_server_stop_pcm(DBusConnection* conn, DBusMessage* msg); + +int ttsd_dbus_server_add_pcm(DBusConnection* conn, DBusMessage* msg); + #ifdef __cplusplus } #endif diff --git a/server/ttsd_server.c b/server/ttsd_server.c index 8820904..3c8f8d0 100644 --- a/server/ttsd_server.c +++ b/server/ttsd_server.c @@ -895,7 +895,6 @@ int ttsd_server_play(int uid, const char* credential) return TTSD_ERROR_NONE; } - int ttsd_server_stop(int uid) { app_state_e state; @@ -1069,4 +1068,165 @@ int ttsd_set_private_data_requested_cb(ttse_private_data_requested_cb callback) return ret; } +int ttsd_server_play_pcm(int uid) +{ + app_state_e state; + if (0 > ttsd_data_get_client_state(uid, &state)) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] uid(%d) is NOT valid ", uid); + return TTSD_ERROR_INVALID_PARAMETER; + } + + if (APP_STATE_PLAYING == state) { + SLOG(LOG_WARN, tts_tag(), "[Server WARNING] Current state(%d) is 'play' ", uid); + return TTSD_ERROR_NONE; + } + + int current_uid = ttsd_data_get_current_playing(); + SLOG(LOG_INFO, tts_tag(), "[Server] playing uid (%d)", current_uid); + + if (uid != current_uid && -1 != current_uid) { + if (TTSD_MODE_DEFAULT != ttsd_get_mode()) { + /* Send interrupt message */ + SLOG(LOG_DEBUG, tts_tag(), "[Server] Old uid(%d) will be interrupted into 'Stop' state ", current_uid); + + /* pause player */ + if (0 != ttsd_server_stop(current_uid)) { + SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to stop : uid (%d)", current_uid); + } + if (0 != ttsd_player_stop(current_uid)) { + SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to player stop : uid (%d)", current_uid); + } + + intptr_t pcurrent_uid = (intptr_t)current_uid; + ecore_timer_add(0, __send_interrupt_client, (void*)pcurrent_uid); + } else { + /* Default mode policy of interrupt is "Pause" */ + + /* Send interrupt message */ + SLOG(LOG_DEBUG, tts_tag(), "[Server] Old uid(%d) will be interrupted into 'Pause' state ", current_uid); + + /* pause player */ + if (0 != ttsd_player_pause(current_uid)) { + SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to ttsd_player_pause() : uid (%d)", current_uid); + } + + /* change state */ + ttsd_data_set_client_state(current_uid, APP_STATE_PAUSED); + + intptr_t pcurrent_uid = (intptr_t)current_uid; + ecore_timer_add(0, __send_interrupt_client, (void*)pcurrent_uid); + } + } + + /* Change current play */ + if (0 != ttsd_data_set_client_state(uid, APP_STATE_PLAYING)) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to set state : uid(%d)", uid); + return TTSD_ERROR_OPERATION_FAILED; + } + + return TTSD_ERROR_NONE; +} + +int ttsd_server_stop_pcm(int uid) +{ + app_state_e state; + if (0 > ttsd_data_get_client_state(uid, &state)) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] uid is not valid"); + return TTSD_ERROR_INVALID_PARAMETER; + } + + SLOG(LOG_INFO, tts_tag(), "[Server] server stop, state(%d)", state); + if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) { + if (0 != ttsd_player_clear(uid)) + SLOG(LOG_WARN, tts_tag(), "[Server] Fail to ttsd_player_stop()"); + + ttsd_data_set_client_state(uid, APP_STATE_READY); + } + + /* Reset all data */ + ttsd_data_clear_data(uid); + + return TTSD_ERROR_NONE; +} + +int ttsd_server_add_pcm(int uid, int event, void* data, int data_size, int audio_type, int rate) +{ + SLOG(LOG_DEBUG, tts_tag(), "===== ADD PCM"); + + int uttid = -1; + + /* Synthesis is success */ + if (TTSE_RESULT_EVENT_START == event || TTSE_RESULT_EVENT_CONTINUE == event || TTSE_RESULT_EVENT_FINISH == event) { + if (TTSE_RESULT_EVENT_START == event) { + SLOG(LOG_INFO, tts_tag(), "[SERVER] Event : TTSE_RESULT_EVENT_START"); + SECURE_SLOG(LOG_DEBUG, tts_tag(), "[SERVER] PCM Info : uid(%d), utt(%d), data(%p), data size(%d) audiotype(%d) rate(%d)", + uid, uttid, data, data_size, audio_type, rate); + } 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] PCM Info : uid(%d), utt(%d), data(%p), data size(%d) audiotype(%d) rate(%d)", + uid, uttid, data, data_size, audio_type, rate); + } else { + /*if (TTSE_RESULT_EVENT_CONTINUE == event) SLOG(LOG_DEBUG, tts_tag(), "[SERVER] Event : TTSE_RESULT_EVENT_CONTINUE");*/ + } + + if (rate <= 0 || audio_type < 0 || audio_type > TTSE_AUDIO_TYPE_MAX) { + SLOG(LOG_ERROR, tts_tag(), "[SERVER ERROR] audio data is invalid"); + SLOG(LOG_DEBUG, tts_tag(), "====="); + SLOG(LOG_DEBUG, tts_tag(), " "); + return TTSD_ERROR_INVALID_PARAMETER; + } + + /* add wav data */ + sound_data_s* temp_sound_data = NULL; + temp_sound_data = (sound_data_s*)calloc(1, sizeof(sound_data_s)); + if (NULL == temp_sound_data) { + SLOG(LOG_ERROR, tts_tag(), "[SERVER ERROR] Out of memory"); + return TTSD_ERROR_OUT_OF_MEMORY; + } + + temp_sound_data->data = NULL; + temp_sound_data->rate = 0; + temp_sound_data->data_size = 0; + + if (0 < data_size) { + temp_sound_data->data = (char*)calloc(data_size + 5, sizeof(char)); + if (NULL != temp_sound_data->data) { + memcpy(temp_sound_data->data, data, data_size); + temp_sound_data->data_size = data_size; + SLOG(LOG_INFO, tts_tag(), "[DEBUG][memcpy] uid(%d), event(%d) sound_data(%p) data(%p) size(%d)", + uid, event, temp_sound_data, temp_sound_data->data, temp_sound_data->data_size); + } else { + SLOG(LOG_ERROR, tts_tag(), "Fail to allocate memory"); + } + } else { + SLOG(LOG_ERROR, tts_tag(), "Sound data is NULL"); + } + + temp_sound_data->utt_id = uttid; + temp_sound_data->event = event; + temp_sound_data->audio_type = audio_type; + temp_sound_data->rate = rate; + + if (0 != ttsd_data_add_sound_data(uid, temp_sound_data)) { + SECURE_SLOG(LOG_ERROR, tts_tag(), "[SERVER ERROR] Fail to add sound data : uid(%d)", uid); + } + + if (0 != ttsd_player_play(uid)) { + SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to play sound : uid(%d)", uid); + + /* Change ready state */ + ttsd_server_stop(uid); + + int tmp_pid; + tmp_pid = ttsd_data_get_pid(uid); + ttsdc_send_set_state_message(tmp_pid, uid, APP_STATE_READY); + } + } else { + SLOG(LOG_DEBUG, tts_tag(), "[SERVER] Event : TTSE_RESULT_EVENT_ERROR"); + } + + SLOG(LOG_DEBUG, tts_tag(), "====="); + + return TTSD_ERROR_NONE; +} diff --git a/server/ttsd_server.h b/server/ttsd_server.h index d2fadb9..89478b8 100644 --- a/server/ttsd_server.h +++ b/server/ttsd_server.h @@ -65,6 +65,12 @@ int ttsd_server_set_private_data(int uid, const char* key, const char* data); int ttsd_server_get_private_data(int uid, const char* key, char** data); +int ttsd_server_play_pcm(int uid); + +int ttsd_server_stop_pcm(int uid); + +int ttsd_server_add_pcm(int uid, int event, void* data, int data_size, int audio_type, int rate); + #ifdef __cplusplus } #endif