/*
-* Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd All Rights Reserved
+* Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* limitations under the License.
*/
-
-#include <mm_types.h>
-#include <mm_player.h>
-#include <mm_player_internal.h>
-#include <mm_session.h>
-#include <mm_error.h>
+#include <audio_io.h>
#include <Ecore.h>
+#include <sound_manager.h>
+#include <sound_manager_internal.h>
#include "ttsd_main.h"
#include "ttsd_player.h"
#include "ttsd_data.h"
#include "ttsd_dbus.h"
+#include "tts_internal.h"
+#include "ttsd_server.h"
/*
* Internal data structure
*/
-#define TEMP_FILE_MAX 36
-
-typedef struct {
- char riff[4];
- int file_size;
- char wave[4];
- char fmt[4];
- int header_size;
- short sample_format;
- short n_channels;
- int sample_rate;
- int bytes_per_second;
- short block_align;
- short bits_per_sample;
- char data[4];
- int data_size;
-} WavHeader;
-
-typedef struct {
- int uid; /** client id */
- MMHandleType player_handle; /** mm player handle */
- int utt_id; /** utt_id of next file */
- ttsp_result_event_e event; /** event of callback */
-} player_s;
+typedef enum {
+ AUDIO_STATE_NONE = 0,
+ AUDIO_STATE_READY,
+ AUDIO_STATE_PLAY
+} audio_state_e;
typedef struct {
- int uid;
- int utt_id;
- ttsp_result_event_e event;
- char filename[TEMP_FILE_MAX];
-} user_data_s;
+ int uid; /** client id */
+ app_tts_state_e state; /** client state */
+ /* Current utterance information */
+ ttse_result_event_e event; /** event of last utterance */
-/*
-* static data
-*/
+ bool is_paused_data;
+ int idx;
+ sound_data_s* paused_data;
+} player_s;
-#define TEMP_FILE_PATH "/tmp"
-#define FILE_PATH_SIZE 256
-#define DEFAULT_FILE_SIZE 10
+#define SOUND_BUFFER_LENGTH 2048
+#define FOCUS_SERVER_READY "/tmp/.sound_server_ready"
/** player init info */
static bool g_player_init = false;
-/** tts engine list */
+/** Client list */
static GList *g_player_list;
/** current player information */
static player_s* g_playing_info;
-/** player callback function */
-static player_result_callback_func g_result_callback;
+/* player state */
+static audio_state_e g_audio_state;
+
+static ttse_audio_type_e g_audio_type;
+
+static int g_sampling_rate;
-/** numbering for temp file */
-static unsigned int g_index;
+static audio_out_h g_audio_h;
-/** For resume when the 'Paused' state of player after end of play */
-static bool g_pause_info;
-static int g_paused_uid;
+static sound_stream_info_h g_stream_info_h;
+static int g_focus_watch_id;
/*
-* Internal Interfaces
+* Internal Interfaces
*/
-player_s* __player_get_item(int uid);
+player_s* __player_get_item(int uid)
+{
+ 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;
+
+ /* compare uid */
+ if (uid == data->uid)
+ return data;
+
+ /* Get next item */
+ iter = g_list_next(iter);
+ }
+ }
+
+ return NULL;
+}
+
+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");
-int __save_file(int uid, int index, sound_data_s data, char** filename);
+ if (stream_info != g_stream_info_h) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Invalid stream info handle");
+ return;
+ }
+ 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);
-int __set_and_start(player_s* player);
+ if (AUDIO_STATE_PLAY == g_audio_state && focus_mask == SOUND_STREAM_FOCUS_FOR_PLAYBACK && SOUND_STREAM_FOCUS_STATE_RELEASED == focus_state) {
+ if (TTSD_MODE_DEFAULT == ttsd_get_mode()) {
+ g_audio_state = AUDIO_STATE_READY;
-int __init_wave_header(WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel);
+ if (NULL == g_playing_info) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player");
+ return;
+ }
-static int msg_callback(int message, void *data, void *user_param) ;
+ if (APP_STATE_PLAYING == g_playing_info->state) {
+ int uid = g_playing_info->uid;
+ if (0 != ttsd_player_pause(uid)) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to pause the player");
+ return;
+ }
-/*
-* Player Interfaces
+ ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
+ int pid = ttsd_data_get_pid(uid);
+ /* send message to client about changing state */
+ ttsdc_send_set_state_message(pid, uid, APP_STATE_PAUSED);
+ }
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] Ignore focus state cb - mode(%d)", ttsd_get_mode());
+ }
+ }
+
+/* if (AUDIO_STATE_READY == g_audio_state && focus_mask == SOUND_STREAM_FOCUS_FOR_PLAYBACK && SOUND_STREAM_FOCUS_STATE_ACQUIRED == focus_state) {
+ if (TTSD_MODE_DEFAULT == ttsd_get_mode()) {
+ g_audio_state = AUDIO_STATE_PLAY;
+
+ if (NULL == g_playing_info) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player");
+ return;
+ }
+
+ if (APP_STATE_PAUSED == g_playing_info->state) {
+ int uid = g_playing_info->uid;
+
+ g_audio_state = AUDIO_STATE_PLAY;
+ if (0 != ttsd_player_resume(uid)) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to resume the player");
+ g_audio_state = AUDIO_STATE_READY;
+ return;
+ }
+
+ ttsd_data_set_client_state(uid, APP_STATE_PLAYING);
+ int pid = ttsd_data_get_pid(uid);
+ ttsdc_send_set_state_message(pid, uid, APP_STATE_PLAYING);
+ }
+
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] Ignore focus state cb - mode(%d)", ttsd_get_mode());
+ }
+ }
*/
+ SLOG(LOG_DEBUG, tts_tag(), "@@@");
+
+ return;
+}
-int ttsd_player_init(player_result_callback_func result_cb)
+void __player_focus_state_watch_cb(int id, sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state, sound_stream_focus_change_reason_e reason,
+ const char *extra_info, void *user_data)
{
- if (NULL == result_cb) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] invalid parameter");
- return TTSD_ERROR_INVALID_PARAMETER;
+ SLOG(LOG_DEBUG, tts_tag(), "@@@ Focus state watch cb");
+
+ ttsd_mode_e mode = ttsd_get_mode();
+
+ if (TTSD_MODE_SCREEN_READER != mode && TTSD_MODE_NOTIFICATION != mode) {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] This is not screen-reader mode and notification mode.");
+ return;
}
- g_result_callback = result_cb;
+ if (AUDIO_STATE_PLAY == g_audio_state && SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION == reason &&
+ NULL != extra_info && 0 == strncmp(extra_info, "TTSD_MODE_INTERRUPT", strlen(extra_info))) {
+ /* If the focus is changed by "Interrupt" mode and current players of "SR" and "Noti" modes are on going, please stop the current players. */
+ g_audio_state = AUDIO_STATE_READY;
- g_playing_info = NULL;
-
- g_index = 1;
- g_player_init = true;
+ if (NULL == g_playing_info) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player");
+ return;
+ }
+
+ if (APP_STATE_PLAYING == g_playing_info->state) {
+ int uid = g_playing_info->uid;
+
+ if (0 != ttsd_server_stop(uid)) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to stop TTS server");
+ return;
+ }
+ if (0 != ttsd_player_stop(uid)) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to stop the player");
+ return;
+ }
- if (TTSD_MODE_DEFAULT == ttsd_get_mode()) {
- if (MM_ERROR_NONE != mm_session_init(MM_SESSION_TYPE_EXCLUSIVE)) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_session_init(MM_SESSION_TYPE_EXCLUSIVE)");
+ ttsd_data_set_client_state(uid, APP_STATE_READY);
+ int pid = ttsd_data_get_pid(uid);
+ /* send message to client about changing state */
+ ttsdc_send_set_state_message(pid, uid, APP_STATE_READY);
} else {
- SLOG(LOG_ERROR, get_tag(), "[Player SUCCESS] mm_session_init(MM_SESSION_TYPE_EXCLUSIVE)");
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] Not playing state");
}
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] This is not Interrupt mode or not playing state.");
}
- return 0;
+ return;
}
-int ttsd_player_release(void)
+static int __create_audio_out(ttse_audio_type_e type, int rate)
{
- if (false == g_player_init) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized");
- return TTSD_ERROR_OPERATION_FAILED;
+ 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;
}
- /* clear g_player_list */
- g_playing_info = NULL;
- g_player_init = false;
+ 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;
}
-int ttsd_player_create_instance(int uid)
+static int __destroy_audio_out()
{
- if (false == g_player_init) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
- return -1;
- }
-
- /* Check uid is duplicated */
- if (NULL != __player_get_item(uid)) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is already registered", uid);
+ if (NULL == g_audio_h) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current handle is not valid");
return -1;
}
- int ret = MM_ERROR_NONE;
- MMHandleType player_handle;
-
- ret = mm_player_create(&player_handle);
- if (ret != MM_ERROR_NONE || 0 == player_handle) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_create() : %x", ret);
- return -2;
+ 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");
}
- player_s* new_client = (player_s*)g_malloc0( sizeof(player_s) * 1);
-
- new_client->uid = uid;
- new_client->player_handle = player_handle;
- new_client->utt_id = -1;
- new_client->event = TTSP_RESULT_EVENT_FINISH;
-
- SLOG(LOG_DEBUG, get_tag(), "[Player] Create player : uid(%d), handle(%d)", uid, player_handle );
+ g_audio_type = 0;
+ g_sampling_rate = 0;
- g_player_list = g_list_append(g_player_list, new_client);
+ g_audio_state = AUDIO_STATE_NONE;
+ g_audio_h = NULL;
return 0;
}
-int ttsd_player_destroy_instance(int uid)
+static void __end_play_thread(void *data, Ecore_Thread *thread)
{
- if (false == g_player_init) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
- return -1;
+ SLOG(LOG_ERROR, tts_tag(), "@@@ End thread");
+}
+
+static void __set_policy_for_playing(int volume)
+{
+ /* Set stream info */
+ int ret;
+ ttsd_mode_e mode = ttsd_get_mode();
+ if (TTSD_MODE_DEFAULT == mode) {
+ ret = sound_manager_acquire_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 acquire focus");
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Success to acquire focus (default mode)");
+ }
+ } else if (TTSD_MODE_INTERRUPT == mode) {
+ ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, "TTSD_MODE_INTERRUPT");
+ 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 (interrupt mode)");
+ }
}
- player_s* current;
- current = __player_get_item(uid);
- if (NULL == current) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
- return -1;
+ 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");
}
- if (NULL != g_playing_info) {
- if (uid == g_playing_info->uid) {
- g_playing_info = NULL;
+ SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] set policy for playing");
+
+ return;
+}
+
+static void __unset_policy_for_playing()
+{
+ int ret;
+ ttsd_mode_e mode = ttsd_get_mode();
+ /* Unset stream info */
+ if (TTSD_MODE_DEFAULT == mode || TTSD_MODE_INTERRUPT == mode) {
+ sound_stream_focus_state_e state_for_playing = SOUND_STREAM_FOCUS_STATE_ACQUIRED;
+ 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) {
+ if (TTSD_MODE_DEFAULT == mode || TTSD_MODE_INTERRUPT == mode) {
+ ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
+ SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] release focus (mode: %d)", mode);
+ }
+
+ if (SOUND_MANAGER_ERROR_NONE != ret) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to release focus");
+ }
}
}
- MMPlayerStateType player_state;
- mm_player_get_state(current->player_handle, &player_state);
+ SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] unset policy for playing");
- SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
+ return;
+}
- int ret = -1;
- /* destroy player */
- switch (player_state) {
- case MM_PLAYER_STATE_PLAYING:
- case MM_PLAYER_STATE_PAUSED:
- case MM_PLAYER_STATE_READY:
- ret = mm_player_unrealize(current->player_handle);
- if (MM_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
- }
- /* NO break for destroy */
-
- case MM_PLAYER_STATE_NULL:
- ret = mm_player_destroy(current->player_handle);
- if (MM_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_destroy() : %x", ret);
- }
- break;
+int ttsd_player_check_current_playback_focus(bool *is_current_interrupt)
+{
+ int ret;
+ ttsd_mode_e mode = ttsd_get_mode();
- default:
- break;
- }
-
- GList *iter = NULL;
- player_s *data = NULL;
+ if (TTSD_MODE_INTERRUPT != mode) {
+ /* check the current playback focus */
+ sound_stream_focus_change_reason_e reason;
+ int sound_behavior = 0;
+ char *extra_info = NULL;
- if (0 < g_list_length(g_player_list)) {
- /* Get a first item */
- iter = g_list_first(g_player_list);
+ ret = sound_manager_get_current_playback_focus(&reason, &sound_behavior, &extra_info);
- while (NULL != iter) {
- /* Get handle data from list */
- data = (player_s*)iter->data;
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] current playback focus: extra_info(%s), reason(%d), sound_behavior(%d)", extra_info, reason, sound_behavior, extra_info);
- if (NULL != data) {
- /* compare uid */
- if (uid == data->uid) {
- g_player_list = g_list_remove_link(g_player_list, iter);
- g_free(data);
- break;
- }
+ if (SOUND_MANAGER_ERROR_NONE == ret && NULL != extra_info && 0 < strlen(extra_info)) {
+ if (SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION == reason && 0 == strncmp(extra_info, "TTSD_MODE_INTERRUPT", strlen(extra_info))) {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] The current focus in Interrupt. Cannot play the requested sound data");
+ *is_current_interrupt = true;
+
+ free(extra_info);
+ extra_info = NULL;
+
+ return TTSD_ERROR_NONE;
}
-
- /* Get next item */
- iter = g_list_next(iter);
+ }
+
+ if (NULL != extra_info) {
+ free(extra_info);
+ extra_info = NULL;
}
}
- SLOG(LOG_DEBUG, get_tag(), "[PLAYER Success] Destroy instance");
+ *is_current_interrupt = false;
- return 0;
+ return TTSD_ERROR_NONE;
}
-int ttsd_player_play(int uid)
+static void __play_thread(void *data, Ecore_Thread *thread)
{
- SLOG(LOG_DEBUG, get_tag(), "[Player] start play : uid(%d)", uid );
+ SLOG(LOG_DEBUG, tts_tag(), "@@@ Start thread");
- if (false == g_player_init) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
- return -1;
+ if (NULL == g_playing_info) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] No current player");
+ return;
}
- if (NULL != g_playing_info) {
- if (uid == g_playing_info->uid) {
- SLOG(LOG_WARN, get_tag(), "[Player WARNING] uid(%d) has already played", g_playing_info->uid);
- return 0;
+ player_s* player = g_playing_info;
+ sound_data_s* sound_data = NULL;
+
+ int ret = -1;
+ int len = SOUND_BUFFER_LENGTH;
+ int idx = 0;
+
+ /* set volume policy as 40% */
+ __set_policy_for_playing(40);
+ while (1) {
+ if (true == player->is_paused_data) {
+ /* Resume player */
+ sound_data = player->paused_data;
+ player->paused_data = NULL;
+
+ idx = player->idx;
+
+ player->is_paused_data = false;
+ player->idx = 0;
+
+ 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;
+
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+ return;
+ }
+ 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 {
+ sound_data = NULL;
+ ret = ttsd_data_get_sound_data(player->uid, &sound_data);
+ if (0 != ret || NULL == sound_data) {
+ /* empty queue */
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] No sound data. Waiting mode");
+
+ /* wait for new audio data come */
+ while (1) {
+ usleep(10000);
+ if (NULL == g_playing_info) {
+ /* current playing uid is replaced */
+ SLOG(LOG_INFO, tts_tag(), "[Player] Finish thread");
+ if (AUDIO_STATE_PLAY == g_audio_state) {
+ /* 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;
+ }
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+ return;
+ } else if (0 < ttsd_data_get_sound_data_size(player->uid)) {
+ /* new audio data come */
+ SLOG(LOG_INFO, tts_tag(), "[Player] Resume thread");
+ break;
+ }
+
+ /* If engine is not on processing */
+ if (TTSD_SYNTHESIS_CONTROL_DOING != ttsd_get_synth_control()) {
+ if (AUDIO_STATE_PLAY == g_audio_state) {
+ /* 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;
+
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+ }
+ }
+ }
+
+ SLOG(LOG_INFO, tts_tag(), "[Player] Finish to wait for new audio data come");
+
+ if (AUDIO_STATE_READY == g_audio_state) {
+ /* set volume policy as 40%, when resume play thread*/
+ __set_policy_for_playing(40);
+ }
+
+ /* resume play thread */
+ player->state = APP_STATE_PLAYING;
+ continue;
+ }
+
+ /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
+ * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
+ * When previous wdata's event is 'finish' and current wdata's event is 'finish',
+ * the player should send utt started event.
+ */
+ if (TTSE_RESULT_EVENT_START == sound_data->event ||
+ (TTSE_RESULT_EVENT_FINISH == player->event && TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
+ int pid = ttsd_data_get_pid(player->uid);
+
+ if (pid <= 0) {
+ SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+
+ return;
+ }
+
+ if (0 != ttsdc_send_utt_start_message(pid, player->uid, sound_data->utt_id)) {
+ SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%d), uttid(%d)",
+ pid, player->uid, sound_data->utt_id);
+ }
+ SLOG(LOG_INFO, tts_tag(), "[Player] Start utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
+ }
+
+ /* Save last event to check utterance start */
+ player->event = sound_data->event;
+ idx = 0;
+
+ if (NULL == sound_data->data || 0 >= sound_data->data_size) {
+ if (TTSE_RESULT_EVENT_FINISH == sound_data->event) {
+ SLOG(LOG_DEBUG, tts_tag(), "No sound data");
+ /* send utterence finish signal */
+ int pid = ttsd_data_get_pid(player->uid);
+
+ if (pid <= 0) {
+ SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+ return;
+ }
+ if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
+ SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)",
+ pid, player->uid, sound_data->utt_id);
+ }
+ }
+ SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
+ ttsd_data_clear_sound_data(player->uid, &sound_data);
+ continue;
+ }
+ }
+
+ if (g_sampling_rate != sound_data->rate || g_audio_type != sound_data->audio_type) {
+ SLOG(LOG_DEBUG, 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_clear_sound_data(player->uid, &sound_data);
+
+ return;
+ }
+
+ __set_policy_for_playing(40);
+ }
+
+ while (APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) {
+ if ((unsigned int)idx >= sound_data->data_size)
+ break;
+
+ if ((unsigned int)idx + SOUND_BUFFER_LENGTH > sound_data->data_size) {
+ len = sound_data->data_size - idx;
+ } else {
+ len = SOUND_BUFFER_LENGTH;
+ }
+
+ if (AUDIO_STATE_READY == g_audio_state) {
+ /* Request prepare */
+ ret = audio_out_prepare(g_audio_h);
+ if (AUDIO_IO_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to prepare audio : %d", ret);
+ g_playing_info = NULL;
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+
+ ttsd_data_clear_sound_data(player->uid, &sound_data);
+
+ return;
+ }
+ SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Prepare audio");
+ g_audio_state = AUDIO_STATE_PLAY;
+ }
+
+ char* temp_data = sound_data->data;
+ SLOG(LOG_INFO, tts_tag(), "[Player INFO] Before audio_out_write. temp_data(%p), idx(%d), data_idx(%d), uid(%d), utt_id(%d), len(%d)",
+ temp_data, idx, &temp_data[idx], player->uid, sound_data->utt_id, len);
+ ret = audio_out_write(g_audio_h, &temp_data[idx], len);
+ if (0 > ret) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to audio write - %d", ret);
+ } else {
+ idx += len;
+ SLOG(LOG_INFO, tts_tag(), "[Player INFO] After audio_out_write. temp_data(%p), idx(%d), data_idx(%d), uid(%d), utt_id(%d), len(%d)",
+ temp_data, idx, &temp_data[idx], player->uid, sound_data->utt_id, len);
+ }
+
+ 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);
+ }
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+
+ ttsd_data_clear_sound_data(player->uid, &sound_data);
+
+ return;
+ }
+
+ if (APP_STATE_PAUSED == player->state) {
+ /* Save data */
+ player->paused_data = sound_data;
+
+ 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");
+ }
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+ return;
+ }
+ }
+
+ 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");
+ }
+
+ ttsd_data_clear_sound_data(player->uid, &sound_data);
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+ return;
+ }
+
+ if ((APP_STATE_PLAYING == player->state || APP_STATE_PAUSED == player->state) &&
+ (TTSE_RESULT_EVENT_FINISH == sound_data->event)) {
+ /* send utterence finish signal */
+ int pid = ttsd_data_get_pid(player->uid);
+
+ if (pid <= 0) {
+ SLOG(LOG_WARN, tts_tag(), "[Send WARNIING] Current player is not valid");
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+
+ return;
+ }
+
+ if (0 != ttsdc_send_utt_finish_message(pid, player->uid, sound_data->utt_id)) {
+ SLOG(LOG_ERROR, tts_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)",
+ pid, player->uid, sound_data->utt_id);
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+
+ ttsd_data_clear_sound_data(player->uid, &sound_data);
+ return;
+ }
+
+ SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
+ }
+
+ ttsd_data_clear_sound_data(player->uid, &sound_data);
+
+ 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);
+ }
+ /* unset volume policy, volume will be 100% */
+ __unset_policy_for_playing();
+
+ return;
}
}
+}
- /* Check sound queue size */
- if (0 == ttsd_data_get_sound_data_size(uid)) {
- SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
+/*
+* Player Interfaces
+*/
+int ttsd_player_init()
+{
+ 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");
return -1;
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create stream info");
}
- /* Check uid */
- player_s* current;
- current = __player_get_item(uid);
- if (NULL == current) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
+ /* add sound focus state watch callback */
+ ret = sound_manager_add_focus_state_watch_cb(SOUND_STREAM_FOCUS_FOR_PLAYBACK, __player_focus_state_watch_cb, NULL, &g_focus_watch_id);
+ if (SOUND_MANAGER_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to add sound focus watch callback");
+ sound_manager_destroy_stream_information(g_stream_info_h);
return -1;
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Add sound focus watch callback");
}
- MMPlayerStateType player_state;
- mm_player_get_state(current->player_handle, &player_state);
+ ecore_thread_max_set(1);
- SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
+ ret = __create_audio_out(TTSE_AUDIO_TYPE_RAW_S16, 16000);
+ if (0 != ret) {
+ sound_manager_destroy_stream_information(g_stream_info_h);
+ sound_manager_remove_focus_state_watch_cb(g_focus_watch_id);
+ return -1;
+ }
- switch (player_state) {
- case MM_PLAYER_STATE_PLAYING:
- SLOG(LOG_WARN, get_tag(), "[Player] Current player is playing. Do not start new sound.");
- return 0;
+ g_player_init = true;
+
+ return 0;
+}
- case MM_PLAYER_STATE_PAUSED:
- SLOG(LOG_WARN, get_tag(), "[Player] Player is paused. Do not start new sound.");
- return -1;
+int ttsd_player_release(void)
+{
+ if (false == g_player_init) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
+ return TTSD_ERROR_OPERATION_FAILED;
+ }
- case MM_PLAYER_STATE_READY:
- SLOG(LOG_WARN, get_tag(), "[Player] Player is ready for next play. Do not start new sound.");
- return -1;
+ int ret;
- case MM_PLAYER_STATE_NULL:
+ 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] @@@@@");
+
+ /* The thread should be released */
+ int thread_count = ecore_thread_active_get();
+ int count = 0;
+ while (0 < thread_count) {
+ usleep(10000);
+
+ count++;
+ if (20 == count) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
break;
+ }
+
+ thread_count = ecore_thread_active_get();
+ }
- case MM_PLAYER_STATE_NONE:
- SLOG(LOG_WARN, get_tag(), "[Player] Player is created. Do not start new sound.");
- return -1;
+ SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Thread is released");
- default:
- return -1;
+ ret = __destroy_audio_out();
+ if (0 != ret)
+ 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");
}
- int ret;
- ret = __set_and_start(current);
- if (0 != ret) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to set or start mm_player");
+ /* remove focus state watch callback */
+ ret = sound_manager_remove_focus_state_watch_cb(g_focus_watch_id);
+ if (SOUND_MANAGER_ERROR_NONE != ret) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to remove the focus state watch cb");
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Remove the focus state watch cb");
}
- SLOG(LOG_DEBUG, get_tag(), "[Player] Started play and wait for played callback : uid(%d)", uid);
+ /* clear g_player_list */
+ g_playing_info = NULL;
+ g_player_init = false;
return 0;
}
-int ttsd_player_next_play(int uid)
+int ttsd_player_create_instance(int uid)
{
if (false == g_player_init) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
+ return -1;
+ }
+
+ /* Check uid is duplicated */
+ if (NULL != __player_get_item(uid)) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is already registered", uid);
+ return -1;
+ }
+
+ player_s* new_client = (player_s*)calloc(1, sizeof(player_s));
+ if (NULL == new_client) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to allocate memory");
+ return TTSE_ERROR_OUT_OF_MEMORY;
+ }
+
+ new_client->uid = uid;
+ new_client->event = TTSE_RESULT_EVENT_FINISH;
+ new_client->state = APP_STATE_READY;
+ new_client->is_paused_data = false;
+ new_client->idx = 0;
+ new_client->paused_data = NULL;
+
+ SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Player] Create player : uid(%d)", uid);
+
+ g_player_list = g_list_append(g_player_list, new_client);
+
+ return 0;
+}
+
+int ttsd_player_destroy_instance(int uid)
+{
+ if (false == g_player_init) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
return -1;
}
- /* Check uid */
player_s* current;
current = __player_get_item(uid);
if (NULL == current) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
- g_playing_info = NULL;
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
return -1;
}
if (NULL != g_playing_info) {
- if (uid != g_playing_info->uid) {
- SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player(%d) is NOT uid(%d)", g_playing_info->uid, uid);
- return 0;
+ if (uid == g_playing_info->uid) {
+ g_playing_info = NULL;
}
- } else {
- SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player do NOT exist");
- return -1;
}
- MMPlayerStateType player_state;
- mm_player_get_state(current->player_handle, &player_state);
-
- SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
-
- int ret = -1;
- /* stop player */
- switch (player_state) {
- case MM_PLAYER_STATE_PLAYING:
- case MM_PLAYER_STATE_PAUSED:
- case MM_PLAYER_STATE_READY:
- ret = mm_player_unrealize(current->player_handle);
- if (MM_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
- return -1;
- }
- break;
+ GList *iter = NULL;
+ player_s *data = NULL;
- case MM_PLAYER_STATE_NULL:
- break;
+ if (0 < g_list_length(g_player_list)) {
+ /* Get a first item */
+ iter = g_list_first(g_player_list);
- default:
- break;
- }
+ while (NULL != iter) {
+ /* Get handle data from list */
+ data = (player_s*)iter->data;
- /* Check sound queue size */
- if (0 == ttsd_data_get_sound_data_size(uid)) {
- SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
- g_playing_info = NULL;
- return -1;
- }
+ if (NULL != data) {
+ /* compare uid */
+ if (uid == data->uid) {
+ g_player_list = g_list_remove_link(g_player_list, iter);
+ free(data);
+ g_list_free(iter);
+ break;
+ }
+ }
- ret = __set_and_start(current);
- if (0 != ret) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to set or start mm_player");
+ /* Get next item */
+ iter = g_list_next(iter);
+ }
}
- SLOG(LOG_DEBUG, get_tag(), "[Player] Started play and wait for played callback : uid(%d)", uid);
+ SLOG(LOG_DEBUG, tts_tag(), "[PLAYER Success] Destroy instance");
return 0;
}
-
-int ttsd_player_stop(int uid)
+int ttsd_player_play(int uid)
{
- SLOG(LOG_DEBUG, get_tag(), "[Player] stop player : uid(%d)", uid );
-
if (false == g_player_init) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
+ return -1;
+ }
+
+ if (NULL != g_playing_info) {
+ if (uid == g_playing_info->uid) {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] uid(%d) has already played", g_playing_info->uid);
+ return 0;
+ } else {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] stop old player (%d)", g_playing_info->uid);
+ ttsd_player_stop(g_playing_info->uid);
+ }
+ }
+
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%d)", uid);
+
+ /* Check sound queue size */
+ if (0 == ttsd_data_get_sound_data_size(uid)) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
return -1;
}
player_s* current;
current = __player_get_item(uid);
if (NULL == current) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
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 */
- g_playing_info = NULL;
- }
- } else {
- SLOG(LOG_DEBUG, get_tag(), "[Player] No current playing");
- }
-
- current->utt_id = -1;
-
- MMPlayerStateType player_state;
- mm_player_get_state(current->player_handle, &player_state);
+ current->state = APP_STATE_PLAYING;
- SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
+ g_playing_info = current;
- int ret = -1;
- switch (player_state) {
- case MM_PLAYER_STATE_PLAYING:
- case MM_PLAYER_STATE_PAUSED:
- case MM_PLAYER_STATE_READY:
- ret = mm_player_unrealize(current->player_handle);
- if (MM_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
- return -1;
- }
- break;
+ SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
- case MM_PLAYER_STATE_NULL:
- break;
-
- default:
- break;
+ if (0 < ttsd_data_get_sound_data_size(current->uid)) {
+ SLOG(LOG_INFO, tts_tag(), "[Player] Run thread");
+ ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
}
- SLOG(LOG_DEBUG, get_tag(), "[Player SUCCESS] Stop player : uid(%d)", uid);
-
return 0;
}
-int ttsd_player_pause(int uid)
+int ttsd_player_stop(int uid)
{
- SLOG(LOG_DEBUG, get_tag(), "[Player] pause player : uid(%d)", uid );
-
if (false == g_player_init) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
return -1;
}
player_s* current;
current = __player_get_item(uid);
if (NULL == current) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] ttsd_player_pause() : uid(%d) is not valid", uid);
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
return -1;
}
if (uid == g_playing_info->uid) {
/* release current playing info */
g_playing_info = NULL;
- } else {
- /* error case */
}
+ } else {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] No current playing");
}
- MMPlayerStateType player_state;
- mm_player_get_state(current->player_handle, &player_state);
+ if (true == current->is_paused_data) {
+ if (NULL != current->paused_data) {
+ if (NULL != current->paused_data->data) {
+ free(current->paused_data->data);
+ current->paused_data->data = NULL;
+ }
+
+ free(current->paused_data);
+ current->paused_data = NULL;
+ }
+ }
- SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
+ current->event = TTSE_RESULT_EVENT_FINISH;
+ current->state = APP_STATE_READY;
+ current->is_paused_data = false;
+ current->idx = 0;
+
+ if (NULL == g_playing_info) {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
+ SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
+
+ /* The thread should be released */
+ int thread_count = ecore_thread_active_get();
+ int count = 0;
+ while (0 < thread_count) {
+ usleep(10000);
+
+ count++;
+ if (30 == count) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
+ break;
+ }
- int ret = 0;
- if (MM_PLAYER_STATE_PLAYING == player_state) {
- ret = mm_player_pause(current->player_handle);
- if (MM_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_pause : %x ", ret);
+ thread_count = ecore_thread_active_get();
}
- } else {
- SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current player is NOT 'playing'");
+
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
+ SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
}
-
+
+ SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Stop player : uid(%d)", uid);
return 0;
}
-int ttsd_player_resume(int uid)
+int ttsd_player_clear(int uid)
{
- SLOG(LOG_DEBUG, get_tag(), "[Player] Resume player : uid(%d)", uid );
-
if (false == g_player_init) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
return -1;
}
- /* Check id */
+ /* Check uid */
player_s* current;
current = __player_get_item(uid);
if (NULL == current) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
+ SECURE_SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
return -1;
}
- /* check current player */
- if (NULL != g_playing_info)
- g_playing_info = NULL;
-
-
- MMPlayerStateType player_state;
- mm_player_get_state(current->player_handle, &player_state);
-
- SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
-
- int ret = -1;
- if (MM_PLAYER_STATE_PAUSED == player_state) {
- /* When the 'Paused' state of player after end of play */
- if (g_pause_info == true && g_paused_uid == uid) {
- g_playing_info = current;
-
- g_pause_info = false;
- g_paused_uid = -1;
-
- /* Current state need load and play */
- ret = ttsd_player_next_play(uid);
- if (0 != ret) {
- SLOG(LOG_ERROR, get_tag(), "[player] Fail to next play in resume function");
- }
- } else {
- ret = mm_player_resume(current->player_handle);
- if (MM_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_resume() : %d", ret);
- return -1;
- } else {
- SLOG(LOG_DEBUG, get_tag(), "[Player] Resume player");
+ if (true == current->is_paused_data) {
+ if (NULL != current->paused_data) {
+ if (NULL != current->paused_data->data) {
+ free(current->paused_data->data);
+ current->paused_data->data = NULL;
}
- g_playing_info = current;
+ free(current->paused_data);
+ current->paused_data = NULL;
}
- } else {
- SLOG(LOG_WARN, get_tag(), "[Player WARNING] Current uid is NOT paused state.");
}
+ current->event = TTSE_RESULT_EVENT_FINISH;
+ current->state = APP_STATE_READY;
+ current->is_paused_data = false;
+ current->idx = 0;
+
+ SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Clear player : uid(%d)", uid);
+
return 0;
}
-int ttsd_player_get_state(int uid, ttsd_player_state_e* state)
+int ttsd_player_pause(int uid)
{
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] pause player : uid(%d)", uid);
+
if (false == g_player_init) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
return -1;
}
+ /* Check uid */
player_s* current;
current = __player_get_item(uid);
if (NULL == current) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] ttsd_player_pause() : uid(%d) is not valid", uid);
return -1;
}
- MMPlayerStateType player_state;
- mm_player_get_state(current->player_handle, &player_state);
+ /* 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 {
+ /* error case */
+ }
+ }
- SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
+ current->state = APP_STATE_PAUSED;
- int ret = -1;
- /* destroy player */
- switch (player_state) {
- case MM_PLAYER_STATE_PLAYING:
- *state = TTSD_PLAYER_STATE_PLAYING;
- break;
- case MM_PLAYER_STATE_PAUSED:
- *state = TTSD_PLAYER_STATE_PAUSED;
- break;
-
- case MM_PLAYER_STATE_NULL:
- *state = TTSD_PLAYER_STATE_NULL;
- break;
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
+ SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
- case MM_PLAYER_STATE_READY:
- default:
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] player state of uid(%d) is not valid", uid);
- return -1;
- break;
- }
+ /* The thread should be released */
+ int thread_count = ecore_thread_active_get();
+ int count = 0;
+ while (0 < thread_count) {
+ usleep(10000);
- return 0;
-}
+ count++;
+ if (30 == count) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue.");
+ break;
+ }
-int ttsd_player_get_current_client()
-{
- if (false == g_player_init) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
- return -1;
+ thread_count = ecore_thread_active_get();
}
- if (NULL != g_playing_info)
- return g_playing_info->uid;
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
+ SLOG(LOG_ERROR, tts_tag(), "[Player] Active thread count : %d", ecore_thread_active_get());
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] @@@@@");
- SLOG(LOG_WARN, get_tag(), "[Player WARNING] No current player");
+ SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Pause player : uid(%d)", uid);
return 0;
}
-int ttsd_player_get_current_utterance_id(int uid)
+int ttsd_player_resume(int uid)
{
- SLOG(LOG_DEBUG, get_tag(), "[Player] get current utt id : uid(%d)", uid );
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] Resume player : uid(%d)", uid);
if (false == g_player_init) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
return -1;
}
- /* Check uid */
+ /* Check id */
player_s* current;
current = __player_get_item(uid);
if (NULL == current) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid);
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
return -1;
}
- return current->utt_id;
+ /* check current player */
+ if (NULL != g_playing_info)
+ g_playing_info = NULL;
+
+ current->state = APP_STATE_PLAYING;
+ g_playing_info = current;
+
+ SLOG(LOG_INFO, tts_tag(), "[Player] Resume to run thread");
+ ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
+
+ return 0;
}
int ttsd_player_all_stop()
{
if (false == g_player_init) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
return -1;
}
g_playing_info = NULL;
- int ret = -1;
GList *iter = NULL;
player_s *data = NULL;
/* Get handle data from list */
data = (player_s*)iter->data;
- app_state_e state;
+ app_tts_state_e state;
if (0 > ttsd_data_get_client_state(data->uid, &state)) {
- SLOG(LOG_ERROR, get_tag(), "[player ERROR] ttsd_player_all_stop : uid is not valid ");
+ SLOG(LOG_ERROR, tts_tag(), "[player ERROR] uid(%d) is not valid", data->uid);
ttsd_player_destroy_instance(data->uid);
iter = g_list_next(iter);
continue;
}
if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
- /* unrealize player */
- ret = mm_player_unrealize(data->player_handle);
- if (MM_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_unrealize() : %x", ret);
- }
-
- data->utt_id = -1;
- data->event = TTSP_RESULT_EVENT_FINISH;
- }
-
- /* Get next item */
- iter = g_list_next(iter);
- }
- }
-
- SLOG(LOG_DEBUG, get_tag(), "[Player SUCCESS] player all stop!! ");
-
- return 0;
-}
-
-static Eina_Bool __player_next_play(void *data)
-{
- SLOG(LOG_DEBUG, get_tag(), "===== PLAYER NEXT PLAY");
-
- int* uid = (int*)data;
-
- if (NULL == uid) {
- SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid is NULL");
- SLOG(LOG_DEBUG, get_tag(), "=====");
- SLOG(LOG_DEBUG, get_tag(), " ");
- return EINA_FALSE;
- }
-
- SLOG(LOG_DEBUG, get_tag(), "[PLAYER] uid = %d", *uid);
-
- if (0 != ttsd_player_next_play(*uid)) {
- SLOG(LOG_WARN, get_tag(), "[PLAYER WARNING] Fail to play next");
- }
-
- free(uid);
-
- SLOG(LOG_DEBUG, get_tag(), "=====");
- SLOG(LOG_DEBUG, get_tag(), " ");
-
- return EINA_FALSE;
-}
-
-static int msg_callback(int message, void *data, void *user_param)
-{
- user_data_s* user_data = NULL;
-
- user_data = (user_data_s*)user_param;
-
- if (NULL == user_data) {
- SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] user_param is NULL");
- return -1;
- }
-
- int uid = user_data->uid;
- int utt_id = user_data->utt_id;
-
- MMMessageParamType *msg = (MMMessageParamType*)data;
-
- switch (message) {
- case MM_MESSAGE_ERROR:
- {
- SLOG(LOG_DEBUG, get_tag(), "===== PLAYER ERROR CALLBACK");
- SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] Info : uid(%d), utt id(%d), error file(%s)", uid, utt_id, user_data->filename);
-
- /* send error info */
- g_result_callback(PLAYER_ERROR, uid, utt_id);
-
- player_s* current;
- current = __player_get_item(uid);
- if (NULL == current) {
- SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid(%d) is NOT valid ", uid);
- } else {
- current->event = TTSP_RESULT_EVENT_FINISH;
- }
-
- if (NULL != user_data)
- g_free(user_data);
-
- /* check current player */
- if (NULL != g_playing_info) {
- if (uid == g_playing_info->uid) {
- g_playing_info = NULL;
- SLOG(LOG_WARN, get_tag(), "[PLAYER] Current Player is NOT uid(%d)", uid);
- }
- }
-
- SLOG(LOG_DEBUG, get_tag(), "=====");
- SLOG(LOG_DEBUG, get_tag(), " ");
- }
- break; /*MM_MESSAGE_ERROR*/
-
- case MM_MESSAGE_BEGIN_OF_STREAM:
-
- break;
-
- case MM_MESSAGE_END_OF_STREAM:
- {
- SLOG(LOG_DEBUG, get_tag(), "===== END OF STREAM CALLBACK");
-
- if (-1 == remove(user_data->filename)) {
- SLOG(LOG_WARN, get_tag(), "[PLAYER WARNING] Fail to remove temp file", user_data->filename);
- }
-
- /* Check uid */
- player_s* current;
- current = __player_get_item(uid);
- if (NULL == current) {
- SLOG(LOG_ERROR, get_tag(), "[PLAYER ERROR] uid(%d) is NOT valid", uid);
- if (NULL != g_playing_info) {
- if (uid == g_playing_info->uid) {
- g_playing_info = NULL;
- SLOG(LOG_WARN, get_tag(), "[PLAYER] Current Player is NOT uid(%d)", uid);
+ data->event = TTSE_RESULT_EVENT_FINISH;
+ data->state = APP_STATE_READY;
+
+ if (true == data->is_paused_data) {
+ if (NULL != data->paused_data) {
+ if (NULL != data->paused_data->data) {
+ free(data->paused_data->data);
+ data->paused_data->data = NULL;
+ }
+
+ free(data->paused_data);
+ data->paused_data = NULL;
}
}
- SLOG(LOG_DEBUG, get_tag(), "=====");
- SLOG(LOG_DEBUG, get_tag(), " ");
- return -1;
- }
-
- g_free(user_data);
-
- int pid = ttsd_data_get_pid(uid);
-
- /* send utterence finish signal */
- if (TTSP_RESULT_EVENT_FINISH == current->event) {
- if (0 == ttsdc_send_utt_finish_message(pid, uid, utt_id))
- SLOG(LOG_DEBUG, get_tag(), "[Send SUCCESS] Send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
- else
- SLOG(LOG_ERROR, get_tag(), "[Send ERROR] Fail to send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
- }
- /* for sync problem */
- MMPlayerStateType player_state;
- mm_player_get_state(current->player_handle, &player_state);
-
- if (MM_PLAYER_STATE_PAUSED == player_state) {
- g_pause_info = true; /* The current state of player is 'Paused' */
- g_paused_uid = uid; /* The current uid when the current state player is 'Paused' */
- } else {
- /* play state */
- int* uid_data = (int*) g_malloc0(sizeof(int));
- *uid_data = uid;
-
- SLOG(LOG_DEBUG, get_tag(), "[PLAYER] uid = %d", *uid_data);
-
- ecore_timer_add(0, __player_next_play, (void*)uid_data);
+ data->is_paused_data = false;
+ data->idx = 0;
}
- SLOG(LOG_DEBUG, get_tag(), "=====");
- SLOG(LOG_DEBUG, get_tag(), " ");
- }
- break; /*MM_MESSAGE_END_OF_STREAM*/
-
- case MM_MESSAGE_STATE_CHANGED:
- break;
-
- case MM_MESSAGE_STATE_INTERRUPTED:
- if (MM_PLAYER_STATE_PAUSED == msg->state.current) {
-
- SLOG(LOG_DEBUG, get_tag(), "===== INTERRUPTED CALLBACK");
-
- ttsd_data_set_client_state(uid, APP_STATE_PAUSED);
-
- int pid = ttsd_data_get_pid(uid);
- /* send message to client about changing state */
- ttsdc_send_set_state_message (pid, uid, APP_STATE_PAUSED);
-
- SLOG(LOG_DEBUG, get_tag(), "=====");
- SLOG(LOG_DEBUG, get_tag(), " ");
- }
- break;
-
- default:
- break;
- }
-
- return TRUE;
-}
-
-player_s* __player_get_item(int uid)
-{
- 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;
-
- /* compare uid */
- if (uid == data->uid)
- return data;
-
/* Get next item */
iter = g_list_next(iter);
}
}
- return NULL;
-}
-
-int __save_file(int uid, int index, sound_data_s data, char** filename)
-{
- char postfix[5];
- memset(postfix, '\0', 5);
-
- switch (data.audio_type) {
- case TTSP_AUDIO_TYPE_RAW:
- case TTSP_AUDIO_TYPE_WAV:
- strcpy(postfix, "wav");
- break;
- case TTSP_AUDIO_TYPE_MP3:
- strcpy(postfix, "mp3");
- break;
- case TTSP_AUDIO_TYPE_AMR:
- strcpy(postfix, "amr");
- break;
- default:
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Audio type(%d) is NOT valid", data.audio_type);
- return -1;
- }
-
- /* make filename to save */
- char* temp;
- temp = (char*)g_malloc0(sizeof(char) * FILE_PATH_SIZE);
- if (NULL == temp) {
- SLOG(LOG_ERROR, get_tag(), "[Player Error] make buf is failed");
- return -1;
- }
-
- int ret = snprintf(temp, FILE_PATH_SIZE, "%s/ttstemp%d_%d.%s", TEMP_FILE_PATH, uid, index, postfix);
-
- if (0 >= ret) {
- if (NULL != temp)
- g_free(temp);
- return -1;
- }
-
- FILE* fp;
- fp = fopen(temp, "wb");
-
- if (fp == NULL) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] temp file open error");
- if (NULL != temp)
- g_free(temp);
- return -1;
- }
-
- if (data.audio_type == TTSP_AUDIO_TYPE_RAW) {
- WavHeader header;
- if (0 != __init_wave_header(&header, data.data_size, data.rate, data.channels)) {
- fclose(fp);
- if (NULL != temp)
- g_free(temp);
- return -1;
- }
-
- if (0 >= fwrite(&header, sizeof(WavHeader), 1, fp)) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to write wav header to file");
- fclose(fp);
- if (NULL != temp)
- g_free(temp);
- return -1;
- }
- }
-
- int size = fwrite(data.data, data.data_size, 1, fp);
- if (size <= 0) {
- size = fwrite("0000000000", DEFAULT_FILE_SIZE, 1, fp);
- if (size <= 0) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail to write date");
- fclose(fp);
- if (NULL != temp)
- g_free(temp);
- return -1;
- }
- }
-
- fclose(fp);
- *filename = temp;
-
- SLOG(LOG_DEBUG, get_tag(), " ");
- SLOG(LOG_DEBUG, get_tag(), "Filepath : %s ", *filename);
- SLOG(LOG_DEBUG, get_tag(), "Header : Data size(%d), Sample rate(%d), Channel(%d) ", data.data_size, data.rate, data.channels);
-
- return 0;
-}
-
-int __init_wave_header (WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel)
-{
- if (hdr == NULL || sampling_rate <= 0 || channel <= 0) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] __init_wave_header : input parameter invalid");
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] hdr : %p", hdr);
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] nsample : %d", nsamples);
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] sampling_rate : %", sampling_rate);
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] channel : %", channel);
- return TTSD_ERROR_INVALID_PARAMETER;
- }
-
- size_t bytesize = DEFAULT_FILE_SIZE;
-
- if (0 < nsamples) {
- bytesize = nsamples;
- }
-
- /* NOT include \0(NULL) */
- strncpy(hdr->riff, "RIFF", 4);
- hdr->file_size = (int)(bytesize + 36);
- strncpy(hdr->wave, "WAVE", 4);
- strncpy(hdr->fmt, "fmt ", 4); /* fmt + space */
- hdr->header_size = 16;
- hdr->sample_format = 1; /* WAVE_FORMAT_PCM */
- hdr->n_channels = channel;
- hdr->sample_rate = (int)(sampling_rate);
- hdr->bytes_per_second = (int)sampling_rate * sizeof(short);
- hdr->block_align = sizeof(short);
- hdr->bits_per_sample = sizeof(short)*8;
- strncpy(hdr->data, "data", 4);
- hdr->data_size = (int)bytesize;
+ SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] player all stop!!");
return 0;
}
-int __set_and_start(player_s* player)
+int ttsd_player_play_pcm(int uid)
{
- /* get sound data */
- sound_data_s wdata;
- if (0 != ttsd_data_get_sound_data(player->uid, &wdata)) {
- SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", player->uid);
+ if (false == g_player_init) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
return -1;
}
- g_index++;
- if (10000 <= g_index) {
- g_index = 1;
- }
-
- int ret;
-
- /* make sound file for mmplayer */
- char* sound_file = NULL;
- ret = __save_file(player->uid, g_index, wdata, &sound_file);
- if (0 != ret || NULL == sound_file) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to make sound file");
- return -1;
+ if (NULL != g_playing_info) {
+ if (uid == g_playing_info->uid) {
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] uid(%d) has already played", g_playing_info->uid);
+ return 0;
+ } else {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] stop old player (%d)", g_playing_info->uid);
+ ttsd_player_stop(g_playing_info->uid);
+ }
}
-
- user_data_s* user_data = (user_data_s*)g_malloc0(sizeof(user_data_s));
- user_data->uid = player->uid;
- user_data->utt_id = wdata.utt_id;
- user_data->event = wdata.event;
- memset(user_data->filename, 0, TEMP_FILE_MAX);
- strncpy( user_data->filename, sound_file, strlen(sound_file) );
- SLOG(LOG_DEBUG, get_tag(), "Info : uid(%d), utt(%d), filename(%s) , event(%d)",
- user_data->uid, user_data->utt_id, user_data->filename, user_data->event);
- SLOG(LOG_DEBUG, get_tag(), " ");
+ SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%d)", uid);
-
- /* set callback func */
- ret = mm_player_set_message_callback(player->player_handle, msg_callback, (void*)user_data);
- if (MM_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_player_set_message_callback() : %x ", ret);
- return -1;
+ /* Check sound queue size */
+ if (0 == ttsd_data_get_sound_data_size(uid)) {
+ SLOG(LOG_WARN, tts_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid);
}
- /* set playing info to mm player */
- char* err_attr_name = NULL;
-
- if (0 != access(sound_file, R_OK)) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail to read sound file (%s)", sound_file);
- return -1;
- }
-
- ret = mm_player_set_attribute(player->player_handle, &err_attr_name,
- "profile_uri", sound_file , strlen(sound_file) + 1,
- "sound_volume_type", MM_SOUND_VOLUME_TYPE_MEDIA,
- "sound_route", MM_AUDIOROUTE_PLAYBACK_NORMAL,
- NULL );
-
- if (MM_ERROR_NONE != ret) {
- if (NULL != err_attr_name) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail mm_player_set_attribute() : msg(%s), result(%x) ", err_attr_name, ret);
- }
+ /* Check uid */
+ player_s* current;
+ current = __player_get_item(uid);
+ if (NULL == current) {
+ SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] uid(%d) is not valid", uid);
return -1;
}
- if (TTSD_MODE_DEFAULT != ttsd_get_mode()) {
- ret = mm_player_ignore_session(player->player_handle);
- if (MM_ERROR_NONE != ret) {
- SLOG(LOG_WARN, get_tag(), "[Player WARNING] fail mm_player_ignore_session() : %x", ret);
- }
- }
-
- /* realize and start mm player */
- ret = mm_player_realize(player->player_handle);
- if (MM_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_realize() : %x", ret);
- return -2;
- }
+ current->state = APP_STATE_PLAYING;
- ret = mm_player_start(player->player_handle);
- if (MM_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail mm_player_start() : %x", ret);
+ g_playing_info = current;
- mm_player_unrealize(player->player_handle);
- return -3;
- }
+ SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
- /* If wdata's event is 'start', current wdata is first data of engine for synthesis.
- * If wdata's event is 'finish', player should check previous event to know whether this wdata is first or not.
- * When previous wdata's event is 'finish' and current wdata's event is 'finish',
- * the player should send utt started event.
- */
- if (TTSP_RESULT_EVENT_START == wdata.event ||
- (TTSP_RESULT_EVENT_FINISH == player->event && TTSP_RESULT_EVENT_FINISH == wdata.event)) {
- int pid;
- pid = ttsd_data_get_pid(player->uid);
-
- /* send utterance start message */
- if (0 != ttsdc_send_utt_start_message(pid, player->uid, wdata.utt_id)) {
- SLOG(LOG_ERROR, get_tag(), "[Send ERROR] Fail to send Utterance Start Signal : pid(%d), uid(%d), uttid(%d)", pid, player->uid, wdata.utt_id);
- }
- } else {
- SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Don't need to send Utterance Start Signal");
+ if (0 <= ttsd_data_get_sound_data_size(current->uid)) {
+ SLOG(LOG_INFO, tts_tag(), "[Player] Run thread");
+ ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
}
- g_playing_info = player;
-
- if (NULL != sound_file)
- g_free(sound_file);
- if (NULL != wdata.data)
- g_free(wdata.data);
-
return 0;
}
-