Use single play thread to play PCM data 10/266210/9
authorSuyeon Hwang <stom.hwang@samsung.com>
Wed, 21 Apr 2021 10:40:41 +0000 (19:40 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Tue, 15 Feb 2022 06:19:43 +0000 (15:19 +0900)
To simplify the management of player thread, this patch makes only one sub thread to play PCM data.

Change-Id: I9f0a050f59411bb692e038488e474dce0716cb46
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
server/ttsd_player.c
server/ttsd_server.c

index cb51e1ad263c4b74882ef7d3baca13072e3ebd6e..cd37958027de9819b8d3532e89dac1a5c9a7e03b 100644 (file)
@@ -112,6 +112,7 @@ static double g_bg_volume_ratio;
 static pthread_mutex_t g_play_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t g_player_control_mutex = PTHREAD_MUTEX_INITIALIZER;
 
+static pthread_cond_t g_play_thread_cond = PTHREAD_COND_INITIALIZER;
 /*
 * Internal Interfaces
 */
@@ -580,7 +581,7 @@ bool ttsd_player_does_interrupt_have_playback_focus()
        return result;
 }
 
-static void __play_thread(void *data, Ecore_Thread *thread)
+static void __play_thread_old(void *data, Ecore_Thread *thread)
 {
        SLOG(LOG_DEBUG, tts_tag(), "@@@ Start thread");
 
@@ -599,7 +600,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
        /* set volume policy as 40% */
        __set_policy_for_playing();
        while (1) { // 1st while(1)
-               pthread_mutex_lock(&g_play_thread_mutex);
                /* check g_playing_info one more time */
                if (false == __is_player_valid(player)) {
                        SLOG(LOG_INFO, tts_tag(), "[Player INFO] Player is not valid");
@@ -609,7 +609,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                                SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret);
                        }
                        __unset_policy_for_playing();
-                       pthread_mutex_unlock(&g_play_thread_mutex);
                        return;
                }
 
@@ -662,7 +661,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
 
                                /* unset volume policy, volume will be 100% */
                                __unset_policy_for_playing();
-                               pthread_mutex_unlock(&g_play_thread_mutex);
                                return;
                        }
                        __set_playing_status(true);
@@ -694,7 +692,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                                                }
                                                /* unset volume policy, volume will be 100% */
                                                __unset_policy_for_playing();
-                                               pthread_mutex_unlock(&g_play_thread_mutex);
                                                return;
                                        } else if (0 < ttsd_data_get_sound_data_size(player->uid)) {
                                                /* new audio data come */
@@ -719,8 +716,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                                                        /* unset volume policy, volume will be 100% */
                                                        __unset_policy_for_playing();
                                                }
-                                       } else { // TTSD_SYNTHESIS_CONTROL_DOING
-                                               SLOG(LOG_ERROR, tts_tag(), "[Player] Sound data is NULL, while engine is on processing to synthesize");
                                        }
                                } // end of 2nd while(1). waiting for new audio data come
 
@@ -733,7 +728,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
 
                                /* resume play thread */
                                player->state = APP_STATE_PLAYING;
-                               pthread_mutex_unlock(&g_play_thread_mutex);
                                continue;
                        } // NULL == sound_data
 
@@ -750,7 +744,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                                        /* unset volume policy, volume will be 100% */
                                        __unset_policy_for_playing();
                                        ttsd_data_clear_sound_data(&sound_data);
-                                       pthread_mutex_unlock(&g_play_thread_mutex);
                                        return;
                                }
 
@@ -781,7 +774,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                                                /* unset volume policy, volume will be 100% */
                                                __unset_policy_for_playing();
                                                ttsd_data_clear_sound_data(&sound_data);
-                                               pthread_mutex_unlock(&g_play_thread_mutex);
                                                return;
                                        }
 
@@ -801,7 +793,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                                } // TTSE_RESULT_EVENT_FINISH == sound_data->event
                                SLOG(LOG_INFO, tts_tag(), "[Player] Event(%d) utterance : uid(%u), uttid(%d)", sound_data->event, player->uid, sound_data->utt_id);
                                ttsd_data_clear_sound_data(&sound_data);
-                               pthread_mutex_unlock(&g_play_thread_mutex);
                                continue;
                        } // (NULL == sound_data->data || 0 >= sound_data->data_size)
                } // NO player->is_paused_data
@@ -819,8 +810,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                                __unset_policy_for_playing();
 
                                ttsd_data_clear_sound_data(&sound_data);
-
-                               pthread_mutex_unlock(&g_play_thread_mutex);
                                return;
                        }
 
@@ -853,11 +842,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                                        __unset_policy_for_playing();
 
                                        ttsd_data_clear_sound_data(&sound_data);
-
-                                       pthread_mutex_unlock(&g_play_thread_mutex);
-                                       pthread_mutex_lock(&g_player_control_mutex);
-                                       g_playing_info = NULL;
-                                       pthread_mutex_unlock(&g_player_control_mutex);
                                        return;
                                }
                                SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Prepare audio");
@@ -889,8 +873,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                                __unset_policy_for_playing();
 
                                ttsd_data_clear_sound_data(&sound_data);
-
-                               pthread_mutex_unlock(&g_play_thread_mutex);
                                return;
                        } // (NULL == g_playing_info && APP_STATE_PAUSED != player->state)
 
@@ -917,7 +899,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                                }
                                /* unset volume policy, volume will be 100% */
                                __unset_policy_for_playing();
-                               pthread_mutex_unlock(&g_play_thread_mutex);
                                return;
                        } // (APP_STATE_PAUSED == player->state)
                } // while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state)
@@ -938,7 +919,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                        /* unset volume policy, volume will be 100% */
                        __unset_policy_for_playing();
                        ttsd_data_clear_sound_data(&sound_data);
-                       pthread_mutex_unlock(&g_play_thread_mutex);
                        return;
                } // (NULL == g_playing_info && APP_STATE_READY == player->state)
 
@@ -952,7 +932,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                                /* unset volume policy, volume will be 100% */
                                __unset_policy_for_playing();
                                ttsd_data_clear_sound_data(&sound_data);
-                               pthread_mutex_unlock(&g_play_thread_mutex);
                                return;
                        }
 
@@ -966,7 +945,6 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                                /* unset volume policy, volume will be 100% */
                                __unset_policy_for_playing();
                                ttsd_data_clear_sound_data(&sound_data);
-                               pthread_mutex_unlock(&g_play_thread_mutex);
                                return;
                        }
 
@@ -985,12 +963,30 @@ static void __play_thread(void *data, Ecore_Thread *thread)
                        /* unset volume policy, volume will be 100% */
                        __unset_policy_for_playing();
                        ttsd_data_clear_sound_data(&sound_data);
-                       pthread_mutex_unlock(&g_play_thread_mutex);
                        return;
                }
+       } // end of 1st while(1)
+}
+
+static void __play_thread(void *data, Ecore_Thread *thread)
+{
+       SLOG(LOG_INFO, tts_tag(), "[Player] play thread is on");
+
+       while (g_player_init) {
+               SLOG(LOG_INFO, tts_tag(), "[Player] Wait play request...");
+               pthread_cond_wait(&g_play_thread_cond, &g_play_thread_mutex);
+               if (false == g_player_init) {
+                       SLOG(LOG_INFO, tts_tag(), "[Player] Player is released");
+                       pthread_mutex_unlock(&g_play_thread_mutex);
+                       break;
+               }
 
+               __play_thread_old(data, thread);
                pthread_mutex_unlock(&g_play_thread_mutex);
-       } // end of 1st while(1)
+               pthread_mutex_lock(&g_player_control_mutex);
+               g_playing_info = NULL;
+               pthread_mutex_unlock(&g_player_control_mutex);
+       }
 }
 
 int __create_ducking_handle(void)
@@ -1084,6 +1080,8 @@ int ttsd_player_init()
                return -1;
        }
 
+       ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
+
        g_player_init = true;
 
        pthread_mutex_unlock(&g_player_control_mutex);
@@ -1181,6 +1179,7 @@ int ttsd_player_release(void)
        /* clear g_player_list */
        g_playing_info = NULL;
        g_player_init = false;
+       pthread_cond_broadcast(&g_play_thread_cond);
 
        g_stream_info_h = NULL;
 
@@ -1312,12 +1311,10 @@ int ttsd_player_play(unsigned int uid)
        }
 
        current->state = APP_STATE_PLAYING;
-
        g_playing_info = current;
 
-       SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
        SLOG(LOG_INFO, tts_tag(), "[Player] Run thread");
-       ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
+       pthread_cond_broadcast(&g_play_thread_cond);
 
        pthread_mutex_unlock(&g_player_control_mutex);
        return 0;
@@ -1471,7 +1468,7 @@ int ttsd_player_resume(unsigned int uid)
        g_playing_info = current;
 
        SLOG(LOG_INFO, tts_tag(), "[Player] Resume to run thread");
-       ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
+       pthread_cond_broadcast(&g_play_thread_cond);
 
        pthread_mutex_unlock(&g_player_control_mutex);
        return 0;
index 8820e746d08a4c8da0277d50d9081f65d13ed656..29b55b5b66eea7564a2d89c2b0cb51d9c1f4cd6f 100644 (file)
@@ -985,6 +985,23 @@ int ttsd_server_add_queue(unsigned int uid, const char* text, const char* lang,
        return TTSD_ERROR_NONE;
 }
 
+static int __pause_client(unsigned int uid)
+{
+       int ret = ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
+       if (TTSD_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail set pause state() : ret(%d)", ret);
+               return TTSD_ERROR_OPERATION_FAILED;
+       }
+
+       ret = ttsd_player_pause(uid);
+       if (TTSD_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail player_pause() : ret(%d)", ret);
+               return TTSD_ERROR_OPERATION_FAILED;
+       }
+
+       return TTSD_ERROR_NONE;
+}
+
 void __send_interrupt_client(unsigned int uid)
 {
        SLOG(LOG_INFO, tts_tag(), "[Server] Send new state by policy. uid(%u)", uid);
@@ -994,14 +1011,14 @@ void __send_interrupt_client(unsigned int uid)
                return;
        }
 
-       ttsd_mode_e mode = ttsd_data_get_mode(uid);
-       if (TTSD_MODE_DEFAULT != mode) {
-               /* send message to client about changing state */
-               ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_READY);
-       } else {
-               ttsdc_ipc_send_set_state_message(pid, uid, APP_STATE_PAUSED);
+       app_tts_state_e state = APP_STATE_CREATED;
+
+       if (0 != ttsd_data_get_client_state(uid, &state)) {
+               SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to get state. uid(%u), pid(%d)", uid, pid);
+               return;
        }
 
+       ttsdc_ipc_send_set_state_message(pid, uid, state);
        SLOG(LOG_INFO, tts_tag(), "[Server] Finish to send new state by policy. uid(%u)", uid);
        return;
 }
@@ -1037,17 +1054,15 @@ int ttsd_server_play(unsigned int uid, const char* credential)
        unsigned int current_uid = ttsd_data_get_current_playing();
        SLOG(LOG_INFO, tts_tag(), "[Server] playing uid (%u)", current_uid);
 
-       if (uid != current_uid && -1 != current_uid) {
+       if (uid != current_uid && 0 <= ttsd_data_is_client(current_uid)) {
                if (TTSD_MODE_DEFAULT != ttsd_data_get_mode(current_uid)) {
                        /* Send interrupt message */
                        SLOG(LOG_DEBUG, tts_tag(), "[Server] Old uid(%u) will be interrupted into 'Stop' state ", current_uid);
 
-                       /* pause player */
+                       /* stop player */
                        if (0 != ttsd_server_stop(current_uid)) {
                                SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to stop server and player : uid (%u)", current_uid);
                        }
-
-                       __send_interrupt_client(current_uid);
                } else {
                        /* Default mode policy of interrupt is "Pause" */
 
@@ -1055,15 +1070,12 @@ int ttsd_server_play(unsigned int uid, const char* credential)
                        SLOG(LOG_DEBUG, tts_tag(), "[Server] Old uid(%u) 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 (%u)", current_uid);
+                       if (0 != __pause_client(current_uid)) {
+                               SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to ttsd_server_pause() : uid (%u)", current_uid);
                        }
-
-                       /* change state */
-                       ttsd_data_set_client_state(current_uid, APP_STATE_PAUSED);
-
-                       __send_interrupt_client(current_uid);
                }
+
+               __send_interrupt_client(current_uid);
        }
 
        /* Change current play */
@@ -1076,21 +1088,20 @@ int ttsd_server_play(unsigned int uid, const char* credential)
                return TTSD_ERROR_OPERATION_FAILED;
        }
 
+       int ret = TTSD_ERROR_NONE;
        if (APP_STATE_PAUSED == state) {
                SLOG(LOG_DEBUG, tts_tag(), "[Server] uid(%u) is 'Pause' state : resume player", uid);
-
                g_is_paused = false;
-
-               /* Resume player */
-               if (0 != ttsd_player_resume(uid)) {
-                       SLOG(LOG_WARN, tts_tag(), "[Server WARNING] Fail to ttsd_player_resume()");
-               }
+               ret = ttsd_player_resume(uid);
        } else {
                SLOG(LOG_DEBUG, tts_tag(), "[Server] Play player. uid(%u)", uid);
+               ret = ttsd_player_play(uid);
+       }
 
-               if (0 != ttsd_player_play(uid)) {
-                       SLOG(LOG_WARN, tts_tag(), "[Server WARNING] Fail to ttsd_player_play()");
-               }
+       if (TTSD_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to play sound : uid(%u)", uid);
+               ttsd_data_set_client_state(uid, state);
+               return TTSD_ERROR_OPERATION_FAILED;
        }
 
        ttsd_data_set_credential(uid, credential);
@@ -1124,19 +1135,17 @@ int ttsd_server_stop(unsigned int uid)
                if (TTSD_SYNTHESIS_CONTROL_DOING == synth_control && uid == ttsd_data_get_current_playing()) {
                        SLOG(LOG_DEBUG, tts_tag(), "[Server] TTS-engine is running");
 
-                       int ret = 0;
-                       ret = ttsd_engine_cancel_synthesis();
-                       if (0 != ret)
+                       int ret = ttsd_engine_cancel_synthesis();
+                       if (TTSD_ERROR_NONE != ret)
                                SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to cancel synthesis : ret(%d)", ret);
                }
                ttsd_set_synth_control(TTSD_SYNTHESIS_CONTROL_EXPIRED);
 
                /* stop player */
-               if (0 != ttsd_player_stop(uid)) {
+               ttsd_data_set_client_state(uid, APP_STATE_READY);
+               if (TTSD_ERROR_NONE != ttsd_player_stop(uid)) {
                        SLOG(LOG_WARN, tts_tag(), "[Server] Fail to ttsd_player_stop()");
                }
-
-               ttsd_data_set_client_state(uid, APP_STATE_READY);
        }
 
        /* Reset all data */
@@ -1164,15 +1173,12 @@ int ttsd_server_pause(unsigned int uid, int* utt_id)
        *utt_id = g_utt.uttid;
        SLOG(LOG_INFO, tts_tag(), "[Server] server pause, uid(%u), g_uid(%u), utt_id(%d)", uid, g_utt.uid, *utt_id);
 
-       int ret = 0;
-       ret = ttsd_player_pause(uid);
-       if (0 != ret) {
-               SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail player_pause() : ret(%d)", ret);
+       int ret = __pause_client(uid);
+       if (TTSD_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to pause player : ret(%d)", ret);
                return TTSD_ERROR_OPERATION_FAILED;
        }
 
-       ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
-
        return TTSD_ERROR_NONE;
 }
 
@@ -1304,17 +1310,15 @@ int ttsd_server_play_pcm(unsigned int uid)
        unsigned int current_uid = ttsd_data_get_current_playing();
        SLOG(LOG_INFO, tts_tag(), "[Server] playing uid (%u)", current_uid);
 
-       if (uid != current_uid && -1 != current_uid) {
+       if (uid != current_uid && 0 <= ttsd_data_is_client(current_uid)) {
                if (TTSD_MODE_DEFAULT != ttsd_data_get_mode(current_uid)) {
                        /* Send interrupt message */
                        SLOG(LOG_DEBUG, tts_tag(), "[Server] Old uid(%u) will be interrupted into 'Stop' state ", current_uid);
 
-                       /* pause player */
+                       /* stop player */
                        if (0 != ttsd_server_stop(current_uid)) {
                                SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to stop server and player : uid (%u)", current_uid);
                        }
-
-                       __send_interrupt_client(current_uid);
                } else {
                        /* Default mode policy of interrupt is "Pause" */
 
@@ -1322,15 +1326,12 @@ int ttsd_server_play_pcm(unsigned int uid)
                        SLOG(LOG_DEBUG, tts_tag(), "[Server] Old uid(%u) 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 (%u)", current_uid);
+                       if (0 != __pause_client(current_uid)) {
+                               SLOG(LOG_WARN, tts_tag(), "[Server ERROR] Fail to ttsd_server_pause() : uid (%u)", current_uid);
                        }
-
-                       /* change state */
-                       ttsd_data_set_client_state(current_uid, APP_STATE_PAUSED);
-
-                       __send_interrupt_client(current_uid);
                }
+
+               __send_interrupt_client(current_uid);
        }
 
        /* Change current play */
@@ -1339,27 +1340,20 @@ int ttsd_server_play_pcm(unsigned int uid)
                return TTSD_ERROR_OPERATION_FAILED;
        }
 
+       int ret = TTSD_ERROR_NONE;
        if (APP_STATE_PAUSED == state) {
                SLOG(LOG_DEBUG, tts_tag(), "[Server] uid(%u) is 'Pause' state : resume player", uid);
-
-               /* Resume player */
-               if (0 != ttsd_player_resume(uid)) {
-                       SLOG(LOG_WARN, tts_tag(), "[Server WARNING] Fail to ttsd_player_resume()");
-               }
+               g_is_paused = false;
+               ret = ttsd_player_resume(uid);
        } else {
-               if (0 != ttsd_player_play(uid)) {
-                       SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to play pcm sound : uid(%u)", uid);
-
-                       // Change ready state
-                       ttsd_server_stop_pcm(uid);
+               SLOG(LOG_DEBUG, tts_tag(), "[Server] Play player. uid(%u)", uid);
+               ret = ttsd_player_play(uid);
+       }
 
-                       int tmp_pid = ttsd_data_get_pid(uid);
-                       if (tmp_pid <= 0) {
-                               SLOG(LOG_WARN, tts_tag(), "[Server WARNING] Fail to send set_state_message. uid(%u)", uid);
-                       } else {
-                               ttsdc_ipc_send_set_state_message(tmp_pid, uid, APP_STATE_READY);
-                       }
-               }
+       if (TTSD_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to play sound : uid(%u)", uid);
+               ttsd_data_set_client_state(uid, state);
+               return TTSD_ERROR_OPERATION_FAILED;
        }
 
        return TTSD_ERROR_NONE;
@@ -1456,18 +1450,6 @@ int ttsd_server_add_pcm(unsigned int uid, int event, void* data, int data_size,
                        free(temp_sound_data);
                        temp_sound_data = NULL;
                }
-
-/*             if (0 != ttsd_player_play(uid)) {
-                       SLOG(LOG_ERROR, tts_tag(), "[Server ERROR] Fail to play sound : uid(%u)", uid);
-
-                       // Change ready state
-                       ttsd_server_stop(uid);
-
-                       int tmp_pid;
-                       tmp_pid = ttsd_data_get_pid(uid);
-                       ttsdc_ipc_send_set_state_message(tmp_pid, uid, APP_STATE_READY);
-               }
-*/
        } else {
                SLOG(LOG_DEBUG, tts_tag(), "[SERVER] Event : TTSE_RESULT_EVENT_ERROR");
        }