Reactivate sound ducking when background volume ratio is changed 44/268344/1
authorSuyeon Hwang <stom.hwang@samsung.com>
Tue, 21 Dec 2021 06:57:53 +0000 (15:57 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Tue, 21 Dec 2021 06:57:53 +0000 (15:57 +0900)
To avoid some side effect or unintended behavior, current code does not apply the change of
background volume ratio immediately. To apply it immediately, tts service has to deactivate the
sound ducking and activate it again. This may cause tick noise or failure to recover background
volume. However, the requirement wants to apply the background volume ratio immediately.

Thus, this patch deactivate and activate the sound ducking right after changing background volume
ratio. To do this safely, the new code handles the behavior for background volume on main loop.
And this new code only works when the sound ducking is activated.

Change-Id: I11ea051aaa69b5a0bd959853d72943569c678a57
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
server/ttsd_player.c

index 630922953fd326e8382d3a42d121c63ac4fb8a93..a99bd2fbce5650892c6794c81054d4c677044800 100644 (file)
@@ -105,6 +105,7 @@ If you choose too big value, it may cause integer overflow issue.
 
 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;
 
@@ -259,14 +260,14 @@ static char* __get_ducking_stream(sound_stream_type_e stream_type)
        return "Non matched stream";
 }
 
-static int __activate_ducking_sound_stream(sound_stream_type_e stream_type, sound_stream_ducking_h stream_ducking_h)
+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, SND_MGR_DUCKING_DURATION, g_bg_volume_ratio);
+               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 {
@@ -276,18 +277,23 @@ static int __activate_ducking_sound_stream(sound_stream_type_e stream_type, soun
        return ret;
 }
 
-static void __change_background_volume(void* data)
+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);
-//             __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);
+               __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;
@@ -408,7 +414,7 @@ static void __set_policy_for_playing(void)
                SLOG(LOG_WARN, tts_tag(), "[Player WARNING] Fail to set stream info");
        }
 
-       ecore_main_loop_thread_safe_call_async(__change_background_volume, NULL);
+       ecore_main_loop_thread_safe_call_async(__change_background_volume_async, NULL);
 
        g_is_set_policy = true;
        SLOG(LOG_ERROR, tts_tag(), "[BG] g_is_set_policy(%d)", g_is_set_policy);
@@ -1484,6 +1490,41 @@ int ttsd_player_get_background_volume_ratio(double* 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);
+       }
+
+       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);
+       }
+}
+
 int ttsd_player_set_background_volume_ratio(double ratio)
 {
        SLOG(LOG_INFO, tts_tag(), "[Player DEBUG] ttsd_player_set_background_volume_ratio : %lf", ratio);
@@ -1492,7 +1533,14 @@ int ttsd_player_set_background_volume_ratio(double 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);
+       }
 
        return TTSD_ERROR_NONE;
 }