Change a logic for changing system volume using ducking APIs 98/227798/1
authorsooyeon.kim <sooyeon.kim@samsung.com>
Fri, 13 Mar 2020 05:48:53 +0000 (14:48 +0900)
committerSooyeon Kim <sooyeon.kim@samsung.com>
Mon, 16 Mar 2020 10:30:17 +0000 (10:30 +0000)
Change-Id: I7ddf0a47c4ea483f8b8bb19e5957c0ae7595d24d
Signed-off-by: sooyeon.kim <sooyeon.kim@samsung.com>
(cherry picked from commit f5e97e754e5e8aac40c03291ce14f3cbfe1a37db)

client/stt.c
include/stt_internal.h

index a99e423..c3f5f70 100644 (file)
@@ -51,8 +51,14 @@ static cynara *p_cynara = NULL;
 static bool g_err_callback_status = false;
 
 /* for changing volume on each sound stream */
-static sound_stream_info_h     g_stream_for_volume_h = NULL;
-static virtual_sound_stream_h  g_virtual_sound_stream_h = NULL;
+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;
+
+#define STT_BG_VOLUME_RATIO_FARFIELD   0.0
+#define STT_BG_VOLUME_RATIO_NEARFIELD  0.7
+#define SND_MGR_DUCKING_DURATION 500
 
 const char* stt_tag()
 {
@@ -2732,117 +2738,128 @@ int stt_cancel_file(stt_h stt)
        return ret;
 }
 
-int __stt_change_system_volume(stt_system_volume_event_e volume_event)
+void __sound_stream_ducking_state_changed_cb(sound_stream_ducking_h stream_ducking, bool is_ducked, void *user_data)
 {
-       int stream_type = -1;
-       if (STT_SYSTEM_VOLUME_EVENT_CHANGE_FOR_FARFIELD == volume_event) {
-               stream_type = SOUND_STREAM_TYPE_VOICE_RECOGNITION;
-       } else if (STT_SYSTEM_VOLUME_EVENT_CHANGE_FOR_NEARFIELD == volume_event) {
-               stream_type = SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE;
-       } else {
-               SLOG(LOG_ERROR, TAG_STTC, "[ERROR] volume type is invalid, type(%d)", volume_event);
-               return STT_ERROR_INVALID_PARAMETER;
-       }
+       SLOG(LOG_DEBUG, TAG_STTC, "@@@ ducking state changed cb");
+       SLOG(LOG_DEBUG, TAG_STTC, "[Volume] is ducked : %d", is_ducked);
+       // ducking_flag = true;
+       return;
+}
 
-       SLOG(LOG_INFO, TAG_STTC, "[INFO] Change system volume, volume_type(%d)", volume_event);
+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";
 
-       int ret = STT_ERROR_NONE;
-       if (g_stream_for_volume_h) {
-               SLOG(LOG_INFO, TAG_STTC, "[INFO] Stream is already created, destroy stream)");
-               ret = sound_manager_destroy_stream_information(g_stream_for_volume_h);
-               if (0 != ret) {
-                       SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to destroy stream information, ret(%d)", ret);
+       return "Non matched stream";
+}
+
+static int __activate_ducking_sound_stream(sound_stream_type_e stream_type, sound_stream_ducking_h stream_ducking_h, double bg_volume_ratio)
+{
+       bool is_ducked = false;
+       int ret = sound_manager_is_ducked(stream_ducking_h, &is_ducked);
+       if (is_ducked) {
+               SLOG(LOG_DEBUG, TAG_STTC, "[Volume] The %s is already ducked", __get_ducking_stream(stream_type));
+       } else {
+               ret = sound_manager_activate_ducking(stream_ducking_h, SND_MGR_DUCKING_DURATION, bg_volume_ratio);
+               if (SOUND_MANAGER_ERROR_NONE != ret) {
+                       SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to activate ducking for %s", __get_ducking_stream(stream_type));
+               } else {
+                       SLOG(LOG_INFO, TAG_STTC, "[Volume SUCCESS] Activate ducking for %s", __get_ducking_stream(stream_type));
                }
-               g_stream_for_volume_h = NULL;
        }
+       return ret;
+}
 
-       if (SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE == stream_type) {
-               SLOG(LOG_INFO, TAG_STTC, "[INFO] Stream type is SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE");
-               ret = sound_manager_create_stream_information_internal(stream_type, NULL, NULL, &g_stream_for_volume_h);
-       } else if (SOUND_STREAM_TYPE_VOICE_RECOGNITION == stream_type) {
-               SLOG(LOG_INFO, TAG_STTC, "[INFO] Stream type is SOUND_STREAM_TYPE_VOICE_RECOGNITION");
-               ret = sound_manager_create_stream_information(stream_type, NULL, NULL, &g_stream_for_volume_h);
-       }
+static void __change_background_volume(stt_system_volume_event_e volume_event)
+{
+       double bg_volume_ratio = 0.0;
 
-       if (0 != ret) {
-               SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Fail to create stream information, ret(%d)", ret);
-               return STT_ERROR_OPERATION_FAILED;
+       if (STT_SYSTEM_VOLUME_EVENT_CHANGE_FOR_FARFIELD == volume_event) {
+               bg_volume_ratio = STT_BG_VOLUME_RATIO_FARFIELD;
+       } else if (STT_SYSTEM_VOLUME_EVENT_CHANGE_FOR_NEARFIELD == volume_event) {
+               bg_volume_ratio = STT_BG_VOLUME_RATIO_NEARFIELD;
        }
 
-       if (g_virtual_sound_stream_h) {
-               SLOG(LOG_INFO, TAG_STTC, "[INFO] Virtual stream is already created, destroy virtual stream)");
-               ret = sound_manager_destroy_virtual_stream(g_virtual_sound_stream_h);
-               if (0 != ret) {
-                       SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to destroy virtual stream, ret(%d)", ret);
-                       return STT_ERROR_OPERATION_FAILED;
-               }
-               g_virtual_sound_stream_h = NULL;
-       }
+       SLOG(LOG_INFO, TAG_STTC, "[Volume] volume ratio(%lf)", bg_volume_ratio);
 
-       ret = sound_manager_create_virtual_stream(g_stream_for_volume_h, &g_virtual_sound_stream_h);
-       if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create virtual stream, ret(%d)", ret);
-               ret = sound_manager_destroy_stream_information(g_stream_for_volume_h);
-               if (0 != ret) {
-                       SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to destroy stream information, ret(%d)", ret);
-               }
-               g_stream_for_volume_h = NULL;
-               return STT_ERROR_OPERATION_FAILED;
+       if (1.0 > bg_volume_ratio) {
+               __activate_ducking_sound_stream(SOUND_STREAM_TYPE_MEDIA, g_media_stream_ducking, bg_volume_ratio);
+               __activate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_ducking, bg_volume_ratio);
+               __activate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_ducking, bg_volume_ratio);
+               __activate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_ducking, bg_volume_ratio);
        }
+}
 
-       ret = sound_manager_start_virtual_stream(g_virtual_sound_stream_h);
-       if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start virtual stream, ret(%d)", ret);
-               ret = sound_manager_destroy_virtual_stream(g_virtual_sound_stream_h);
-               if (0 != ret) {
-                       SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to destroy virtual stream, ret(%d)", ret);
-               }
-               g_virtual_sound_stream_h = NULL;
-
-               ret = sound_manager_destroy_stream_information(g_stream_for_volume_h);
-               if (0 != ret) {
-                       SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to destroy stream information, ret(%d)", ret);
+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, TAG_STTC, "[Volume] 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, TAG_STTC, "[Volume WARNING] Fail to deactivate ducking for %s", __get_ducking_stream(stream_type));
+               } else {
+                       SLOG(LOG_INFO, TAG_STTC, "[Volume SUCCESS] Deactivate ducking for %s", __get_ducking_stream(stream_type));
                }
-               g_stream_for_volume_h = NULL;
-
-               return STT_ERROR_OPERATION_FAILED;
        }
+       return ret;
+}
 
-       SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Change system volume");
-       return 0;
+static void __recover_background_volume()
+{
+       SLOG(LOG_INFO, TAG_STTC, "[Volume] background volume recover");
+
+       __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);
 }
 
-int __stt_recover_system_volume()
+int __create_ducking_handle(void)
 {
-       SLOG(LOG_INFO, TAG_STTC, "[INFO] Recover system volume");
+       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, TAG_STTC, "[Volume WARNING] Fail to create stream ducking for type media, ret(%d)", ret);
+       } else {
+               SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for media stream is already created");
+       }
 
-       int ret = STT_ERROR_NONE;
+       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, TAG_STTC, "[Volume WARNING] Fail to create stream ducking for system type, ret(%d)", ret);
+       } else {
+               SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for system stream is already created");
+       }
 
-       if (g_virtual_sound_stream_h) {
-               ret = sound_manager_stop_virtual_stream(g_virtual_sound_stream_h);
-               if (0 != ret) {
-                       SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to stop virtual stream, ret(%d)", ret);
-                       return STT_ERROR_OPERATION_FAILED;
-               }
-               ret = sound_manager_destroy_virtual_stream(g_virtual_sound_stream_h);
-               if (0 != ret) {
-                       SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to destroy virtual stream, ret(%d)", ret);
-                       return STT_ERROR_OPERATION_FAILED;
-               }
-               g_virtual_sound_stream_h = NULL;
+       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, TAG_STTC, "[Volume WARNING] Fail to create stream ducking for notification type, ret(%d)", ret);
+       } else {
+               SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for notification stream is already created");
        }
 
-       if (g_stream_for_volume_h) {
-               ret = sound_manager_destroy_stream_information(g_stream_for_volume_h);
-               if (0 != ret) {
-                       SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to destroy stream information, ret(%d)", ret);
-                       return STT_ERROR_OPERATION_FAILED;
-               }
-               g_stream_for_volume_h = NULL;
+       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, TAG_STTC, "[Volume WARNING] Fail to create stream ducking for alarm type, ret(%d)", ret);
+       } else {
+               SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for alarm stream is already created");
        }
 
-       SLOG(LOG_INFO, TAG_STTC, "[SUCCESS] Recover system volume");
-       return 0;
+       return ret;
 }
 
 int stt_change_system_volume(stt_h stt, stt_system_volume_event_e volume_event)
@@ -2867,11 +2884,54 @@ int stt_change_system_volume(stt_h stt, stt_system_volume_event_e volume_event)
        }
 
        /* change system volume */
-       int ret = __stt_change_system_volume(volume_event);
+       int ret = __create_ducking_handle();
        if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to change volume");
+               SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create volume handle");
        } else {
-               SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] Success to change volume");
+               SLOG(LOG_INFO, TAG_STTC, "[DEBUG] Success to create volume handle");
+       }
+
+       __change_background_volume(volume_event);
+       return STT_ERROR_NONE;
+}
+
+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, TAG_STTC, "[Volume WARNING] Fail to destroy media stream ducking, ret(%d)", ret);
+               g_media_stream_ducking = NULL;
+       } else {
+               SLOG(LOG_INFO, TAG_STTC, "[Volume 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, TAG_STTC, "[Volume WARNING] Fail to destroy system stream ducking, ret(%d)", ret);
+               g_system_stream_ducking = NULL;
+       } else {
+               SLOG(LOG_INFO, TAG_STTC, "[Volume 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, TAG_STTC, "[Volume WARNING] Fail to destroy notification stream ducking, ret(%d)", ret);
+               g_notification_stream_ducking = NULL;
+       } else {
+               SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for notification stream is already created");
+       }
+
+       if (g_alarm_stream_ducking) {
+               ret = sound_manager_destroy_stream_ducking(g_alarm_stream_ducking);
+               if (SOUND_MANAGER_ERROR_NONE != ret)
+                       SLOG(LOG_WARN, TAG_STTC, "[Volume WARNING] Fail to destroy alarm stream ducking, ret(%d)", ret);
+               g_alarm_stream_ducking = NULL;
+       } else {
+               SLOG(LOG_INFO, TAG_STTC, "[Volume INFO] Ducking handle for alarm stream is already created");
        }
        return ret;
 }
@@ -2898,12 +2958,14 @@ int stt_recover_system_volume(stt_h stt)
        }
 
        /* recover volume */
-       int ret = __stt_recover_system_volume();
+       __recover_background_volume();
+       int ret = __destroy_ducking_handle();
        if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to recover volume");
+               SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to destroy volume handle");
        } else {
-               SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] Success to recover volume");
+               SLOG(LOG_INFO, TAG_STTC, "[DEBUG] Success to destroy volume handle");
        }
-       return ret;
+
+       return STT_ERROR_NONE;
 }
 //LCOV_EXCL_STOP
index 334c3f5..e84ff2b 100644 (file)
@@ -143,6 +143,9 @@ int stt_cancel_file(stt_h stt);
  * @since_tizen 5.5
  * @privlevel public
  * @privilege %http://tizen.org/privilege/recorder
+ * @privilege %http://tizen.org/privilege/volume.set
+ * @remarks If @a volume_event is STT_SYSTEM_VOLUME_EVENT_CHANGE_FOR_NEARFIELD, the background volume will be reduced by 70 percentage.
+ *          And, if @a volume_event is STT_SYSTEM_VOLUME_EVENT_CHANGE_FOR_FARFIELD, the background volume will be mute.
  * @param[in] stt The STT handle
  * @param[in] volume_event System volume event
  * @return @c 0 on success,
@@ -163,6 +166,7 @@ int stt_change_system_volume(stt_h stt, stt_system_volume_event_e volume_event);
  * @since_tizen 5.5
  * @privlevel public
  * @privilege %http://tizen.org/privilege/recorder
+ * @privilege %http://tizen.org/privilege/volume.set
  * @param[in] stt The STT handle
  * @param[in] volume_event System volume event
  * @return @c 0 on success,