change codes to function such as ttsd_player_clear
[platform/core/uifw/tts.git] / server / ttsd_player.c
index be9e904..c96ed44 100644 (file)
@@ -1,5 +1,5 @@
 /*
-*  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 enum {
+       AUDIO_STATE_NONE = 0,
+       AUDIO_STATE_READY,
+       AUDIO_STATE_PLAY
+} audio_state_e;
 
 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;
+       int                     uid;    /** client id */
+       app_tts_state_e         state;  /** client state */
 
-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 */
-       bool            pause_after_complete;   /** For resume when the 'Paused' state of player after end callback */
-} player_s;
+       /* Current utterance information */
+       ttse_result_event_e     event;  /** event of last utterance */
 
-typedef struct {
-       int  uid;
-       int  utt_id;
-       ttsp_result_event_e event;
-       char filename[TEMP_FILE_MAX];
-} user_data_s;
+       bool                    is_paused_data;
+       int                     idx;
+       sound_data_s*           paused_data;
+} player_s;
 
+#define SOUND_BUFFER_LENGTH    2048
+#define FOCUS_SERVER_READY "/tmp/.sound_server_ready"
 
+/* Sound buf save for test */
 /*
-* static data
+#define BUF_SAVE_MODE
 */
+#ifdef BUF_SAVE_MODE
+static char g_temp_file_name[128] = {'\0',};
+
+static FILE* g_pFile;
 
-#define TEMP_FILE_PATH  "/tmp"
-#define FILE_PATH_SIZE  256
-#define DEFAULT_FILE_SIZE 10
+static int g_count = 1;
+#endif
 
 /** 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;
 
-/** numbering for temp file */
-static unsigned int g_index;              
+static ttse_audio_type_e g_audio_type;
 
-/*
-* Internal Interfaces 
-*/
-player_s* __player_get_item(int uid);
+static int g_sampling_rate;
+
+static audio_out_h g_audio_h;
 
-int __save_file(int uid, int index, sound_data_s data, char** filename);
+static sound_stream_info_h g_stream_info_h;
 
-int __set_and_start(player_s* player);
+static sound_stream_ducking_h g_media_stream_ducking;
+static sound_stream_ducking_h g_system_stream_ducking;
+static sound_stream_ducking_h g_notification_stream_ducking;
+static sound_stream_ducking_h g_alarm_stream_ducking;
 
-int __init_wave_header(WavHeader* hdr, size_t nsamples, size_t sampling_rate, int channel);
+// static bool ducking_flag;
 
-static int msg_callback(int message, void *data, void *user_param) ;
+#define SND_MGR_DUCKING_DURATION 500
 
+static int g_focus_watch_id;
+
+static double g_bg_volume_ratio;
 
 /*
-* Player Interfaces 
+* Internal Interfaces
 */
 
-int ttsd_player_init(player_result_callback_func result_cb)
+player_s* __player_get_item(int uid)
 {
-       if (NULL == result_cb) {
-               SLOG(LOG_ERROR, get_tag(), "[Player ERROR] invalid parameter");
-               return TTSD_ERROR_INVALID_PARAMETER;
+       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);
+               }
        }
 
-       g_result_callback = result_cb;
+       return NULL;
+}
 
-       g_playing_info = NULL;
-       
-       g_index = 1;
-       g_player_init = true;
+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");
+
+       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);
+
+       if (NULL == g_playing_info) {
+               SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player");
+               return;
+       }
+
+       if (APP_STATE_PLAYING == g_playing_info->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 uid = g_playing_info->uid;
+
+                       if (0 != ttsd_player_pause(uid)) {
+                               SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to pause 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_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_ERROR, get_tag(), "[Player SUCCESS] mm_session_init(MM_SESSION_TYPE_EXCLUSIVE)");      
+                       SLOG(LOG_DEBUG, tts_tag(), "[Player] Ignore focus state cb - mode(%d)", ttsd_get_mode());
                }
        }
 
-       return 0;
+/*     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_release(void)
+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 (false == g_player_init) {
-               SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized");
-               return TTSD_ERROR_OPERATION_FAILED;
+       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;
        }
 
-       /* clear g_player_list */
-       g_playing_info = NULL;
-       g_player_init = false;
+       if (NULL == g_playing_info) {
+               SLOG(LOG_WARN, tts_tag(), "[Player WARNING] No current player");
+               return;
+       }
 
-       return 0;
+       if (APP_STATE_PLAYING == g_playing_info->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;
+
+               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;
+               }
+
+               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_DEBUG, tts_tag(), "[Player] Extra info is not Interrupt mode(%s) or not playing state(%d).", extra_info, g_playing_info->state);
+       }
+
+       return;
 }
 
-int ttsd_player_create_instance(int uid)
+void __sound_stream_ducking_state_changed_cb(sound_stream_ducking_h stream_ducking, bool is_ducked, void *user_data)
 {
-       if (false == g_player_init) {
-               SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
-               return -1;
+       SLOG(LOG_DEBUG, tts_tag(), "@@@ ducking state changed cb");
+       SLOG(LOG_DEBUG, tts_tag(), "[Player] is ducked : %d", is_ducked);
+       // ducking_flag = true;
+       return;
+}
+
+static char* __get_ducking_stream(sound_stream_type_e stream_type)
+{
+       if (SOUND_STREAM_TYPE_MEDIA == stream_type)
+               return "Media stream";
+       else if (SOUND_STREAM_TYPE_SYSTEM == stream_type)
+               return "System stream";
+       else if (SOUND_STREAM_TYPE_NOTIFICATION == stream_type)
+               return "Notification stream";
+       else if (SOUND_STREAM_TYPE_ALARM == stream_type)
+               return "Alarm stream";
+       return "Non matched stream";
+}
+
+static int __activate_ducking_sound_stream(sound_stream_type_e stream_type, sound_stream_ducking_h stream_ducking_h)
+{
+       bool is_ducked = false;
+       int ret = sound_manager_is_ducked(stream_ducking_h, &is_ducked);
+       if (is_ducked) {
+               SLOG(LOG_DEBUG, tts_tag(), "[Player] The %s is already ducked", __get_ducking_stream(stream_type));
+       } else {
+               ret = sound_manager_activate_ducking(stream_ducking_h, SND_MGR_DUCKING_DURATION, g_bg_volume_ratio);
+               if (SOUND_MANAGER_ERROR_NONE != ret) {
+                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to activate ducking for %s", __get_ducking_stream(stream_type));
+               } else {
+                       SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Activate ducking for %s", __get_ducking_stream(stream_type));
+               }
        }
-       
-       /* Check uid is duplicated */
-       if (NULL != __player_get_item(uid)) {
-               SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is already registered", uid); 
-               return -1;
+       return ret;
+}
+
+static void __change_background_volume()
+{
+       SLOG(LOG_INFO, tts_tag(), "[Player] volume ratio(%lf)", g_bg_volume_ratio);
+       if (1.0 > g_bg_volume_ratio) {
+               __activate_ducking_sound_stream(SOUND_STREAM_TYPE_MEDIA, g_media_stream_ducking);
+               __activate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_ducking);
+               __activate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_ducking);
+               __activate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_ducking);
        }
+}
 
-       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;
+static int __deactivate_ducking_sound_stream(sound_stream_type_e stream_type, sound_stream_ducking_h stream_ducking_h)
+{
+       bool is_ducked = false;
+       int ret = sound_manager_is_ducked(stream_ducking_h, &is_ducked);
+       if (!is_ducked) {
+               SLOG(LOG_DEBUG, tts_tag(), "[Player] The %s is already recovered from ducking", __get_ducking_stream(stream_type));
+       } else {
+               ret = sound_manager_deactivate_ducking(stream_ducking_h);
+               if (SOUND_MANAGER_ERROR_NONE != ret) {
+                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to deactivate ducking for %s", __get_ducking_stream(stream_type));
+               } else {
+                       SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Deactivate ducking for %s", __get_ducking_stream(stream_type));
+               }
        }
+       return ret;
+}
 
-       player_s* new_client = (player_s*)g_malloc0( sizeof(player_s) * 1);
+static void __recover_background_volume()
+{
+       __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_MEDIA, g_media_stream_ducking);
+       __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_ducking);
+       __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_ducking);
+       __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_ducking);
+}
 
-       new_client->uid = uid;
-       new_client->player_handle = player_handle;
-       new_client->utt_id = -1;
-       new_client->event = TTSP_RESULT_EVENT_FINISH;
-       new_client->pause_after_complete = false;
-       
-       SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] Create player : uid(%d), handle(%d)", uid, player_handle );
+static int __create_audio_out(ttse_audio_type_e type, int rate)
+{
+       int ret = -1;
+       audio_sample_type_e sample_type;
 
-       g_player_list = g_list_append(g_player_list, new_client);
+       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;
 }
 
-int ttsd_player_destroy_instance(int uid)
+static int __destroy_audio_out()
 {
-       if (false == g_player_init) {
-               SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
+       if (NULL == g_audio_h) {
+               SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Current handle is not valid");
                return -1;
        }
 
-       player_s* current;
-       current = __player_get_item(uid);
-       if (NULL == current) {
-               SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] uid(%d) is not valid", uid); 
+       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");
        }
 
-       if (NULL != g_playing_info) {
-               if (uid == g_playing_info->uid) {
-                       g_playing_info = NULL;
+       g_audio_type = 0;
+       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");
+
+#ifdef BUF_SAVE_MODE
+       fclose(g_pFile);
+#endif
+}
+
+static void __set_policy_for_playing(int volume)
+{
+
+       __change_background_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)");
+               }
+       }
+
+       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");
        }
 
-       MMPlayerStateType player_state;
-       mm_player_get_state(current->player_handle, &player_state);
+       SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] set 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;
+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");
+                       }
+               }
+       }
+
+       __recover_background_volume();
+
+       SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] unset policy for playing");
+
+       return;
+}
+
+int ttsd_player_check_current_playback_focus(bool *is_current_interrupt)
+{
+       int ret;
+       ttsd_mode_e mode = ttsd_get_mode();
 
-               default:
+       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;
+
+               ret = sound_manager_get_current_playback_focus(&reason, &sound_behavior, &extra_info);
+
+               SLOG(LOG_DEBUG, tts_tag(), "[Player] current playback focus: extra_info(%s), reason(%d), sound_behavior(%d)", extra_info, reason, sound_behavior);
+
+               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;
+                       }
+               }
+
+               if (NULL != extra_info) {
+                       free(extra_info);
+                       extra_info = NULL;
+               }
+       }
+
+       *is_current_interrupt = false;
+
+       return TTSD_ERROR_NONE;
+}
+
+static void __play_thread(void *data, Ecore_Thread *thread)
+{
+       SLOG(LOG_DEBUG, tts_tag(), "@@@ Start thread");
+
+#ifdef BUF_SAVE_MODE
+       g_count++;
+
+       while (1) {
+               snprintf(g_temp_file_name, sizeof(g_temp_file_name), "/tmp/tts_temp_%d_%d", getpid(), g_count);
+               int ret = access(g_temp_file_name, 0);
+
+               if (0 == ret) {
+                       SLOG(LOG_ERROR, tts_tag(), "[Recorder ERROR] File is already exist");
+                       if (0 == remove(g_temp_file_name)) {
+                               SLOG(LOG_DEBUG, tts_tag(), "[Recorder] Remove file");
+                               break;
+                       } else {
+                               g_count++;
+                       }
+               } else {
                        break;
+               }
        }
-               
-       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);
+       SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Recorder] Temp file name=[%s]", g_temp_file_name);
 
-               while (NULL != iter) {
-                       /* Get handle data from list */
-                       data = (player_s*)iter->data;
+       /* open test file */
+       g_pFile = fopen(g_temp_file_name, "wb+x");
+       if (!g_pFile) {
+               SLOG(LOG_ERROR, tts_tag(), "[Recorder ERROR] File not found!");
+               return;
+       }
+#endif
 
-                       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 (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;
+
+       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();
+                                       ttsd_data_clear_sound_data(&sound_data);
+                                       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();
+                                               ttsd_data_clear_sound_data(&sound_data);
+                                               return;
+                                       }
+
+                                       __unset_policy_for_playing();
+
+                                       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);
+                                       } else {
+                                               SLOG(LOG_INFO, tts_tag(), "[Player] Finish utterance : uid(%d), uttid(%d)", player->uid, sound_data->utt_id);
+                                       }
+                               }
+                               SLOG(LOG_INFO, tts_tag(), "[Player] Event(%d) utterance : uid(%d), uttid(%d)", sound_data->event, player->uid, sound_data->utt_id);
+                               ttsd_data_clear_sound_data(&sound_data);
+                               continue;
                        }
-                               
-                       /* Get next item */
-                       iter = g_list_next(iter);
                }
-       }
 
-       SLOG(LOG_DEBUG, get_tag(), "[PLAYER Success] Destroy instance");
+               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();
 
-       return 0;
+                               ttsd_data_clear_sound_data(&sound_data);
+
+                               return;
+                       }
+
+                       SLOG(LOG_INFO, tts_tag(), "[Player INFO] Success to destroy and recreate audio out");
+                       __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(&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. data(%p), data[%d](%p), uid(%d), utt_id(%d), len(%d)",
+                                       temp_data, idx, &temp_data[idx], player->uid, sound_data->utt_id, len);
+#ifdef BUF_SAVE_MODE
+                       /* write pcm buffer */
+                       fwrite(&temp_data[idx], 1, len, g_pFile);
+#endif
+                       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");
+                       }
+
+                       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(&sound_data);
+
+                               return;
+                       }
+
+                       if (APP_STATE_PAUSED == player->state) {
+                               /* Save data */
+                               SLOG(LOG_DEBUG, tts_tag(), "[Player] player(%p)", player);
+                               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");
+                       }
+
+                       /* unset volume policy, volume will be 100% */
+                       __unset_policy_for_playing();
+                       ttsd_data_clear_sound_data(&sound_data);
+                       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();
+                               ttsd_data_clear_sound_data(&sound_data);
+                               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(&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(&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();
+                       ttsd_data_clear_sound_data(&sound_data);
+                       return;
+               }
+       }
 }
 
-int ttsd_player_play(int uid)
+int __create_ducking_handle(void)
 {
-       SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] start play : uid(%d)", uid );
+       int ret = -1;
+       if (NULL == g_media_stream_ducking) {
+               ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_MEDIA, __sound_stream_ducking_state_changed_cb, NULL, &g_media_stream_ducking);
+               if (SOUND_MANAGER_ERROR_NONE != ret)
+                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create stream ducking for type media, ret(%d)", ret);
+       } else {
+               SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for media stream is already created");
+       }
+       if (NULL == g_system_stream_ducking) {
+               ret = sound_manager_create_stream_ducking(SOUND_TYPE_SYSTEM, __sound_stream_ducking_state_changed_cb, NULL, &g_system_stream_ducking);
+               if (SOUND_MANAGER_ERROR_NONE != ret)
+                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create stream ducking for system type, ret(%d)", ret);
+       } else {
+               SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for system stream is already created");
+       }
 
-       if (false == g_player_init) {
-               SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
-               return -1;
+       if (NULL == g_notification_stream_ducking) {
+               ret = sound_manager_create_stream_ducking(SOUND_TYPE_NOTIFICATION, __sound_stream_ducking_state_changed_cb, NULL, &g_notification_stream_ducking);
+               if (SOUND_MANAGER_ERROR_NONE != ret)
+                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create stream ducking for notification type, ret(%d)", ret);
+       } else {
+               SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for notification stream is already created");
        }
 
-       if (NULL != g_playing_info) {
-               if (uid == g_playing_info->uid) {
-                       SECURE_SLOG(LOG_WARN, get_tag(), "[Player WARNING] uid(%d) has already played", g_playing_info->uid); 
-                       return 0;
+       if (NULL == g_alarm_stream_ducking) {
+               ret = sound_manager_create_stream_ducking(SOUND_TYPE_ALARM, __sound_stream_ducking_state_changed_cb, NULL, &g_alarm_stream_ducking);
+               if (SOUND_MANAGER_ERROR_NONE != ret)
+                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create stream ducking for alarm type, ret(%d)", ret);
+       } else {
+               SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for alarm stream is already created");
+       }
+
+       return ret;
+}
+
+/*
+* 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);
                }
        }
 
-       /* Check sound queue size */
-       if (0 == ttsd_data_get_sound_data_size(uid)) {
-               SECURE_SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", uid); 
+       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) {
-               SECURE_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);
+       ret = __create_ducking_handle();
+       if (SOUND_MANAGER_ERROR_NONE != ret) {
+               SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to create ducking handle, ret(%d)", ret);
+       } else {
+               SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Create ducking handle");
+       }
 
-       SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
+       ecore_thread_max_set(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;
+       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;
+       }
 
-               case MM_PLAYER_STATE_PAUSED:
-                       SLOG(LOG_WARN, get_tag(), "[Player] Player is paused. Do not start new sound.");
-                       return -1;
+       g_player_init = true;
 
-               case MM_PLAYER_STATE_READY:
-                       SLOG(LOG_WARN, get_tag(), "[Player] Player is ready for next play. Do not start new sound.");
-                       return -1;
+       return 0;
+}
 
-               case MM_PLAYER_STATE_NULL:
-                       break;
+int __destroy_ducking_handle(void)
+{
+       int ret = -1;
+       if (g_media_stream_ducking) {
+               ret = sound_manager_destroy_stream_ducking(g_media_stream_ducking);
+               if (SOUND_MANAGER_ERROR_NONE != ret)
+                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy media stream ducking, ret(%d)", ret);
+               g_media_stream_ducking = NULL;
+       } else {
+               SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for media stream is already created");
+       }
+
+       if (g_system_stream_ducking) {
+               ret = sound_manager_destroy_stream_ducking(g_system_stream_ducking);
+               if (SOUND_MANAGER_ERROR_NONE != ret)
+                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy system stream ducking, ret(%d)", ret);
+               g_system_stream_ducking = NULL;
+       } else {
+               SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for system stream is already created");
+       }
+
+       if (g_notification_stream_ducking) {
+               ret = sound_manager_destroy_stream_ducking(g_notification_stream_ducking);
+               if (SOUND_MANAGER_ERROR_NONE != ret)
+                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy notification stream ducking, ret(%d)", ret);
+               g_notification_stream_ducking = NULL;   
+       } else {
+               SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for notification stream is already created");
+       }
 
-               case MM_PLAYER_STATE_NONE:
-                       SLOG(LOG_WARN, get_tag(), "[Player] Player is created. Do not start new sound.");
-                       return -1;
+       if (g_alarm_stream_ducking) {
+               ret = sound_manager_destroy_stream_ducking(g_alarm_stream_ducking);
+               if (SOUND_MANAGER_ERROR_NONE != ret)
+                       SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy alarm stream ducking, ret(%d)", ret);
+               g_alarm_stream_ducking = NULL;
+       } else {
+               SLOG(LOG_INFO, tts_tag(), "[Player INFO] Ducking handle for alarm stream is already created");
+       }
+       return ret;
+}
 
-               default:
-                       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;
        }
 
        int ret;
-       ret = __set_and_start(current);
-       if (0 != ret) {
-               SLOG(LOG_ERROR, get_tag(), "[Player ERROR] fail to set or start mm_player");
-               return 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] @@@@@");
+
+       /* 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();
        }
 
-       SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] Started play and wait for played callback : uid(%d)", uid);
+       SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Thread is released");
+
+       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");
+       }
+
+       /* 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");
+       }
+
+       ret = __destroy_ducking_handle();
+       if (SOUND_MANAGER_ERROR_NONE != ret)
+               SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to destroy stream ducking, ret(%d)", ret);
+       else
+               SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy stream ducking");
+
+       /* 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) {
-               SECURE_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) {
-                       SECURE_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)) {
-               SECURE_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");
-               return ret;
+                       /* Get next item */
+                       iter = g_list_next(iter);
+               }
        }
 
-       SECURE_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_play(int uid)
+{
+       if (false == g_player_init) {
+               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);
+               }
+       }
 
-int ttsd_player_stop(int uid)
-{
-       SECURE_SLOG(LOG_DEBUG, get_tag(), "[Player] stop player : uid(%d)", uid );
+       SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%d)", uid);
 
-       if (false == g_player_init) {
-               SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
+       /* 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;
        }
 
@@ -412,67 +1152,30 @@ int ttsd_player_stop(int uid)
        player_s* current;
        current = __player_get_item(uid);
        if (NULL == current) {
-               SECURE_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;
-       current->pause_after_complete = false;
+       current->state = APP_STATE_PLAYING;
 
-       MMPlayerStateType player_state;
-       mm_player_get_state(current->player_handle, &player_state);
+       g_playing_info = current;
 
-       SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
-
-       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);
        }
 
-       SECURE_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)
 {
-       SECURE_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" );
-               return -1;
-       }
-
-       /* Check uid */
-       player_s* current;
-       current = __player_get_item(uid);
-       if (NULL == current) {
-               SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] ttsd_player_pause() : uid(%d) is not valid", uid); 
-               return -1;
+       int ret = ttsd_player_clear(uid);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Fail to stop player, ret(%d)", ret);
+               return ret;
        }
 
        /* check whether uid is current playing or not */
@@ -480,175 +1183,182 @@ int ttsd_player_pause(int uid)
                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);
-
-       SLOG(LOG_DEBUG, get_tag(), "[PLAYER] Current state(%d)", player_state);
+       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)
 {
-       SECURE_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) {
-               SECURE_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 (true == current->pause_after_complete) {
-                       g_playing_info = current;
-
-                       current->pause_after_complete = false;
-                       
-                       /* 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) {
-               SECURE_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 */
+                       SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] release current playing info (%d)", uid);
+                       g_playing_info = NULL;
+               } else {
+                       /* error case */
+               }
+       }
 
-       SLOG(LOG_DEBUG, get_tag(), "[PLAYER] State changed : state(%d)", player_state);
+       SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] current player (%p), g_playing_info(%p)", current, g_playing_info);
 
-       /* 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;
+       current->state = APP_STATE_PAUSED;
 
-               case MM_PLAYER_STATE_READY:
-               default:
-                       SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] player state of uid(%d) is not valid", uid); 
-                       return -1;
-                       break;
-       }
+       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] @@@@@");
 
-       return 0;
-}
+               /* The thread should be released */
+               int thread_count = ecore_thread_active_get();
+               int count = 0;
+               while (0 < thread_count) {
+                       usleep(10000);
 
-int ttsd_player_get_current_client()
-{
-       if (false == g_player_init) {
-               SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Not Initialized" );
-               return -1;
+                       count++;
+                       SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] current(%p), state(%d)", current, current->state);
+
+                       if (30 == count) {
+                               SLOG(LOG_WARN, tts_tag(), "[Player WARNING!!] Thread is blocked. Player release continue. current(%p) current state(%d)", current, current->state);
+                               break;
+                       }
+
+                       thread_count = ecore_thread_active_get();
+               }
+
+               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] @@@@@");
        }
 
-       if (NULL != g_playing_info) 
-               return g_playing_info->uid;
 
-       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)
 {
-       SECURE_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) {
-               SECURE_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;
 
@@ -660,475 +1370,104 @@ int ttsd_player_all_stop()
                        /* 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;
+                               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;
+                                       }
+                               }
+
+                               data->is_paused_data = false;
+                               data->idx = 0;
                        }
-                       
+
                        /* Get next item */
                        iter = g_list_next(iter);
                }
        }
 
-       SLOG(LOG_DEBUG, get_tag(), "[Player SUCCESS] player all stop!! ");
+       SLOG(LOG_DEBUG, tts_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;
-       }
-
-       SECURE_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) 
+int ttsd_player_play_pcm(int uid)
 {
-       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");
+       if (false == g_player_init) {
+               SLOG(LOG_ERROR, tts_tag(), "[Player ERROR] Not Initialized");
                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");
-                       SECURE_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) {
-                               SECURE_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;
-                                       SECURE_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)) {
-                               SECURE_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) {
-                               SECURE_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;
-                                               SECURE_SLOG(LOG_WARN, get_tag(), "[PLAYER] Current Player is NOT uid(%d)", uid);
-                                       }
-                               }
-                               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))
-                                       SECURE_SLOG(LOG_DEBUG, get_tag(), "[Send SUCCESS] Send Utterance Completed Signal : pid(%d), uid(%d), uttid(%d)", pid, uid, utt_id);
-                               else 
-                                       SECURE_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) {
-                               /* The current state of player is 'Paused' */
-                               current->pause_after_complete = true;
-                       } else {
-                               /* play state */
-                               int* uid_data = (int*) g_malloc0(sizeof(int));
-                               *uid_data = uid;
-
-                               SECURE_SLOG(LOG_DEBUG, get_tag(), "[PLAYER] uid = %d", *uid_data);
-
-                               ecore_timer_add(0, __player_next_play, (void*)uid_data);
-                       }
-
-                       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);
+       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);
                }
        }
 
-       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:
-               SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Audio type(%d) is NOT valid", data.audio_type); 
-               return -1;
-       }
+       SLOG(LOG_DEBUG, tts_tag(), "[Player] start play : uid(%d)", uid);
 
-       /* 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;
+       /* 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);
        }
 
-       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);
+       /* 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;
        }
 
-       FILE* fp;
-       fp = fopen(temp, "wb");
+       current->state = APP_STATE_PLAYING;
 
-       if (fp == NULL) {
-               SLOG(LOG_ERROR, get_tag(), "[Player ERROR] temp file open error");
-               if (NULL != temp)
-                       g_free(temp);
-               return -1;
-       }
+       g_playing_info = current;
 
-       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;
-               }
+       SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] Active thread count : %d", ecore_thread_active_get());
 
-               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;
-               }
+       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);
        }
 
-       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(), " ");
-       SECURE_SLOG(LOG_DEBUG, get_tag(), "Filepath : %s ", *filename);
-       SECURE_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)
+int ttsd_player_get_background_volume_ratio(double* ratio)
 {
-       if (hdr == NULL || sampling_rate <= 0 || channel <= 0) {
-               SLOG(LOG_ERROR, get_tag(), "[Player ERROR] __init_wave_header : input parameter invalid");
-               SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] hdr : %p", hdr);
-               SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] nsample : %d", nsamples);
-               SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] sampling_rate : %", sampling_rate);
-               SECURE_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;
+       if (NULL == ratio)
+               return -1;
+       else
+               *ratio = g_bg_volume_ratio;
 
-       return 0;
+       return TTSD_ERROR_NONE;
 }
 
-int __set_and_start(player_s* player)
+int ttsd_player_set_background_volume_ratio(double ratio)
 {
-       /* get sound data */
-       sound_data_s wdata;
-       if (0 != ttsd_data_get_sound_data(player->uid, &wdata)) {
-               SECURE_SLOG(LOG_WARN, get_tag(), "[Player WARNING] A sound queue of current player(%d) is empty", player->uid); 
-               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;
-       }
-       
-       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) );
-
-       SECURE_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(), " ");
-
-       
-       /* 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);
-               if (NULL != user_data)  g_free(user_data);
-               return -1;
-       }
-
-       /* set playing info to mm player */
-       char* err_attr_name = NULL;
-
-       if (0 != access(sound_file, R_OK)) {
-               SECURE_SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Fail to read sound file (%s)", sound_file);
-               if (NULL != user_data)  g_free(user_data);
-               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);
-               }
-               if (NULL != user_data)  g_free(user_data);
-               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);
+       SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] ttsd_player_set_background_volume_ratio : %lf", ratio);
 
-               if (NULL != user_data)  g_free(user_data);
-               return -2;
-       }
-
-       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);
-               mm_player_unrealize(player->player_handle);
-
-               int reason;
-               if (MM_ERROR_POLICY_BLOCKED == ret) {
-                       SLOG(LOG_ERROR, get_tag(), "[Player ERROR] Blocked to start player by policy : %x", ret);
-                       reason = TTSD_ERROR_AUDIO_POLICY_BLOCKED;
-               } else {
-                       reason = TTSD_ERROR_OPERATION_FAILED;
-               }
-
-               if (NULL != user_data) {
-                       ttsd_data_set_error_data(user_data->uid, user_data->utt_id, reason);
-                       g_free(user_data);
-               }
-               return -3;
-       }
-
-       /* 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)) {
-                       SECURE_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");
-       }
-
-       g_playing_info = player;
-
-       if (NULL != sound_file) 
-               g_free(sound_file);
-       if (NULL != wdata.data) 
-               g_free(wdata.data);
-
-       return 0;
+       g_bg_volume_ratio = ratio;
+       return TTSD_ERROR_NONE;
 }
-
-