summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWonnam Jang <wn.jang@samsung.com>2017-07-26 08:59:17 +0900
committerWonnam Jang <wn.jang@samsung.com>2017-07-27 01:40:48 +0000
commit2b655e53ec85ba486a4e02a03d156500c8fd6ef8 (patch)
treee9fe7e81de3128e372cd3739f4aa805151b011ff
parent44a6f4776f16d8ef4682bc2663ac8bf1cccc9cc9 (diff)
downloadstt-accepted/tizen_3.0_mobile.tar.gz
stt-accepted/tizen_3.0_mobile.tar.bz2
stt-accepted/tizen_3.0_mobile.zip
Change-Id: Ic51ab61631b9f0023a8005e2c7496309b76d1bb9 Signed-off-by: Wonnam Jang <wn.jang@samsung.com> (cherry picked from commit 6136ff63f55ec03f67272624a37e8a21e623441f)
-rw-r--r--client/stt.c121
-rw-r--r--client/stt_dbus.c115
-rw-r--r--client/stt_dbus.h4
-rw-r--r--client/stt_file_client.c4
-rw-r--r--common/stt_defs.h3
-rw-r--r--include/stt_internal.h64
-rw-r--r--server/sttd_dbus.c23
-rw-r--r--server/sttd_dbus_server.c90
-rw-r--r--server/sttd_dbus_server.h3
-rw-r--r--server/sttd_engine_agent.c61
-rw-r--r--server/sttd_engine_agent.h4
-rw-r--r--server/sttd_recorder.c67
-rw-r--r--server/sttd_recorder.h4
-rw-r--r--server/sttd_server.c173
-rw-r--r--server/sttd_server.h3
15 files changed, 729 insertions, 10 deletions
diff --git a/client/stt.c b/client/stt.c
index 6e9702f..52531f5 100644
--- a/client/stt.c
+++ b/client/stt.c
@@ -1996,9 +1996,9 @@ static void __stt_notify_state_changed(void *data)
client->state_changed_cb(client->stt, client->before_state,
client->current_state, client->state_changed_user_data);
stt_client_not_use_callback(client);
- SLOG(LOG_DEBUG, TAG_STTC, "State changed callback is called");
+ SLOG(LOG_DEBUG, TAG_STTC, "State changed callback is called, State(%d)", client->current_state);
} else {
- SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
+ SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null, State(%d)", client->current_state);
}
return;
@@ -2488,3 +2488,120 @@ int stt_unset_speech_status_cb(stt_h stt)
return 0;
}
+
+int stt_start_file(stt_h stt, const char* language, const char* type, const char* filepath, stt_audio_type_e audio_type, int sample_rate)
+{
+ stt_client_s* client = NULL;
+ if (0 != __stt_get_feature_enabled()) {
+ return STT_ERROR_NOT_SUPPORTED;
+ }
+ if (0 != __stt_check_privilege()) {
+ return STT_ERROR_PERMISSION_DENIED;
+ }
+ if (0 != __stt_check_handle(stt, &client)) {
+ return STT_ERROR_INVALID_PARAMETER;
+ }
+ if (NULL == filepath) {
+ SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
+ return STT_ERROR_INVALID_PARAMETER;
+ }
+
+ SLOG(LOG_DEBUG, TAG_STTC, "===== STT START FILE");
+
+ /* check state */
+ if (client->current_state != STT_STATE_READY) {
+ SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
+ return STT_ERROR_INVALID_STATE;
+ }
+
+ if (STT_INTERNAL_STATE_NONE != client->internal_state) {
+ SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is NOT none : %d", client->internal_state);
+ return STT_ERROR_IN_PROGRESS_TO_RECORDING;
+ }
+
+ int ret = -1;
+ char appid[128] = {0, };
+ ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
+
+ if ((AUL_R_OK != ret) || (0 == strlen(appid))) {
+ SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get application ID");
+ } else {
+ SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] Current app id is %s", appid);
+ }
+
+ char* temp = NULL;
+ if (NULL == language) {
+ temp = strdup("default");
+ } else {
+ temp = strdup(language);
+ }
+
+ if (true == client->credential_needed && NULL == client->credential) {
+ SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Do not have app credential for this engine(%s)", client->current_engine_id);
+ return STT_ERROR_PERMISSION_DENIED;
+ }
+
+ client->internal_state = STT_INTERNAL_STATE_STARTING;
+ ret = stt_dbus_request_start_file(client->uid, temp, type, client->silence, appid, client->credential, filepath, audio_type, sample_rate);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start file : %s", __stt_get_error_code(ret));
+ client->internal_state = STT_INTERNAL_STATE_NONE;
+ } else {
+ SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Start is successful but not done");
+ }
+
+ if (NULL != temp) free(temp);
+
+ SLOG(LOG_DEBUG, TAG_STTC, "=====");
+ SLOG(LOG_DEBUG, TAG_STTC, " ");
+
+ return ret;
+}
+
+int stt_cancel_file(stt_h stt)
+{
+ stt_client_s* client = NULL;
+ if (0 != __stt_get_feature_enabled()) {
+ return STT_ERROR_NOT_SUPPORTED;
+ }
+ if (0 != __stt_check_privilege()) {
+ return STT_ERROR_PERMISSION_DENIED;
+ }
+ if (0 != __stt_check_handle(stt, &client)) {
+ return STT_ERROR_INVALID_PARAMETER;
+ }
+
+ SLOG(LOG_DEBUG, TAG_STTC, "===== STT CANCEL FILE");
+
+ /* check state */
+ if (STT_STATE_RECORDING != client->current_state && STT_STATE_PROCESSING != client->current_state) {
+ SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid state : Current state(%d) is 'Ready'", client->current_state);
+ return STT_ERROR_INVALID_STATE;
+ }
+
+ if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
+ SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state);
+ return STT_ERROR_IN_PROGRESS_TO_RECORDING;
+ } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
+ SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state);
+ return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
+ } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
+ SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state);
+ return STT_ERROR_IN_PROGRESS_TO_READY;
+ }
+
+ client->internal_state = STT_INTERNAL_STATE_CANCELING;
+ int ret = stt_dbus_request_cancel_file(client->uid);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to cancel file : %s", __stt_get_error_code(ret));
+ client->internal_state = STT_INTERNAL_STATE_NONE;
+ } else {
+ SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Cancel file is successful but not done");
+ }
+
+ SLOG(LOG_DEBUG, TAG_STTC, "=====");
+ SLOG(LOG_DEBUG, TAG_STTC, " ");
+
+ return ret;
+}
+
diff --git a/client/stt_dbus.c b/client/stt_dbus.c
index f6ddbf0..68defb8 100644
--- a/client/stt_dbus.c
+++ b/client/stt_dbus.c
@@ -2117,3 +2117,118 @@ int stt_dbus_request_cancel(int uid)
return result;
#endif
}
+
+int stt_dbus_request_start_file(int uid, const char* lang, const char* type, int silence, const char* appid, const char* credential, const char* filepath, stt_audio_type_e audio_type, int sample_rate)
+{
+ if (NULL == lang || NULL == type || NULL == appid) {
+ SLOG(LOG_ERROR, TAG_STTC, "Input parameter is NULL");
+ return STT_ERROR_INVALID_PARAMETER;
+ }
+
+ DBusMessage* msg;
+
+ /* create a signal & check for errors */
+ msg = dbus_message_new_method_call(
+ g_server_service_name,
+ g_server_service_object,
+ g_server_service_interface,
+ STT_METHOD_START_FILE);
+
+ if (NULL == msg) {
+ SLOG(LOG_ERROR, TAG_STTC, ">>>> stt start file : Fail to make message");
+ return STT_ERROR_OPERATION_FAILED;
+ } else {
+ SLOG(LOG_DEBUG, TAG_STTC, ">>>> stt start file : uid(%d), language(%s), type(%s), appid(%s), filepath(%s), audio_type(%d), sample_rate(%d)", uid, lang, type, appid, filepath, audio_type, sample_rate);
+ }
+
+ char *temp = NULL;
+ if (NULL == credential) {
+ temp = strdup("NULL");
+ } else {
+ temp = strdup(credential);
+ }
+
+ dbus_message_append_args(msg,
+ DBUS_TYPE_INT32, &uid,
+ DBUS_TYPE_STRING, &lang,
+ DBUS_TYPE_STRING, &type,
+ DBUS_TYPE_INT32, &silence,
+ DBUS_TYPE_STRING, &appid,
+ DBUS_TYPE_STRING, &temp,
+ DBUS_TYPE_STRING, &filepath,
+ DBUS_TYPE_INT32, &audio_type,
+ DBUS_TYPE_INT32, &sample_rate,
+ DBUS_TYPE_INVALID);
+ if (g_conn_sender) {
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (!dbus_connection_send(g_conn_sender, msg, NULL)) {
+ SLOG(LOG_ERROR, TAG_STTC, "[Dbus ERROR] <<<< stt start message : Out Of Memory !");
+ if (NULL != temp) {
+ free(temp);
+ temp = NULL;
+ }
+ return STT_ERROR_OUT_OF_MEMORY;
+ } else {
+ dbus_connection_flush(g_conn_sender);
+ }
+
+ dbus_message_unref(msg);
+
+ } else {
+ SLOG(LOG_WARN, TAG_STTC, "[WARN] dbus connection handle is null (%p)", g_conn_sender);
+ if (NULL != temp) {
+ free(temp);
+ temp = NULL;
+ }
+ return STT_ERROR_OPERATION_FAILED;
+ }
+
+ if (NULL != temp) {
+ free(temp);
+ temp = NULL;
+ }
+ return 0;
+}
+
+int stt_dbus_request_cancel_file(int uid)
+{
+ DBusMessage* msg;
+
+ /* create a signal & check for errors */
+ msg = dbus_message_new_method_call(
+ g_server_service_name,
+ g_server_service_object,
+ g_server_service_interface,
+ STT_METHOD_CANCEL_FILE);
+
+ if (NULL == msg) {
+ SLOG(LOG_ERROR, TAG_STTC, ">>>> stt cancel file : Fail to make message");
+ return STT_ERROR_OPERATION_FAILED;
+ } else {
+ SLOG(LOG_DEBUG, TAG_STTC, ">>>> stt cancel file : uid(%d)", uid);
+ }
+
+ dbus_message_append_args(msg,
+ DBUS_TYPE_INT32, &uid,
+ DBUS_TYPE_INVALID);
+
+ if (g_conn_sender) {
+ dbus_message_set_no_reply(msg, TRUE);
+
+ if (!dbus_connection_send(g_conn_sender, msg, NULL)) {
+ SLOG(LOG_ERROR, TAG_STTC, "[Dbus ERROR] <<<< stt stop message : Out Of Memory !");
+ return STT_ERROR_OUT_OF_MEMORY;
+ } else {
+ dbus_connection_flush(g_conn_sender);
+ }
+
+ dbus_message_unref(msg);
+ } else {
+ SLOG(LOG_WARN, TAG_STTC, "[WARN] dbus connection handle is null (%p)", g_conn_sender);
+ return STT_ERROR_OPERATION_FAILED;
+ }
+
+ return 0;
+}
+
diff --git a/client/stt_dbus.h b/client/stt_dbus.h
index 4564d41..6c7e059 100644
--- a/client/stt_dbus.h
+++ b/client/stt_dbus.h
@@ -17,6 +17,7 @@
#include "stt.h"
#include "stt_main.h"
+#include "stt_internal.h"
#ifdef __cplusplus
extern "C" {
@@ -62,6 +63,9 @@ int stt_dbus_request_stop(int uid);
int stt_dbus_request_cancel(int uid);
+int stt_dbus_request_start_file(int uid, const char* lang, const char* type, int silence, const char* appid, const char* credential, const char* filepath, stt_audio_type_e audio_type, int sample_rate);
+
+int stt_dbus_request_cancel_file(int uid);
#ifdef __cplusplus
}
diff --git a/client/stt_file_client.c b/client/stt_file_client.c
index 40f722e..a5303e4 100644
--- a/client/stt_file_client.c
+++ b/client/stt_file_client.c
@@ -28,6 +28,10 @@ int stt_file_client_new()
}
g_client_info = (stt_file_client_s*)calloc(1, sizeof(stt_file_client_s));
+ if (!g_client_info) {
+ SLOG(LOG_ERROR, TAG_STTFC, "[ERROR] Fail to allocate memory");
+ return STT_FILE_ERROR_OUT_OF_MEMORY;
+ }
/* initialize client data */
g_client_info->recognition_result_cb = NULL;
diff --git a/common/stt_defs.h b/common/stt_defs.h
index 465e22c..2fd8fd6 100644
--- a/common/stt_defs.h
+++ b/common/stt_defs.h
@@ -76,6 +76,9 @@ extern "C" {
#define STTD_METHOD_SET_VOLUME "sttd_method_set_volume"
#define STTD_METHOD_SPEECH_STATUS "sttd_method_speech_status"
+#define STT_METHOD_START_FILE "stt_method_start_file"
+#define STT_METHOD_CANCEL_FILE "stt_method_cancel_file"
+
/******************************************************************************************
* Defines for configuration
diff --git a/include/stt_internal.h b/include/stt_internal.h
index 5b0cc70..bebf85b 100644
--- a/include/stt_internal.h
+++ b/include/stt_internal.h
@@ -32,6 +32,14 @@ extern "C"
#define STT_SPEECH_STATUS_BEGINNING_POINT_DETECTED 0
/**
+* @brief Enumerations of audio type.
+*/
+typedef enum {
+ STT_AUDIO_TYPE_RAW_S16 = 0, /**< Signed 16-bit audio sample */
+ STT_AUDIO_TYPE_RAW_U8, /**< Unsigned 8-bit audio sample */
+} stt_audio_type_e;
+
+/**
* @brief Called when user speaking is detected.
*
* @param[in] stt The STT handle
@@ -124,6 +132,62 @@ int stt_unset_speech_status_cb(stt_h stt);
*/
int stt_set_server_stt(stt_h stt, const char* key, char* user_data);
+/**
+ * @brief Starts file recognition asynchronously.
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/recorder
+ * @remarks This function starts sending recorded data from file to engine.
+ * @param[in] stt The STT handle
+ * @param[in] language The language selected from stt_foreach_supported_languages()
+ * @param[in] type The type for recognition (e.g. #STT_RECOGNITION_TYPE_FREE, #STT_RECOGNITION_TYPE_FREE_PARTIAL)
+ * @param[in] filepath PCM filepath for recognition
+ * @param[in] audio_type audio type of file
+ * @param[in] sample_rate sample rate of file
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #STT_ERROR_NONE Successful
+ * @retval #STT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STT_ERROR_INVALID_STATE Invalid state
+ * @retval #STT_ERROR_OPERATION_FAILED Operation failure
+ * @retval #STT_ERROR_NOT_SUPPORTED STT NOT supported
+ * @retval #STT_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #STT_ERROR_IN_PROGRESS_TO_RECORDING Progress to recording is not finished
+ * @pre The state should be #STT_STATE_READY.
+ * @post It will invoke stt_state_changed_cb(), if you register a callback with stt_state_changed_cb().
+ * If this function succeeds, the STT state will be #STT_STATE_RECORDING.
+ * If you call this function again before state changes, you will receive STT_ERROR_IN_PROGRESS_TO_RECORDING.
+ * @see stt_cancel_file()
+ * @see stt_state_changed_cb()
+*/
+int stt_start_file(stt_h stt, const char* language, const char* type, const char* filepath, stt_audio_type_e audio_type, int sample_rate);
+
+/**
+ * @brief Cancels processing file recognition asynchronously.
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/recorder
+ * @remarks This function cancels recording and engine cancels recognition processing.
+ * After successful cancel, stt_state_changed_cb() is called otherwise if error is occurred, stt_error_cb() is called.
+ * @param[in] stt The STT handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #STT_ERROR_NONE Successful
+ * @retval #STT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STT_ERROR_INVALID_STATE Invalid state
+ * @retval #STT_ERROR_OPERATION_FAILED Operation failure
+ * @retval #STT_ERROR_NOT_SUPPORTED STT NOT supported
+ * @retval #STT_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #STT_ERROR_IN_PROGRESS_TO_READY Progress to ready is not finished
+ * @retval #STT_ERROR_IN_PROGRESS_TO_RECORDING Progress to recording is not finished
+ * @retval #STT_ERROR_IN_PROGRESS_TO_PROCESSING Progress to processing is not finished
+ * @pre The state should be #STT_STATE_RECORDING or #STT_STATE_PROCESSING.
+ * @post It will invoke stt_state_changed_cb(), if you register a callback with stt_state_changed_cb().
+ * If this function succeeds, the STT state will be #STT_STATE_READY.
+ * If you call this function again before state changes, you will receive STT_ERROR_IN_PROGRESS_TO_READY.
+ * @see stt_start_file()
+ * @see stt_state_changed_cb()
+*/
+int stt_cancel_file(stt_h stt);
+
#ifdef __cplusplus
}
#endif
diff --git a/server/sttd_dbus.c b/server/sttd_dbus.c
index 0f68473..99a29a2 100644
--- a/server/sttd_dbus.c
+++ b/server/sttd_dbus.c
@@ -475,6 +475,11 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle
else if (dbus_message_is_method_call(msg, g_server_service_interface, STT_METHOD_CANCEL))
sttd_dbus_server_cancel(g_conn_listener, msg);
+ else if (dbus_message_is_method_call(msg, g_server_service_interface, STT_METHOD_START_FILE))
+ sttd_dbus_server_start_file(g_conn_listener, msg);
+
+ else if (dbus_message_is_method_call(msg, g_server_service_interface, STT_METHOD_CANCEL_FILE))
+ sttd_dbus_server_cancel_file(g_conn_listener, msg);
/* free the message */
dbus_message_unref(msg);
@@ -585,18 +590,24 @@ int __sttd_get_buxtonkey()
if (NULL == engine_appid || NULL == engine_default || 0 == strncmp(engine_appid, engine_default, strlen(engine_appid))) {
g_server_service_name = (char*)calloc(strlen(STT_SERVER_SERVICE_NAME) + 1, sizeof(char));
- snprintf(g_server_service_name, strlen(STT_SERVER_SERVICE_NAME) + 1, "%s", STT_SERVER_SERVICE_NAME);
+ if (g_server_service_name)
+ snprintf(g_server_service_name, strlen(STT_SERVER_SERVICE_NAME) + 1, "%s", STT_SERVER_SERVICE_NAME);
g_server_service_object = (char*)calloc(strlen(STT_SERVER_SERVICE_OBJECT_PATH) + 1, sizeof(char));
- snprintf(g_server_service_object, strlen(STT_SERVER_SERVICE_OBJECT_PATH) + 1, "%s", STT_SERVER_SERVICE_OBJECT_PATH);
+ if (g_server_service_object)
+ snprintf(g_server_service_object, strlen(STT_SERVER_SERVICE_OBJECT_PATH) + 1, "%s", STT_SERVER_SERVICE_OBJECT_PATH);
g_server_service_interface = (char*)calloc(strlen(STT_SERVER_SERVICE_INTERFACE) + 1, sizeof(char));
- snprintf(g_server_service_interface, strlen(STT_SERVER_SERVICE_INTERFACE) + 1, "%s", STT_SERVER_SERVICE_INTERFACE);
+ if (g_server_service_interface)
+ snprintf(g_server_service_interface, strlen(STT_SERVER_SERVICE_INTERFACE) + 1, "%s", STT_SERVER_SERVICE_INTERFACE);
} else {
g_server_service_name = (char*)calloc(strlen(STT_SERVER_SERVICE_NAME) + strlen(engine_appid) - 8, sizeof(char));
- snprintf(g_server_service_name, strlen(STT_SERVER_SERVICE_NAME) + strlen(engine_appid) - 8, "%s%s%s", STT_SERVER_SERVICE_NAME, ".", (engine_appid + 10));
+ if (g_server_service_name)
+ snprintf(g_server_service_name, strlen(STT_SERVER_SERVICE_NAME) + strlen(engine_appid) - 8, "%s%s%s", STT_SERVER_SERVICE_NAME, ".", (engine_appid + 10));
g_server_service_object = (char*)calloc(strlen(STT_SERVER_SERVICE_OBJECT_PATH) + strlen(engine_appid) - 8, sizeof(char));
- snprintf(g_server_service_object, strlen(STT_SERVER_SERVICE_OBJECT_PATH) + strlen(engine_appid) - 8, "%s%s%s", STT_SERVER_SERVICE_OBJECT_PATH, "/", (engine_appid + 10));
+ if (g_server_service_object)
+ snprintf(g_server_service_object, strlen(STT_SERVER_SERVICE_OBJECT_PATH) + strlen(engine_appid) - 8, "%s%s%s", STT_SERVER_SERVICE_OBJECT_PATH, "/", (engine_appid + 10));
g_server_service_interface = (char*)calloc(strlen(STT_SERVER_SERVICE_INTERFACE) + strlen(engine_appid) - 8, sizeof(char));
- snprintf(g_server_service_interface, strlen(STT_SERVER_SERVICE_INTERFACE) + strlen(engine_appid) - 8, "%s%s%s", STT_SERVER_SERVICE_INTERFACE, ".", (engine_appid + 10));
+ if (g_server_service_interface)
+ snprintf(g_server_service_interface, strlen(STT_SERVER_SERVICE_INTERFACE) + strlen(engine_appid) - 8, "%s%s%s", STT_SERVER_SERVICE_INTERFACE, ".", (engine_appid + 10));
}
if (NULL == g_server_service_name || NULL == g_server_service_object || NULL == g_server_service_interface) {
diff --git a/server/sttd_dbus_server.c b/server/sttd_dbus_server.c
index 2428cb0..b3ab460 100644
--- a/server/sttd_dbus_server.c
+++ b/server/sttd_dbus_server.c
@@ -1147,3 +1147,93 @@ int sttd_dbus_server_cancel(DBusConnection* conn, DBusMessage* msg)
return 0;
}
+
+int sttd_dbus_server_start_file(DBusConnection* conn, DBusMessage* msg)
+{
+ DBusError err;
+ dbus_error_init(&err);
+
+ int uid;
+ char* lang;
+ char* type;
+ char* appid;
+ int silence;
+ char* credential;
+ char* filepath;
+ stte_audio_type_e audio_type;
+ int sample_rate;
+
+ int ret = STTD_ERROR_OPERATION_FAILED;
+
+ dbus_message_get_args(msg, &err,
+ DBUS_TYPE_INT32, &uid,
+ DBUS_TYPE_STRING, &lang,
+ DBUS_TYPE_STRING, &type,
+ DBUS_TYPE_INT32, &silence,
+ DBUS_TYPE_STRING, &appid,
+ DBUS_TYPE_STRING, &credential,
+ DBUS_TYPE_STRING, &filepath,
+ DBUS_TYPE_INT32, &audio_type,
+ DBUS_TYPE_INT32, &sample_rate,
+ DBUS_TYPE_INVALID);
+
+ SLOG(LOG_DEBUG, TAG_STTD, ">>>>> STT Start File");
+
+ if (dbus_error_is_set(&err)) {
+ SLOG(LOG_ERROR, TAG_STTD, "[IN ERROR] stt start file: get arguments error (%s)", err.message);
+ dbus_error_free(&err);
+ ret = STTD_ERROR_OPERATION_FAILED;
+ } else {
+ SLOG(LOG_DEBUG, TAG_STTD, "[IN] stt start file : uid(%d), lang(%s), type(%s), silence(%d) appid(%s) filepath(%s), audio_type(%d), sample_rate(%d)"
+ , uid, lang, type, silence, appid, filepath, audio_type, sample_rate);
+ ret = sttd_server_start_file(uid, lang, type, silence, appid, credential, filepath, audio_type, sample_rate);
+ }
+
+ if (0 <= ret) {
+ SLOG(LOG_DEBUG, TAG_STTD, "[OUT SUCCESS] Result(%d)", ret);
+ } else {
+ SLOG(LOG_ERROR, TAG_STTD, "[OUT ERROR] Result(%d)", ret);
+ if (0 != sttdc_send_error_signal(uid, ret, "[ERROR] Fail to start file")) {
+ SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to send error signal");
+ }
+ }
+
+ SLOG(LOG_DEBUG, TAG_STTD, "<<<<<");
+ SLOG(LOG_DEBUG, TAG_STTD, " ");
+
+ return 0;
+}
+
+int sttd_dbus_server_cancel_file(DBusConnection* conn, DBusMessage* msg)
+{
+ DBusError err;
+ dbus_error_init(&err);
+
+ int uid;
+ int ret = STTD_ERROR_OPERATION_FAILED;
+ dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID);
+
+ SLOG(LOG_DEBUG, TAG_STTD, ">>>>> STT Cancel File");
+
+ if (dbus_error_is_set(&err)) {
+ SLOG(LOG_ERROR, TAG_STTD, "[IN ERROR] stt cancel file : get arguments error (%s)", err.message);
+ dbus_error_free(&err);
+ ret = STTD_ERROR_OPERATION_FAILED;
+ } else {
+ SLOG(LOG_DEBUG, TAG_STTD, "[IN] stt cancel file : uid(%d)", uid);
+ ret = sttd_server_cancel_file(uid);
+ }
+
+ if (0 <= ret) {
+ SLOG(LOG_DEBUG, TAG_STTD, "[OUT SUCCESS] Result(%d)", ret);
+ } else {
+ SLOG(LOG_ERROR, TAG_STTD, "[OUT ERROR] Result(%d)", ret);
+ if (0 != sttdc_send_error_signal(uid, ret, "[ERROR] Fail to cancel")) {
+ SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to send error signal");
+ }
+ }
+ SLOG(LOG_DEBUG, TAG_STTD, "<<<<<");
+ SLOG(LOG_DEBUG, TAG_STTD, " ");
+
+ return 0;
+}
diff --git a/server/sttd_dbus_server.h b/server/sttd_dbus_server.h
index 6e7c16d..da21771 100644
--- a/server/sttd_dbus_server.h
+++ b/server/sttd_dbus_server.h
@@ -68,6 +68,9 @@ int sttd_dbus_server_stop(DBusConnection* conn, DBusMessage* msg);
int sttd_dbus_server_cancel(DBusConnection* conn, DBusMessage* msg);
+int sttd_dbus_server_start_file(DBusConnection* conn, DBusMessage* msg);
+
+int sttd_dbus_server_cancel_file(DBusConnection* conn, DBusMessage* msg);
#ifdef __cplusplus
diff --git a/server/sttd_engine_agent.c b/server/sttd_engine_agent.c
index 5e39973..b0e7071 100644
--- a/server/sttd_engine_agent.c
+++ b/server/sttd_engine_agent.c
@@ -837,6 +837,32 @@ int sttd_engine_agent_recognize_start_recorder(int uid)
return 0;
}
+int sttd_engine_agent_recognize_start_file(int uid, const char* filepath)
+{
+ if (NULL == g_engine_info) {
+ SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The engine is not valid");
+ return STTD_ERROR_INVALID_PARAMETER;
+ }
+
+ if (false == g_engine_info->is_loaded) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
+ return STTD_ERROR_OPERATION_FAILED;
+ }
+
+ SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Start recorder");
+
+ int ret;
+ ret = sttd_recorder_start_file(uid, filepath);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to start recorder : result(%d)", ret);
+ stt_engine_recognize_cancel();
+ sttd_recorder_stop_file();
+ return ret;
+ }
+
+ return 0;
+}
+
int sttd_engine_agent_set_recording_data(const void* data, unsigned int length)
{
if (false == g_agent_init) {
@@ -867,6 +893,41 @@ int sttd_engine_agent_set_recording_data(const void* data, unsigned int length)
return ret;
}
+int sttd_engine_agent_recognize_stop_file()
+{
+ if (false == g_agent_init) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not Initialized");
+ return STTD_ERROR_OPERATION_FAILED;
+ }
+
+ if (NULL == g_engine_info) {
+ SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] The engine is not valid");
+ return STTD_ERROR_INVALID_PARAMETER;
+ }
+
+ if (false == g_engine_info->is_loaded) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Not loaded engine");
+ return STTD_ERROR_OPERATION_FAILED;
+ }
+
+ SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Stop recorder");
+ int ret;
+ ret = sttd_recorder_stop_file();
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Engine Agent ERROR] Fail to stop recorder : result(%d)", ret);
+ return ret;
+ }
+
+#ifdef AUDIO_CREATE_ON_START
+ SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent] Destroy recorder");
+ if (0 != sttd_recorder_destroy())
+ SECURE_SLOG(LOG_WARN, TAG_STTD, "[Engine Agent] Fail to destroy recorder");
+#endif
+
+ SLOG(LOG_DEBUG, TAG_STTD, "[Engine Agent Success] Stop recorder");
+ return 0;
+}
+
int sttd_engine_agent_recognize_stop_recorder()
{
if (false == g_agent_init) {
diff --git a/server/sttd_engine_agent.h b/server/sttd_engine_agent.h
index f44723d..58058be 100644
--- a/server/sttd_engine_agent.h
+++ b/server/sttd_engine_agent.h
@@ -98,10 +98,14 @@ int sttd_engine_agent_recognize_start_engine(int uid, const char* lang, const ch
int sttd_engine_agent_recognize_start_recorder(int uid);
+int sttd_engine_agent_recognize_start_file(int uid, const char* filepath);
+
int sttd_engine_agent_set_recording_data(const void* data, unsigned int length);
int sttd_engine_agent_recognize_stop();
+int sttd_engine_agent_recognize_stop_file();
+
int sttd_engine_agent_recognize_stop_recorder();
int sttd_engine_agent_recognize_stop_engine();
diff --git a/server/sttd_recorder.c b/server/sttd_recorder.c
index a8b0cf0..d95d3c9 100644
--- a/server/sttd_recorder.c
+++ b/server/sttd_recorder.c
@@ -623,3 +623,70 @@ int sttd_recorder_stop()
return 0;
}
+
+int sttd_recorder_start_file(int uid, const char *filepath)
+{
+ if (STTD_RECORDER_STATE_RECORDING == g_recorder_state)
+ return 0;
+
+ /* Check engine id is valid */
+ if (NULL == g_recorder) {
+ SLOG(LOG_WARN, TAG_STTD, "[Recorder WARNING] Engine id is not valid");
+ return STTD_ERROR_INVALID_PARAMETER;
+ }
+ g_recorder_state = STTD_RECORDER_STATE_RECORDING;
+ g_recorder->uid = uid;
+
+ int cnt = 0;
+ int totalReadBytes = 0;
+
+ FILE *infile = fopen(filepath, "rb");
+
+ //process the file
+ if (infile != NULL) {
+ while (!feof(infile)) {
+ static char pcm_buff[BUFFER_LENGTH];
+ int read_byte = fread(pcm_buff, 1, BUFFER_LENGTH, infile);
+ totalReadBytes += read_byte;
+ if (0 != read_byte) {
+ if (0 != g_audio_cb(pcm_buff, read_byte)) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to call audio callback");
+ fclose(infile);
+ return -1;
+ }
+ if (0 == cnt % 30) {
+ float vol_db = get_volume_decibel(pcm_buff, BUFFER_LENGTH, g_recorder->audio_type);
+ if (0 != sttdc_send_set_volume(g_recorder->uid, vol_db)) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Recorder] Fail to send recording volume(%f)", vol_db);
+ }
+ }
+
+ /* Audio read log */
+ if (0 == cnt % 50)
+ SLOG(LOG_DEBUG, TAG_STTD, "[Recorder][%d] Recording... : read_size(%d)", cnt, read_byte);
+ cnt++;
+ }
+ }
+ fclose(infile);
+ }
+
+ SLOG(LOG_DEBUG, TAG_STTD, "[Recorder][%d] total bytes(%d)", cnt, totalReadBytes);
+ return 0;
+}
+
+int sttd_recorder_stop_file()
+{
+ if (STTD_RECORDER_STATE_READY == g_recorder_state)
+ return 0;
+
+ /* Check engine id is valid */
+ if (NULL == g_recorder) {
+ SLOG(LOG_WARN, TAG_STTD, "[Recorder WARNING] Engine id is not valid");
+ return STTD_ERROR_INVALID_PARAMETER;
+ }
+
+ g_recorder->uid = -1;
+ g_recorder_state = STTD_RECORDER_STATE_READY;
+
+ return 0;
+}
diff --git a/server/sttd_recorder.h b/server/sttd_recorder.h
index 946a283..3c27c87 100644
--- a/server/sttd_recorder.h
+++ b/server/sttd_recorder.h
@@ -42,6 +42,10 @@ int sttd_recorder_start(int uid);
int sttd_recorder_stop();
+int sttd_recorder_start_file(int uid, const char *filepath);
+
+int sttd_recorder_stop_file();
+
#ifdef __cplusplus
}
diff --git a/server/sttd_server.c b/server/sttd_server.c
index a0d9fce..313774f 100644
--- a/server/sttd_server.c
+++ b/server/sttd_server.c
@@ -341,8 +341,8 @@ int __server_speech_status_callback(stte_speech_status_e status, void *user_para
return STTD_ERROR_OPERATION_FAILED;
}
- if (APP_STATE_RECORDING != state) {
- SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
+ if (APP_STATE_RECORDING != state && APP_STATE_PROCESSING != state) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording, state(%d), status(%d)", state, status);
return STTD_ERROR_INVALID_STATE;
}
@@ -1454,3 +1454,172 @@ int sttd_server_cancel(int uid)
return STTD_ERROR_NONE;
}
+
+int sttd_server_start_file(int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential,
+ const char* filepath, stte_audio_type_e audio_type, int sample_rate)
+{
+ if (NULL == lang || NULL == recognition_type || NULL == filepath) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
+ return STTD_ERROR_INVALID_PARAMETER;
+ }
+
+ /* check if uid is valid */
+ app_state_e state;
+ if (0 != sttd_client_get_state(uid, &state)) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
+ return STTD_ERROR_INVALID_PARAMETER;
+ }
+
+ /* check uid state */
+ if (APP_STATE_READY != state) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
+ return STTD_ERROR_INVALID_STATE;
+ }
+
+ int ret = 0;
+ if (false == stt_client_get_app_agreed(uid)) {
+ bool temp = false;
+ ret = sttd_engine_agent_check_app_agreed(appid, &temp);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
+ return ret;
+ }
+
+ if (false == temp) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server] App(%s) NOT confirmed that engine is available", appid);
+ return STTD_ERROR_PERMISSION_DENIED;
+ }
+
+ stt_client_set_app_agreed(uid);
+ }
+
+ /* check if engine use network */
+ if (true == sttd_engine_agent_need_network()) {
+ if (false == stt_network_is_connected()) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
+ return STTD_ERROR_OUT_OF_NETWORK;
+ }
+ }
+
+ if (0 != stt_client_set_current_recognition(uid)) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
+ return STTD_ERROR_RECORDER_BUSY;
+ }
+
+ /* engine start recognition */
+ SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s), appid(%s), file(%s), audio_type(%d), sample_rate(%d)", uid, lang, recognition_type, appid, filepath, audio_type, sample_rate);
+
+ /* 1. Set audio session */
+ ret = sttd_recorder_set_audio_session();
+ if (0 != ret) {
+ stt_client_unset_current_recognition();
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
+ return ret;
+ }
+
+ /* 2. Start engine to recognize */
+ ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
+ if (0 != ret) {
+ stt_client_unset_current_recognition();
+ sttd_recorder_unset_audio_session();
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start engine : result(%d)", ret);
+ return ret;
+ }
+
+ sttd_client_set_state(uid, APP_STATE_RECORDING);
+ sttdc_send_set_state(uid, APP_STATE_RECORDING);
+
+ /* 3. Start to send pcm from file to engine */
+ ret = sttd_engine_agent_recognize_start_file(uid, filepath);
+ if (0 != ret) {
+ stt_client_unset_current_recognition();
+ sttd_recorder_unset_audio_session();
+ sttd_engine_agent_recognize_cancel();
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start file : result(%d)", ret);
+ return ret;
+ }
+
+ /* 4. Stop to send pcm from file */
+ ret = sttd_engine_agent_recognize_stop_file();
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
+ stt_client_unset_current_recognition();
+ sttd_recorder_unset_audio_session();
+ sttd_engine_agent_recognize_cancel();
+ return ret;
+ }
+
+ /* 5. change & notify uid state */
+ sttd_client_set_state(uid, APP_STATE_PROCESSING);
+ sttdc_send_set_state(uid, APP_STATE_PROCESSING);
+
+ /* 6. Unset audio session */
+ ret = sttd_recorder_unset_audio_session();
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
+ stt_client_unset_current_recognition();
+ return ret;
+ }
+
+ /* 7. Stop engine */
+ ret = sttd_engine_agent_recognize_stop_engine();
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
+ stt_client_unset_current_recognition();
+ return ret;
+ }
+
+ return STTD_ERROR_NONE;
+}
+
+int sttd_server_cancel_file(int uid)
+{
+ /* check if uid is valid */
+ app_state_e state;
+ if (0 != sttd_client_get_state(uid, &state)) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
+ return STTD_ERROR_INVALID_PARAMETER;
+ }
+
+ /* check uid state */
+ if (APP_STATE_READY == state) {
+ SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
+ return STTD_ERROR_NONE;
+ }
+
+ stt_client_unset_current_recognition();
+
+ if (NULL != g_recording_timer) {
+ ecore_timer_del(g_recording_timer);
+ g_recording_timer = NULL;
+ }
+
+ if (NULL != g_processing_timer) {
+ ecore_timer_del(g_processing_timer);
+ g_processing_timer = NULL;
+ }
+
+ if (APP_STATE_RECORDING == state) {
+ /* Unset audio session */
+ int ret = sttd_recorder_unset_audio_session();
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
+ return ret;
+ }
+ }
+
+ /* change uid state */
+ sttd_client_set_state(uid, APP_STATE_READY);
+
+ /* cancel engine recognition */
+ int ret = sttd_engine_agent_recognize_cancel();
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
+ return ret;
+ }
+
+ /* Notify uid state change */
+ sttdc_send_set_state(uid, APP_STATE_READY);
+
+ return STTD_ERROR_NONE;
+}
diff --git a/server/sttd_server.h b/server/sttd_server.h
index 0fd6dd9..72c231b 100644
--- a/server/sttd_server.h
+++ b/server/sttd_server.h
@@ -76,6 +76,9 @@ int sttd_server_stop(int uid);
int sttd_server_cancel(int uid);
+int sttd_server_start_file(int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential, const char* filepath, stte_audio_type_e audio_type, int sample_rate);
+
+int sttd_server_cancel_file(int uid);
#ifdef __cplusplus