#include "BackgroundVolume.h"
#include "AudioStream.h"
+#include "PlayerThread.h"
#include "tts_internal.h"
#include "ttsd_server.h"
static BackgroundVolume* g_background_volume = nullptr;
static AudioStream* g_audio_stream = nullptr;
+static PlayerThread* g_player_thread = nullptr;
/*
* Internal Interfaces
}
#endif
-static bool __is_player_valid(player_s* player)
-{
- if (NULL == player || NULL == g_playing_info) {
- SLOG(LOG_ERROR, tts_tag(), "[ERROR] player is NULL");
- return false;
- }
-
- if (g_playing_info != player || g_playing_info->uid != player->uid) {
- SLOG(LOG_ERROR, tts_tag(), "[ERROR] player is not current player");
- return false;
- }
-
- return true;
-}
-
player_s* __player_get_item(unsigned int uid)
{
GList *iter = NULL;
static void __focus_release_callback()
{
- if (NULL == g_playing_info) {
- SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player");
+ unsigned int uid = g_player_thread->getCurrentUid();
+ if (APP_STATE_PLAYING != ttsd_data_get_client_state(uid)) {
return;
}
- if (APP_STATE_PLAYING != ttsd_data_get_client_state(g_playing_info->uid)) {
- return;
- }
-
- unsigned int uid = g_playing_info->uid;
ttsd_mode_e mode = ttsd_data_get_mode(uid);
-
switch (mode) {
case TTSD_MODE_DEFAULT:
{
return TTSD_ERROR_NONE;
}
-static int __play_sound_data(player_s* player, sound_data_s* sound_data)
+static int __play_sound_data(unsigned int uid, sound_data_s* sound_data)
{
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");
unsigned int idx = sound_data->played_data_size;
while (idx < sound_data->data_size) {
- app_tts_state_e state = ttsd_data_get_client_state(player->uid);
+ app_tts_state_e state = ttsd_data_get_client_state(uid);
if (APP_STATE_PLAYING != state && APP_STATE_PAUSED != state) {
break;
}
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(%u)",
- temp_data, idx, &temp_data[idx], player->uid, sound_data->utt_id, len);
+ temp_data, idx, &temp_data[idx], uid, sound_data->utt_id, len);
#ifdef BUF_SAVE_MODE
__write_buffer_dump_file(&temp_data[idx], len);
return TTSD_ERROR_INVALID_STATE;
}
- if (false == __is_player_valid(player)) {
+ if (false == g_player_thread->isCurrentUid(uid)) {
return TTSD_ERROR_OPERATION_FAILED;
}
}
return TTSD_ERROR_NONE;
}
-static void __wait_sound_data(player_s* player)
+static void __wait_sound_data(unsigned int uid)
{
- while (0 >= ttsd_data_get_sound_data_size(player->uid)) { // 2nd while(1)
+ while (0 >= ttsd_data_get_sound_data_size(uid)) {
usleep(10000);
- if (false == __is_player_valid(player)) {
+ if (false == g_player_thread->isCurrentUid(uid)) {
return;
}
{
SLOG(LOG_DEBUG, tts_tag(), "@@@ Start thread");
- if (NULL == g_playing_info) {
- SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] No current player");
- return;
- }
-
- player_s* player = g_playing_info;
- sound_data_s* sound_data = NULL;
-
+ unsigned int uid = g_player_thread->getCurrentUid();
+ sound_data_s* sound_data = nullptr;
int ret = -1;
while (1) { // 1st while(1)
- /* check g_playing_info one more time */
- if (false == __is_player_valid(player)) {
- SLOG(LOG_INFO, tts_tag(), "[Player INFO] Player is not valid");
+ if (false == g_player_thread->isCurrentUid(uid)) {
+ SLOG(LOG_INFO, tts_tag(), "[Player INFO] uid is not played");
g_audio_stream->unprepareAudioOut();
__unset_policy_for_playing();
return;
}
- if (ttsd_data_is_paused_data_existing(player->uid)) {
+ if (ttsd_data_is_paused_data_existing(uid)) {
/* Resume player */
- sound_data = ttsd_data_get_first_sound_data(player->uid);
- ttsd_data_set_paused_data_existing(player->uid, false);
+ sound_data = ttsd_data_get_first_sound_data(uid);
+ ttsd_data_set_paused_data_existing(uid, false);
if (NULL == sound_data) {
g_audio_stream->unprepareAudioOut();
SLOG(LOG_INFO, tts_tag(), "[Player] Sound info : id(%d) data(%p) size(%d) audiotype(%d) rate(%d) event(%d)",
sound_data->utt_id, sound_data->data, sound_data->data_size, sound_data->audio_type, sound_data->rate, sound_data->event);
} else { // NO player->is_paused_data
- sound_data = ttsd_data_get_first_sound_data(player->uid);
+ sound_data = ttsd_data_get_first_sound_data(uid);
if (nullptr == sound_data) {
/* empty queue */
SLOG(LOG_ERROR, tts_tag(), "[Player] No sound data. Waiting mode");
- __wait_sound_data(player);
- if (false == __is_player_valid(player)) {
+ __wait_sound_data(uid);
+ if (false == g_player_thread->isCurrentUid(uid)) {
SLOG(LOG_INFO, tts_tag(), "[Player] Finish thread");
g_audio_stream->unprepareAudioOut();
__unset_policy_for_playing();
* When previous wdata's event is 'finish' and current wdata's event is 'finish',
* the player should send utt started event.
*/
- ttse_result_event_e last_event = ttsd_data_get_last_sound_result_event(player->uid);
+ ttse_result_event_e last_event = ttsd_data_get_last_sound_result_event(uid);
if (TTSE_RESULT_EVENT_START == sound_data->event || (TTSE_RESULT_EVENT_FINISH == last_event && TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
- int ret = __notify_utterance_started_event(player->uid, sound_data->utt_id);
+ int ret = __notify_utterance_started_event(uid, sound_data->utt_id);
if (TTSD_ERROR_INVALID_PARAMETER == ret) {
g_audio_stream->unprepareAudioOut();
__unset_policy_for_playing();
} // (TTSE_RESULT_EVENT_START == sound_data->event || (TTSE_RESULT_EVENT_FINISH == player->event && TTSE_RESULT_EVENT_FINISH == sound_data->event))
/* Save last event to check utterance start */
- ttsd_data_set_last_sound_result_event(player->uid, sound_data->event);
+ ttsd_data_set_last_sound_result_event(uid, sound_data->event);
if (NULL == sound_data->data || 0 >= sound_data->data_size) {
ttse_result_event_e event = sound_data->event;
int utt_id = sound_data->utt_id;
- if (TTSD_ERROR_NONE == ttsd_data_pop_sound_data(player->uid)) {
+ if (TTSD_ERROR_NONE == ttsd_data_pop_sound_data(uid)) {
ttsd_data_destroy_sound_data(sound_data);
}
sound_data = nullptr;
SLOG(LOG_DEBUG, tts_tag(), "No sound data");
__unset_policy_for_playing();
- ret = __notify_utterance_completed_event(player->uid, utt_id);
+ ret = __notify_utterance_completed_event(uid, utt_id);
if (TTSD_ERROR_INVALID_PARAMETER == ret) {
g_audio_stream->unprepareAudioOut();
return;
}
} // TTSE_RESULT_EVENT_FINISH == event
- SLOG(LOG_INFO, tts_tag(), "[Player] Event(%d) utterance : uid(%u), uttid(%d)", event, player->uid, utt_id);
+ SLOG(LOG_INFO, tts_tag(), "[Player] Event(%d) utterance : uid(%u), uttid(%d)", event, uid, utt_id);
continue;
} // (NULL == sound_data->data || 0 >= sound_data->data_size)
} // NO player->is_paused_data
- ret = __play_sound_data(player, sound_data);
+ ret = __play_sound_data(uid, sound_data);
if (TTSD_ERROR_INVALID_STATE == ret) {
- SLOG(LOG_DEBUG, tts_tag(), "[Player] Player(%p) is paused, uid(%u)", player, player->uid);
- ttsd_data_set_paused_data_existing(player->uid, true);
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] Uid(%u) is paused", uid);
+ ttsd_data_set_paused_data_existing(uid, true);
g_audio_stream->unprepareAudioOut();
__unset_policy_for_playing();
return;
} else if (TTSD_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, tts_tag(), "[Player] Fail to play audio data. player(%p), uid(%u)", player, player->uid);
-
- g_playing_info = NULL;
+ SLOG(LOG_ERROR, tts_tag(), "[Player] Fail to play audio data. uid(%u)", uid);
g_audio_stream->unprepareAudioOut();
__unset_policy_for_playing();
return;
ttse_result_event_e event = sound_data->event;
int utt_id = sound_data->utt_id;
- if (TTSD_ERROR_NONE == ttsd_data_pop_sound_data(player->uid)) {
+ if (TTSD_ERROR_NONE == ttsd_data_pop_sound_data(uid)) {
ttsd_data_destroy_sound_data(sound_data);
}
sound_data = nullptr;
if (TTSE_RESULT_EVENT_FINISH == event) {
- ret = __notify_utterance_completed_event(player->uid, utt_id);
+ ret = __notify_utterance_completed_event(uid, utt_id);
if (TTSD_ERROR_NONE != ret) {
g_audio_stream->unprepareAudioOut();
__unset_policy_for_playing();
}
} // (TTSE_RESULT_EVENT_FINISH == event)
- app_tts_state_e state = ttsd_data_get_client_state(player->uid);
+ app_tts_state_e state = ttsd_data_get_client_state(uid);
if (APP_STATE_READY == state) {
/* player_stop */
SLOG(LOG_DEBUG, tts_tag(), "[Player] Stop player thread");
__unset_policy_for_playing();
return;
} // (APP_STATE_READY == state)
-
- if (NULL == g_playing_info) {
- SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current player is NULL");
- g_audio_stream->unprepareAudioOut();
- /* unset volume policy, volume will be 100% */
- __unset_policy_for_playing();
- return;
- }
} // end of 1st while(1)
}
__play_thread_old(data, thread);
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);
}
}
pthread_mutex_lock(&g_player_control_mutex);
g_playing_info = NULL;
- ecore_thread_max_set(1);
-
g_background_volume = new BackgroundVolume(SND_MGR_DUCKING_DURATION);
g_audio_stream = new AudioStream(__focus_release_callback);
+ g_player_thread = new PlayerThread(nullptr);
- ecore_thread_max_set(1);
ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
g_is_set_policy = false;
/* clear g_player_list */
g_playing_info = NULL;
g_player_init = false;
+ g_player_thread->requestStop();
pthread_cond_broadcast(&g_play_thread_cond);
delete g_audio_stream;
delete g_background_volume;
g_background_volume = nullptr;
+ delete g_player_thread;
+ g_player_thread = nullptr;
+
pthread_mutex_unlock(&g_player_control_mutex);
return 0;
return TTSD_ERROR_OPERATION_FAILED;
}
- if (NULL != g_playing_info) {
- if (uid == g_playing_info->uid) {
- SLOG(LOG_DEBUG, tts_tag(), "[Player] uid(%u) has already played", g_playing_info->uid);
+ if (0 > ttsd_data_is_client(uid)) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
+ pthread_mutex_unlock(&g_player_control_mutex);
+ return -1;
+ }
+
+ unsigned int currentUid = g_player_thread->getCurrentUid();
+ if (0 < ttsd_data_is_client(currentUid)) {
+ if (uid == currentUid) {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] uid(%u) has already played", uid);
pthread_mutex_unlock(&g_player_control_mutex);
return 0;
} else {
- SLOG(LOG_WARN, tts_tag(), "[Player WARNING] stop old player (%u)", g_playing_info->uid);
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] stop old player (%u)", currentUid);
pthread_mutex_unlock(&g_player_control_mutex);
- ttsd_player_stop(g_playing_info->uid);
+ ttsd_player_stop(currentUid);
pthread_mutex_lock(&g_player_control_mutex);
}
}
- SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%u)", uid);
-
- /* Check uid */
- player_s* current;
- current = __player_get_item(uid);
- if (NULL == current) {
- SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
- pthread_mutex_unlock(&g_player_control_mutex);
- return -1;
- }
-
- g_playing_info = current;
-
- SLOG(LOG_INFO, tts_tag(), "[Player] Run thread");
+ SLOG(LOG_INFO, tts_tag(), "[Player] start play : uid(%u)", uid);
+ g_player_thread->requestPlay(uid);
pthread_cond_broadcast(&g_play_thread_cond);
pthread_mutex_unlock(&g_player_control_mutex);
return TTSD_ERROR_OPERATION_FAILED;
}
- /* check whether uid is current playing or not */
- if (NULL != g_playing_info) {
- if (uid == g_playing_info->uid) {
- /* release current playing info */
- g_playing_info = NULL;
- }
- } else {
- SLOG(LOG_DEBUG, tts_tag(), "[Player] No current playing");
- }
+ if (uid == g_player_thread->getCurrentUid()) {
+ g_player_thread->requestStop();
+ pthread_cond_broadcast(&g_play_thread_cond);
- if (NULL == g_playing_info) {
pthread_mutex_lock(&g_play_thread_mutex);
SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
pthread_mutex_unlock(&g_play_thread_mutex);
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] No current playing");
}
#ifdef BUF_SAVE_MODE
#endif
__set_playing_status(false);
- int ret = ttsd_player_clear(uid);
- if (0 != ret) {
- SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to stop player, ret(%d)", ret);
- pthread_mutex_unlock(&g_player_control_mutex);
- return ret;
- }
+ ttsd_data_set_last_sound_result_event(uid, TTSE_RESULT_EVENT_FINISH);
+ ttsd_data_set_paused_data_existing(uid, false);
SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Stop player : uid(%u)", uid);
return TTSD_ERROR_OPERATION_FAILED;
}
- /* Check uid */
- player_s* current;
- current = __player_get_item(uid);
- if (NULL == current) {
+ if (0 > ttsd_data_is_client(uid)) {
SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] ttsd_player_pause() : uid(%u) is not valid", uid);
pthread_mutex_unlock(&g_player_control_mutex);
return -1;
}
- /* check whether uid is current playing or not */
- if (NULL != g_playing_info) {
- if (uid == g_playing_info->uid) {
- /* release current playing info */
- SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] release current playing info (%u)", uid);
- g_playing_info = NULL;
- } else {
- /* error case */
- }
- }
+ if (uid == g_player_thread->getCurrentUid()) {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] release current playing info (%u)", uid);
+ g_player_thread->requestStop();
- SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] current player (%p), g_playing_info(%p)", current, g_playing_info);
-
- if (NULL == g_playing_info) {
pthread_mutex_lock(&g_play_thread_mutex);
SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
pthread_mutex_unlock(&g_play_thread_mutex);
return TTSD_ERROR_OPERATION_FAILED;
}
- /* Check id */
- player_s* current;
- current = __player_get_item(uid);
- if (NULL == current) {
+ if (0 > ttsd_data_is_client(uid)) {
SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
pthread_mutex_unlock(&g_player_control_mutex);
return -1;
}
- /* check current player */
- if (NULL != g_playing_info)
- g_playing_info = NULL;
-
- g_playing_info = current;
-
SLOG(LOG_INFO, tts_tag(), "[Player] Resume to run thread");
+ g_player_thread->requestPlay(uid);
pthread_cond_broadcast(&g_play_thread_cond);
pthread_mutex_unlock(&g_player_control_mutex);
return 0;
}
+bool __stop_all_client_callback(int pid, unsigned int uid, app_tts_state_e state, void* user_data)
+{
+ if (0 > ttsd_data_is_client(uid)) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%u) is not valid", uid);
+ return true;
+ }
+
+ if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
+ ttsd_data_set_last_sound_result_event(uid, TTSE_RESULT_EVENT_FINISH);
+ ttsd_data_set_paused_data_existing(uid, false);
+ }
+
+ return true;
+}
+
int ttsd_player_all_stop()
{
pthread_mutex_lock(&g_player_control_mutex);
return TTSD_ERROR_OPERATION_FAILED;
}
- g_playing_info = NULL;
-
- GList *iter = NULL;
- player_s *data = NULL;
-
- if (0 < g_list_length(g_player_list)) {
- /* Get a first item */
- iter = g_list_first(g_player_list);
-
- while (NULL != iter) {
- /* Get handle data from list */
- data = (player_s*)iter->data;
-
- app_tts_state_e state = ttsd_data_get_client_state(data->uid);
- if (APP_STATE_NONE == state) {
- SLOG(LOG_ERROR, tts_tag(), "[player ERROR] uid(%u) is not valid", data->uid);
- iter = g_list_next(iter);
-
- pthread_mutex_unlock(&g_player_control_mutex);
- ttsd_player_destroy_instance(data->uid);
- pthread_mutex_lock(&g_player_control_mutex);
- continue;
- }
-
- if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
- ttsd_data_set_last_sound_result_event(data->uid, TTSE_RESULT_EVENT_FINISH);
- ttsd_data_set_paused_data_existing(data->uid, false);
- }
-
- /* Get next item */
- iter = g_list_next(iter);
- }
- }
+ ttsd_data_foreach_clients(__stop_all_client_callback, nullptr);
+ g_player_thread->requestStop();
SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] player all stop!!");