From 1f36a3377bf13eb09934e6edf566a24e95ce503b Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Mon, 10 May 2021 18:20:28 +0900 Subject: [PATCH] Use AudioStream class on ttsd_player Change-Id: Ifddb83248619e710356fab0ee0bcef274b1b8d29 Signed-off-by: Suyeon Hwang --- server/ttsd_player.cpp | 304 ++++++------------------------------------------- 1 file changed, 37 insertions(+), 267 deletions(-) diff --git a/server/ttsd_player.cpp b/server/ttsd_player.cpp index 3547454..e268fbe 100644 --- a/server/ttsd_player.cpp +++ b/server/ttsd_player.cpp @@ -11,9 +11,7 @@ * limitations under the License. */ -#include #include -#include #include #include "ttsd_main.h" @@ -23,6 +21,7 @@ #include "ttsd_ipc.h" #include "BackgroundVolume.h" +#include "AudioStream.h" #include "tts_internal.h" #include "ttsd_server.h" @@ -31,13 +30,6 @@ * Internal data structure */ -typedef enum { - AUDIO_STATE_NONE = 0, - AUDIO_STATE_READY, - AUDIO_STATE_WAIT_FOR_PLAYING, - AUDIO_STATE_PLAY -} audio_state_e; - typedef struct { unsigned int uid; /** client id */ app_tts_state_e state; /** client state */ @@ -51,7 +43,6 @@ typedef struct { } player_s; #define SOUND_BUFFER_LENGTH 2048 -#define FOCUS_SERVER_READY "/tmp/.sound_server_ready" static const intptr_t CHECK_TIMER_DELETE = 1; static const int EXTRA_INFO_LENGTH = 20; @@ -77,17 +68,6 @@ static GList *g_player_list; /** current player information */ static player_s* g_playing_info; -/* player state */ -static audio_state_e g_audio_state; - -static ttse_audio_type_e g_audio_type; - -static int g_sampling_rate; - -static audio_out_h g_audio_h; - -static sound_stream_info_h g_stream_info_h; - static bool g_is_set_policy; /* CAUTION! @@ -102,6 +82,7 @@ static pthread_mutex_t g_player_control_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t g_play_thread_cond = PTHREAD_COND_INITIALIZER; static BackgroundVolume* g_background_volume = nullptr; +static AudioStream* g_audio_stream = nullptr; /* * Internal Interfaces @@ -218,39 +199,14 @@ player_s* __player_get_item(unsigned int uid) return NULL; } -static bool __is_focus_released_on_playing(sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state) +static void __focus_release_callback() { if (NULL == g_playing_info) { - SLOG(LOG_INFO, tts_tag(), "[Player] No current player"); - return false; - } - - if (APP_STATE_PLAYING != g_playing_info->state || AUDIO_STATE_NONE == g_audio_state || AUDIO_STATE_READY == g_audio_state) { - SLOG(LOG_INFO, tts_tag(), "[Player] Audio is not played"); - return false; - } - - if (SOUND_STREAM_FOCUS_FOR_PLAYBACK != focus_mask || SOUND_STREAM_FOCUS_STATE_RELEASED != focus_state) { - SLOG(LOG_INFO, tts_tag(), "[Player] Playback focus is not released"); - return false; - } - - return true; -} - -static void __player_focus_state_cb(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state, - sound_stream_focus_change_reason_e reason_for_change, int sound_behavior, const char *extra_info, void *user_data) -{ - SLOG(LOG_DEBUG, tts_tag(), "@@@ Focus state changed cb"); - SLOG(LOG_WARN, tts_tag(), "[Player] focus state changed to (%d) with reason(%d) and extra info(%s)", (int)focus_state, (int)reason_for_change, extra_info); - - if (stream_info != g_stream_info_h) { - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Invalid stream info handle"); + SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player"); return; } - if (false == __is_focus_released_on_playing(focus_mask, focus_state)) { - SLOG(LOG_INFO, tts_tag(), "[Player INFO] Playback focus is not released on playing"); + if (APP_STATE_PLAYING != g_playing_info->state) { return; } @@ -261,8 +217,6 @@ static void __player_focus_state_cb(sound_stream_info_h stream_info, sound_strea case TTSD_MODE_DEFAULT: { SLOG(LOG_DEBUG, tts_tag(), "[Player] Pause current player - mode(%d)", mode); - g_audio_state = AUDIO_STATE_READY; - if (0 != ttsd_player_pause(uid)) { SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to pause the player"); break; @@ -284,7 +238,6 @@ static void __player_focus_state_cb(sound_stream_info_h stream_info, sound_strea case TTSD_MODE_SCREEN_READER: { SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop current player - mode(%d)", mode); - g_audio_state = AUDIO_STATE_READY; ttsd_send_all_stop(); break; } @@ -303,60 +256,6 @@ static void __player_focus_state_cb(sound_stream_info_h stream_info, sound_strea return; } -static int __create_audio_out(ttse_audio_type_e type, int rate) -{ - int ret = -1; - audio_sample_type_e sample_type; - - if (TTSE_AUDIO_TYPE_RAW_S16 == type) { - sample_type = AUDIO_SAMPLE_TYPE_S16_LE; - } else { - sample_type = AUDIO_SAMPLE_TYPE_U8; - } - - ret = audio_out_create_new(rate, AUDIO_CHANNEL_MONO, sample_type, &g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - g_audio_state = AUDIO_STATE_NONE; - g_audio_h = NULL; - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio"); - return -1; - } else { - SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create audio"); - } - - g_audio_type = type; - g_sampling_rate = rate; - - g_audio_state = AUDIO_STATE_READY; - - return 0; -} - -static int __destroy_audio_out() -{ - if (NULL == g_audio_h) { - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current handle is not valid"); - return -1; - } - - int ret = -1; - ret = audio_out_destroy(g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to destroy audio"); - return -1; - } else { - SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy audio"); - } - - g_audio_type = TTSE_AUDIO_TYPE_RAW_S16; - g_sampling_rate = 0; - - g_audio_state = AUDIO_STATE_NONE; - g_audio_h = NULL; - - return 0; -} - static void __end_play_thread(void *data, Ecore_Thread *thread) { SLOG(LOG_ERROR, tts_tag(), "@@@ End thread"); @@ -364,24 +263,12 @@ static void __end_play_thread(void *data, Ecore_Thread *thread) static void __set_policy_for_playing(void) { - /* Set stream info */ const char* extra_info = NULL; if (TTSD_MODE_INTERRUPT == ttsd_get_mode()) { extra_info = "TTSD_MODE_INTERRUPT"; } - int ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, extra_info); - if (SOUND_MANAGER_ERROR_NONE != ret) { - SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to acquire focus"); - } else { - SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Success to acquire focus"); - } - - ret = audio_out_set_sound_stream_info(g_audio_h, g_stream_info_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to set stream info"); - } - + g_audio_stream->acquireSoundFocus(extra_info); g_background_volume->applyVolumeRatio(); g_is_set_policy = true; SLOG(LOG_ERROR, tts_tag(), "[BG] g_is_set_policy(%d)", g_is_set_policy); @@ -392,21 +279,7 @@ static void __set_policy_for_playing(void) static void __unset_policy_for_playing() { - /* Unset stream info */ - sound_stream_focus_state_e state_for_playing = SOUND_STREAM_FOCUS_STATE_ACQUIRED; - int ret = sound_manager_get_focus_state(g_stream_info_h, &state_for_playing, NULL); - if (SOUND_MANAGER_ERROR_NONE != ret) { - SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to get focus state: %d", ret); - } - - if (SOUND_STREAM_FOCUS_STATE_ACQUIRED == state_for_playing) { - SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] release focus (mode: %d)", ttsd_get_mode()); - ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL); - if (SOUND_MANAGER_ERROR_NONE != ret) { - SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to release focus: %d", ret); - } - } - + g_audio_stream->releaseSoundFocus(); g_background_volume->recoverVolumeRatio(); g_is_set_policy = false; SLOG(LOG_ERROR, tts_tag(), "[BG] g_is_set_policy(%d)", g_is_set_policy); @@ -466,11 +339,7 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) /* check g_playing_info one more time */ if (false == __is_player_valid(player)) { SLOG(LOG_INFO, tts_tag(), "[Player INFO] Player is not valid"); - g_audio_state = AUDIO_STATE_READY; - ret = audio_out_unprepare(g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret); - } + g_audio_stream->unprepareAudioOut(); __unset_policy_for_playing(); return; } @@ -498,14 +367,7 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) if (NULL == sound_data) { /* Request unprepare */ - ret = audio_out_unprepare(g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret); - } else { - SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio"); - } - - g_audio_state = AUDIO_STATE_READY; + g_audio_stream->unprepareAudioOut(); /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); @@ -528,15 +390,9 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) if (false == __is_player_valid(player)) { /* current playing uid is replaced */ SLOG(LOG_INFO, tts_tag(), "[Player] Finish thread"); - if (AUDIO_STATE_PLAY == g_audio_state) { + if (AudioStream::AUDIO_STATE_PLAY == g_audio_stream->getState()) { /* release audio & recover session */ - ret = audio_out_unprepare(g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret); - } else { - SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio"); - } - g_audio_state = AUDIO_STATE_READY; + g_audio_stream->unprepareAudioOut(); } /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); @@ -551,15 +407,9 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) ttsd_synthesis_control_e synth_control = ttsd_get_synth_control(); if (TTSD_SYNTHESIS_CONTROL_DOING != synth_control) { SLOG(LOG_INFO, tts_tag(), "[Server INFO] synth_control(%d)", synth_control); - if (AUDIO_STATE_PLAY == g_audio_state) { + if (AudioStream::AUDIO_STATE_PLAY == g_audio_stream->getState()) { /* release audio & recover session */ - ret = audio_out_unprepare(g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret); - } else { - SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio"); - } - g_audio_state = AUDIO_STATE_READY; + g_audio_stream->unprepareAudioOut(); /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); @@ -569,7 +419,7 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) SLOG(LOG_INFO, tts_tag(), "[Player] Finish to wait for new audio data come"); - if (AUDIO_STATE_READY == g_audio_state || AUDIO_STATE_WAIT_FOR_PLAYING == g_audio_state) { + if (AudioStream::AUDIO_STATE_READY == g_audio_stream->getState() || AudioStream::AUDIO_STATE_WAIT_FOR_PLAYING == g_audio_stream->getState()) { /* set volume policy as 40%, when resume play thread*/ __set_policy_for_playing(); } @@ -649,24 +499,14 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) } // NO player->is_paused_data // If there is any change in audio format, recreate audio handle - if (g_sampling_rate != sound_data->rate || g_audio_type != sound_data->audio_type) { - SLOG(LOG_INFO, tts_tag(), "[Player] Change audio handle : org type(%d) org rate(%d)", g_audio_type, g_sampling_rate); - if (NULL != g_audio_h) { - __destroy_audio_out(); - } - - if (0 > __create_audio_out(sound_data->audio_type, sound_data->rate)) { - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio out"); - /* unset volume policy, volume will be 100% */ - __unset_policy_for_playing(); - - ttsd_data_destroy_sound_data(sound_data); - sound_data = NULL; - return; - } + if (TTSD_ERROR_NONE != g_audio_stream->setAudioFormat(sound_data->audio_type, sound_data->rate)) { + SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create audio out"); + /* unset volume policy, volume will be 100% */ + __unset_policy_for_playing(); - SLOG(LOG_INFO, tts_tag(), "[Player INFO] Success to destroy and recreate audio out"); - __set_policy_for_playing(); + ttsd_data_destroy_sound_data(sound_data); + sound_data = NULL; + return; } while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) { @@ -685,21 +525,21 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) __set_policy_for_playing(); } - if (AUDIO_STATE_READY == g_audio_state || AUDIO_STATE_WAIT_FOR_PLAYING == g_audio_state) { + if (AudioStream::AUDIO_STATE_READY == g_audio_stream->getState() || AudioStream::AUDIO_STATE_WAIT_FOR_PLAYING == g_audio_stream->getState()) { /* Request prepare */ - ret = audio_out_prepare(g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { + ret = g_audio_stream->prepareAudioOut(); + if (TTSD_ERROR_NONE != ret) { SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to prepare audio : %d", ret); + /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); - ttsd_data_destroy_sound_data(sound_data); sound_data = NULL; return; } + SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Prepare audio"); - g_audio_state = AUDIO_STATE_PLAY; - } // (AUDIO_STATE_READY == g_audio_state || AUDIO_STATE_WAIT_FOR_PLAYING == g_audio_state) + } char* temp_data = sound_data->data; SLOG(LOG_INFO, tts_tag(), "[Player INFO] Before audio_out_write. data(%p), data[%d](%p), uid(%u), utt_id(%d), len(%d)", @@ -707,8 +547,8 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) #ifdef BUF_SAVE_MODE __write_buffer_dump_file(&temp_data[idx], len); #endif - ret = audio_out_write(g_audio_h, &temp_data[idx], len); - if (0 > ret) { + ret = g_audio_stream->playAudioData(&temp_data[idx], len); + if (TTSD_ERROR_NONE != ret) { SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to audio write - %d", ret); } else { idx += len; @@ -717,11 +557,7 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) if (NULL == g_playing_info && APP_STATE_PAUSED != player->state) { SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL"); - g_audio_state = AUDIO_STATE_READY; - ret = audio_out_unprepare(g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret); - } + g_audio_stream->unprepareAudioOut(); /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); @@ -739,17 +575,11 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) player->is_paused_data = true; player->idx = idx; - g_audio_state = AUDIO_STATE_READY; SLOG(LOG_INFO, tts_tag(), "[Player] Stop player thread by pause"); /* Request prepare */ - ret = audio_out_unprepare(g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret); - } else { - SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio"); - } + g_audio_stream->unprepareAudioOut(); /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); return; @@ -758,17 +588,10 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) if (NULL == g_playing_info && APP_STATE_READY == player->state) { /* player_stop */ - g_audio_state = AUDIO_STATE_READY; SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread"); /* Request prepare */ - ret = audio_out_unprepare(g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret); - } else { - SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Unprepare audio"); - } - + g_audio_stream->unprepareAudioOut(); /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); ttsd_data_destroy_sound_data(sound_data); @@ -812,11 +635,7 @@ static void __play_thread_old(void *data, Ecore_Thread *thread) if (NULL == g_playing_info) { SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL"); - g_audio_state = AUDIO_STATE_READY; - ret = audio_out_unprepare(g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to unprepare audio : %d", ret); - } + g_audio_stream->unprepareAudioOut(); /* unset volume policy, volume will be 100% */ __unset_policy_for_playing(); ttsd_data_destroy_sound_data(sound_data); @@ -855,47 +674,13 @@ int ttsd_player_init() { pthread_mutex_lock(&g_player_control_mutex); g_playing_info = NULL; - g_audio_state = AUDIO_STATE_NONE; - g_audio_h = NULL; - - int ret; ecore_thread_max_set(1); - int cnt = 0; - while (1) { - if (0 == access(FOCUS_SERVER_READY, F_OK)) { - SLOG(LOG_ERROR, tts_tag(), "[Player SUCCESS] focus server is available"); - break; - } else { - if (0 == cnt++ % 10) - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] focus server is not available"); - usleep(50000); - } - } - - ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_INFORMATION, __player_focus_state_cb, NULL, &g_stream_info_h); - if (SOUND_MANAGER_ERROR_NONE != ret) { - SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to create stream info"); - pthread_mutex_unlock(&g_player_control_mutex); - return -1; - } else { - SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create stream info"); - } - g_background_volume = new BackgroundVolume(SND_MGR_DUCKING_DURATION); + g_audio_stream = new AudioStream(__focus_release_callback); ecore_thread_max_set(1); - - ret = __create_audio_out(TTSE_AUDIO_TYPE_RAW_S16, 16000); - if (0 != ret) { - sound_manager_destroy_stream_information(g_stream_info_h); - g_stream_info_h = NULL; - pthread_mutex_unlock(&g_player_control_mutex); - - return -1; - } - ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL); g_is_set_policy = false; @@ -920,8 +705,6 @@ int ttsd_player_release(void) return TTSD_ERROR_OPERATION_FAILED; } - int ret; - SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] @@@@@"); SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get()); SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] @@@@@"); @@ -943,25 +726,13 @@ int ttsd_player_release(void) SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Thread is released"); - ret = __destroy_audio_out(); - if (0 != ret) { - pthread_mutex_unlock(&g_player_control_mutex); - return -1; - } - - ret = sound_manager_destroy_stream_information(g_stream_info_h); - if (SOUND_MANAGER_ERROR_NONE != ret) { - SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy stream info"); - } else { - SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy stream info"); - } - /* clear g_player_list */ g_playing_info = NULL; g_player_init = false; pthread_cond_broadcast(&g_play_thread_cond); - g_stream_info_h = NULL; + delete g_audio_stream; + g_audio_stream = nullptr; delete g_background_volume; g_background_volume = nullptr; @@ -1358,7 +1129,6 @@ int ttsd_player_wait_to_play(unsigned int uid) SLOG(LOG_INFO, tts_tag(), "[Player INFO] wait to play (%u)", uid); - g_audio_state = AUDIO_STATE_WAIT_FOR_PLAYING; - + g_audio_stream->waitForPlay(); return TTSD_ERROR_NONE; } -- 2.7.4