Add new functions for handling audio streaming 33/293733/2
authorSuyeon Hwang <stom.hwang@samsung.com>
Fri, 26 May 2023 06:39:28 +0000 (15:39 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Thu, 6 Jul 2023 07:59:33 +0000 (16:59 +0900)
- Requirements:
The engine library needs to recognize audio streaming from the clients.

- Contents:
To handle audio streaming from the clients, this patch adds new
functions. Through this new functions, the engine library can sends the
raw PCM data from the clients to the engine.

Change-Id: If54a437d0bf43cf2ead88f65a264225e645f57da
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
server/sttd_client_data.c
server/sttd_client_data.h
server/sttd_server.c
server/sttd_server.h

index a47427a..02e7b0e 100644 (file)
@@ -100,6 +100,7 @@ int sttd_client_add(int pid, unsigned int uid)
        info->state = APP_STATE_READY;
 
        info->app_agreed = false;
+       info->is_streaming = false;
 
        /* Add item to global list */
        g_client_list = g_slist_append(g_client_list, info);
@@ -531,4 +532,32 @@ int sttd_client_set_audio_id(unsigned int uid, const char* audio_id)
        }
 
        return 0;
-}
\ No newline at end of file
+}
+
+bool sttd_client_is_streaming(unsigned int uid)
+{
+       GSList *tmp = __client_get_item(uid);
+       if (NULL == tmp || NULL == tmp->data) {
+               SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Client Data ERROR] uid(%u) is NOT valid", uid);
+               return false;
+       }
+
+       client_info_s* hnd = tmp->data;
+       return hnd->is_streaming;
+}
+
+
+int sttd_client_set_streaming(unsigned int uid, bool is_streaming)
+{
+       GSList *tmp = __client_get_item(uid);
+       if (NULL == tmp || NULL == tmp->data) {
+               SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Client Data ERROR] uid(%u) is NOT valid", uid);
+               return STTD_ERROR_INVALID_PARAMETER;
+       }
+
+       client_info_s* hnd = tmp->data;
+       hnd->is_streaming = is_streaming;
+       SLOG(LOG_DEBUG, TAG_STTD, "[Client Data] Is streaming : %s", hnd->is_streaming ? "True": "False");
+
+       return STTD_ERROR_NONE;
+}
index 0b1e2f0..2dfa5c5 100644 (file)
@@ -37,9 +37,9 @@ typedef struct {
        char*   audio_id;
 
        app_state_e     state;
-/*     Ecore_Timer*    timer;  */
 
        bool    app_agreed;
+       bool    is_streaming;
 } client_info_s;
 
 typedef struct {
@@ -100,6 +100,10 @@ int sttd_client_get_audio_id(unsigned int uid, char** audio_id);
 
 int sttd_client_set_audio_id(unsigned int uid, const char* audio_id);
 
+bool sttd_client_is_streaming(unsigned int uid);
+
+int sttd_client_set_streaming(unsigned int uid, bool is_streaming);
+
 #ifdef __cplusplus
 }
 #endif
index 95d80a8..cf08e41 100644 (file)
@@ -1247,6 +1247,7 @@ int sttd_server_start(unsigned int uid, const char* lang, const char* recognitio
                SLOG(LOG_INFO, TAG_STTD, "[Server] Wait sound finish");
        }
 
+       sttd_client_set_streaming(uid, false);
        return STTD_ERROR_NONE;
 }
 
@@ -1346,6 +1347,11 @@ int sttd_server_stop(unsigned int uid)
                return STTD_ERROR_INVALID_STATE;
        }
 
+       if (sttd_client_is_streaming(uid)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current client is not started as default");
+               return STTD_ERROR_OPERATION_FAILED;
+       }
+
        delete_timers_related_to_recording_session();
 
        char* sound = NULL;
@@ -1423,6 +1429,223 @@ int sttd_server_stop(unsigned int uid)
        return STTD_ERROR_NONE;
 }
 
+static bool play_sound(const char *path, wav_player_playback_completed_cb callback, void *user_data)
+{
+       sound_stream_info_h wav_stream_info_h = NULL;
+       if (SOUND_MANAGER_ERROR_NONE != sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, NULL, NULL, &wav_stream_info_h)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to create stream info for playing wav");
+               return false;
+       }
+
+       int ret = wav_player_start_new(path, wav_stream_info_h, callback, user_data, NULL);
+       if (SOUND_MANAGER_ERROR_NONE != sound_manager_destroy_stream_information(wav_stream_info_h)) {
+               SLOG(LOG_WARN, TAG_STTD, "[Server WARN] Fail to destroy stream info for playing wav");
+       }
+
+       if (WAV_PLAYER_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
+               return false;
+       }
+
+       return true;
+}
+
+static bool play_start_sound_for_uid(unsigned int uid)
+{
+       char* sound = NULL;
+       if (STTD_ERROR_NONE != sttd_client_get_start_sound(uid, &sound)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start sound");
+               return false;
+       }
+
+       if (NULL == sound) {
+               SLOG(LOG_INFO, TAG_STTD, "[Server] There is no start sound");
+               return false;
+       }
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server] start sound : %s", sound);
+       bool ret = play_sound(sound, NULL, NULL);
+       free(sound);
+
+       return ret;
+}
+
+int sttd_server_start_audio_streaming(unsigned int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential, const char* audio_id)
+{
+       if (NULL == lang || NULL == recognition_type) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
+               return STTD_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret = __sttd_server_check_precondition_to_start(uid, appid);
+       if (STTD_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to satisfy preconditions, ret(0x%x)", ret);
+               return ret;
+       }
+
+       if (STTD_ERROR_NONE != 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;
+       }
+
+       delete_timers_related_to_recording_session();
+
+       ret = sttd_client_set_audio_id(uid, audio_id);
+       if (STTD_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set audio_id(%s)", audio_id);
+               return ret;
+       }
+
+       /* engine start recognition */
+       SLOG(LOG_INFO, TAG_STTD, "[Server] start : uid(%u), lang(%s), recog_type(%s)", uid, lang, recognition_type);
+
+       play_start_sound_for_uid(uid);
+
+       /* 3. Create recorder & engine initialize */
+       ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
+       if (STTD_ERROR_NONE != ret) {
+               stt_client_unset_current_recognition();
+               sttd_recorder_unset_audio_session();
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d/%s)", ret, get_error_message(ret));
+               return ret;
+       }
+
+       if (STTD_ERROR_NONE != strcmp(STTE_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type)) {
+               if (NULL == g_processing_timer) {
+                       g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
+               }
+       }
+
+       /* change uid state */
+       sttd_client_set_state(uid, APP_STATE_RECORDING);
+
+       g_recording_log_count = 0;
+
+       app_state_e temp_app_state = APP_STATE_CREATED;
+       if (0 != sttd_client_get_state(uid, &temp_app_state)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid");
+               return STTD_ERROR_INVALID_PARAMETER;
+       }
+
+       if (APP_STATE_READY != temp_app_state && 0 != stt_client_get_current_recognition()) {
+               /* Notify uid state change */
+               sttdc_send_set_state(uid, APP_STATE_RECORDING);
+       }
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Start recognition");
+
+       sttd_client_set_streaming(uid, true);
+       return STTD_ERROR_NONE;
+}
+
+int sttd_server_send_audio_streaming(unsigned int uid, const char *data, size_t data_size)
+{
+       app_state_e state = APP_STATE_CREATED;
+       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_PROCESSING == state) {
+               SLOG(LOG_INFO, TAG_STTD, "[Server] State is already processing. Skip stop behavior");
+               return STTD_ERROR_NONE;
+       }
+
+       if (APP_STATE_RECORDING != state) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
+               return STTD_ERROR_INVALID_STATE;
+       }
+
+       if (false == sttd_client_is_streaming(uid)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current client is not started as audio streaming");
+               return STTD_ERROR_OPERATION_FAILED;
+       }
+
+       int ret = __server_audio_recorder_callback(data, data_size);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send audio data");
+               return STTD_ERROR_OPERATION_FAILED;
+       }
+
+       return STTD_ERROR_NONE;
+}
+
+static bool play_stop_sound_for_uid(unsigned int uid)
+{
+       char* sound = NULL;
+       if (STTD_ERROR_NONE != sttd_client_get_stop_sound(uid, &sound)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start sound");
+               return false;
+       }
+
+       if (NULL == sound) {
+               SLOG(LOG_INFO, TAG_STTD, "[Server] There is no start sound");
+               return false;
+       }
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server] stop sound : %s", sound);
+       bool ret = play_sound(sound, NULL, NULL);
+       free(sound);
+
+       return ret;
+}
+
+int sttd_server_stop_audio_streaming(unsigned int uid)
+{
+       /* check if uid is valid */
+       app_state_e state = APP_STATE_CREATED;
+       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_PROCESSING == state) {
+               SLOG(LOG_INFO, TAG_STTD, "[Server] State is already processing. Skip stop behavior");
+               return STTD_ERROR_NONE;
+       }
+
+       if (APP_STATE_RECORDING != state) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
+               return STTD_ERROR_INVALID_STATE;
+       }
+
+       if (false == sttd_client_is_streaming(uid)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current client is not started as audio streaming");
+               return STTD_ERROR_OPERATION_FAILED;
+       }
+
+       delete_timers_related_to_recording_session();
+
+       /* 2. Request wav play */
+       play_stop_sound_for_uid(uid);
+
+       /* Stop engine */
+       int ret = sttd_engine_agent_recognize_stop_engine();
+       if (0 != ret) {
+               stt_client_unset_current_recognition();
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
+               return ret;
+       }
+
+       /* change uid state */
+       sttd_client_set_state(uid, APP_STATE_PROCESSING);
+
+       /* Notify uid state change */
+       sttdc_send_set_state(uid, APP_STATE_PROCESSING);
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Stop recognition");
+
+       SLOG(LOG_INFO, TAG_STTD, "[INFO] Add g_processing_timer");
+       if (NULL == g_processing_timer) {
+               g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
+       }
+
+       sttd_client_set_streaming(uid, false);
+       return STTD_ERROR_NONE;
+}
+
 static int __sttd_server_cancel(unsigned int uid)
 {
        /* check if uid is valid */
index b24abc7..141a8f7 100644 (file)
@@ -76,6 +76,12 @@ int sttd_server_start(unsigned int uid, const char* lang, const char* recognitio
 
 int sttd_server_stop(unsigned int uid);
 
+int sttd_server_start_audio_streaming(unsigned int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential, const char* audio_id);
+
+int sttd_server_send_audio_streaming(unsigned int uid, const char *data, size_t data_size);
+
+int sttd_server_stop_audio_streaming(unsigned int uid);
+
 int sttd_server_cancel(unsigned int uid);
 
 int sttd_server_start_file(unsigned int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential, const char* filepath);