#include <audio_io.h>
#include <Ecore.h>
#include <sound_manager.h>
-#include <sound_manager_internal.h>
#include <pthread.h>
-#include <time.h>
#include "ttsd_main.h"
#include "ttsd_player.h"
#include "ttsd_dbus.h"
#include "ttsd_ipc.h"
+#include "BackgroundVolume.h"
+
#include "tts_internal.h"
#include "ttsd_server.h"
static sound_stream_info_h g_stream_info_h;
-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;
-
static bool g_is_set_policy;
-// static bool ducking_flag;
-
/* CAUTION!
If you change this constant value. Please check the function '__set_timer_for_delay_recover()'.
If you choose too big value, it may cause integer overflow issue.
*/
#define SND_MGR_DUCKING_DURATION 500
-static struct timespec g_policy_set_time;
-static Ecore_Timer* g_delayed_unset_policy_timer = NULL;
-static Ecore_Timer* g_modify_background_volume = NULL;
-
-static double g_bg_volume_ratio;
-
static pthread_mutex_t g_play_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t g_player_control_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t g_play_thread_cond = PTHREAD_COND_INITIALIZER;
+
+static BackgroundVolume* g_background_volume = nullptr;
+
/*
* Internal Interfaces
*/
return;
}
-void __sound_stream_ducking_state_changed_cb(sound_stream_ducking_h stream_ducking, bool is_ducked, void *user_data)
-{
- SLOG(LOG_DEBUG, tts_tag(), "@@@ ducking state changed cb");
- SLOG(LOG_ERROR, tts_tag(), "[Player] ducking_h(%p) is ducked : %d", stream_ducking, is_ducked);
- // ducking_flag = true;
- return;
-}
-
-static const char* __get_ducking_stream(sound_stream_type_e stream_type)
-{
- const char* type = nullptr;
- if (SOUND_STREAM_TYPE_MEDIA == stream_type)
- type = "Media stream";
- else if (SOUND_STREAM_TYPE_SYSTEM == stream_type)
- type = "System stream";
- else if (SOUND_STREAM_TYPE_NOTIFICATION == stream_type)
- type = "Notification stream";
- else if (SOUND_STREAM_TYPE_ALARM == stream_type)
- type = "Alarm stream";
- else
- type = "Non matched stream";
-
- return type;
-}
-
-static int __activate_ducking_sound_stream(sound_stream_type_e stream_type, sound_stream_ducking_h stream_ducking_h, unsigned int duration)
-{
- 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, 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));
- }
- }
- return ret;
-}
-
-static void __change_background_volume(unsigned int duration)
-{
- SLOG(LOG_INFO, tts_tag(), "[BG] 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, duration);
-// __activate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_ducking, duration);
- __activate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_ducking, duration);
- __activate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_ducking, duration);
- }
-}
-
-static void __change_background_volume_async(void* data)
-{
- __change_background_volume(SND_MGR_DUCKING_DURATION);
-}
-
-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;
-}
-
-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);
-}
-
static int __create_audio_out(ttse_audio_type_e type, int rate)
{
int ret = -1;
SLOG(LOG_ERROR, tts_tag(), "@@@ End thread");
}
-static void __del_timer_for_delayed_recover(void* data)
-{
- if (NULL != g_delayed_unset_policy_timer) {
- int result = (intptr_t)ecore_timer_del(g_delayed_unset_policy_timer);
- g_delayed_unset_policy_timer = NULL;
- SLOG(LOG_ERROR, tts_tag(), "[BG] Remove timer (%d)", result);
- }
-}
-
static void __set_policy_for_playing(void)
{
- ecore_main_loop_thread_safe_call_async(__del_timer_for_delayed_recover, NULL);
-
/* Set stream info */
const char* extra_info = NULL;
if (TTSD_MODE_INTERRUPT == ttsd_get_mode()) {
SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to set stream info");
}
- ecore_main_loop_thread_safe_call_async(__change_background_volume_async, NULL);
-
+ g_background_volume->applyVolumeRatio();
g_is_set_policy = true;
SLOG(LOG_ERROR, tts_tag(), "[BG] g_is_set_policy(%d)", g_is_set_policy);
-
- clock_gettime(CLOCK_MONOTONIC, &g_policy_set_time);
-
SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] set policy for playing");
return;
}
-static Eina_Bool __delay_recover_background_volume(void* data)
-{
- __recover_background_volume();
- SLOG(LOG_INFO, tts_tag(), "[BG] Delayed unset policy success");
-
- g_delayed_unset_policy_timer = NULL;
- return EINA_FALSE;
-}
-
-static long long int __get_duration_from_last_volume_change()
-{
- struct timespec current_time;
- clock_gettime(CLOCK_MONOTONIC, ¤t_time);
-
- long long int diff = ((long long int)current_time.tv_sec - (long long int)g_policy_set_time.tv_sec) * 1000
- + ((long long int)current_time.tv_nsec - (long long int)g_policy_set_time.tv_nsec) / 1000000;
- SLOG(LOG_INFO, tts_tag(), "[BG] Time Diff(%lld)", diff);
-
- return diff;
-}
-
-static void __set_timer_for_delay_recover(void* data)
-{
- if (NULL != g_delayed_unset_policy_timer) {
- return;
- }
-
- long long int diff = __get_duration_from_last_volume_change();
- if (diff > SND_MGR_DUCKING_DURATION) {
- SLOG(LOG_INFO, tts_tag(), "[BG] Direct unset policy");
- __recover_background_volume();
- } else {
- double delay = (double)(SND_MGR_DUCKING_DURATION - diff) / 1000.0;
- g_delayed_unset_policy_timer = ecore_timer_add(delay, __delay_recover_background_volume, (void*)CHECK_TIMER_DELETE);
- SLOG(LOG_INFO, tts_tag(), "[BG] Delayed unset policy (%p), delay(%f)", g_delayed_unset_policy_timer, delay);
- }
-}
-
static void __unset_policy_for_playing()
{
/* Unset stream info */
}
}
- ecore_main_loop_thread_safe_call_async(__set_timer_for_delay_recover, NULL);
-
+ g_background_volume->recoverVolumeRatio();
g_is_set_policy = false;
SLOG(LOG_ERROR, tts_tag(), "[BG] g_is_set_policy(%d)", g_is_set_policy);
SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] unset policy for playing");
}
}
-int __create_ducking_handle(void)
-{
- 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_STREAM_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 (NULL == g_notification_stream_ducking) {
- ret = sound_manager_create_stream_ducking(SOUND_STREAM_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_alarm_stream_ducking) {
- ret = sound_manager_create_stream_ducking(SOUND_STREAM_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
*/
SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Create stream info");
}
- 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");
- }
+ g_background_volume = new BackgroundVolume(SND_MGR_DUCKING_DURATION);
ecore_thread_max_set(1);
ecore_thread_run(__play_thread, __end_play_thread, NULL, NULL);
+ g_is_set_policy = false;
g_player_init = true;
pthread_mutex_unlock(&g_player_control_mutex);
return 0;
}
-static void __destroy_all_ducking_handles()
-{
- SLOG(LOG_INFO, tts_tag(), "[Player] Destroy stream ducking");
- if (__get_duration_from_last_volume_change() <= SND_MGR_DUCKING_DURATION) {
- usleep(500000);
- }
-
- __recover_background_volume();
-
- int ret = -1;
- 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 ducking handle, ret(%d)", ret);
- }
- g_media_stream_ducking = NULL;
-
-/* 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 ducking handle, ret(%d)", ret);
- }
- g_system_stream_ducking = NULL;
-*/
- 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 ducking handle, ret(%d)", ret);
- }
- g_notification_stream_ducking = NULL;
-
- 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 ducking handle, ret(%d)", ret);
- }
- g_alarm_stream_ducking = NULL;
-}
-
int ttsd_player_release(void)
{
#ifdef BUF_SAVE_MODE
SLOG(LOG_DEBUG, tts_tag(), "[Player SUCCESS] Destroy stream info");
}
- __destroy_all_ducking_handles();
-
/* clear g_player_list */
g_playing_info = NULL;
g_player_init = false;
g_stream_info_h = NULL;
+ delete g_background_volume;
+ g_background_volume = nullptr;
+
pthread_mutex_unlock(&g_player_control_mutex);
return 0;
return TTSD_ERROR_OPERATION_FAILED;
}
- if (NULL == ratio)
- return -1;
- else
- *ratio = g_bg_volume_ratio;
-
- return TTSD_ERROR_NONE;
-}
-
-static Eina_Bool __modify_background_volume_async(void* data)
-{
- __recover_background_volume();
- __change_background_volume(0);
- SLOG(LOG_INFO, tts_tag(), "[BG] Modify background volume with delay");
-
- g_modify_background_volume = NULL;
- return EINA_FALSE;
-}
-
-static void __modify_background_volume(void* data)
-{
- if (NULL != g_delayed_unset_policy_timer) {
- SLOG(LOG_INFO, tts_tag(), "[BG] Background volume is going to recover soon. Skip modification");
- return;
- }
-
- if (NULL != g_modify_background_volume) {
- int result = (intptr_t)ecore_timer_del(g_modify_background_volume);
- g_modify_background_volume = NULL;
- SLOG(LOG_ERROR, tts_tag(), "[BG] Remove modify background volume timer (%d)", result);
+ if (NULL == ratio) {
+ return TTSD_ERROR_INVALID_PARAMETER;
}
- long long int diff = __get_duration_from_last_volume_change();
- if (diff > SND_MGR_DUCKING_DURATION) {
- __recover_background_volume();
- __change_background_volume(0);
- SLOG(LOG_INFO, tts_tag(), "[BG] Direct modify background volume");
- } else {
- double delay = (double)(SND_MGR_DUCKING_DURATION - diff) / 1000.0;
- g_modify_background_volume = ecore_timer_add(delay, __modify_background_volume_async, (void*)CHECK_TIMER_DELETE);
- SLOG(LOG_INFO, tts_tag(), "[BG] Delay modifying background volume (%p), delay(%f)", g_modify_background_volume, delay);
- }
+ *ratio = g_background_volume->getVolumeRatio();
+ return TTSD_ERROR_NONE;
}
int ttsd_player_set_background_volume_ratio(double ratio)
}
SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] ttsd_player_set_background_volume_ratio : %lf", ratio);
-
- double prev_ratio = g_bg_volume_ratio;
- g_bg_volume_ratio = ratio;
-
- SLOG(LOG_DEBUG, tts_tag(), "[Player DEBUG] Check whether sound is ducked and Change volume. as-is(%lf), to-be(%lf)", prev_ratio, g_bg_volume_ratio);
- if (prev_ratio == g_bg_volume_ratio) {
- return TTSD_ERROR_NONE;
- }
-
- if (g_is_set_policy) {
- SLOG(LOG_INFO, tts_tag(), "[BG] Direct modify background volume");
- ecore_main_loop_thread_safe_call_async(__modify_background_volume, NULL);
- }
+ g_background_volume->setVolumeRatio(ratio);
return TTSD_ERROR_NONE;
}