From 382db3a538a68182b4c0624181e345d53f5c9625 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Fri, 13 Mar 2020 14:48:53 +0900 Subject: [PATCH] Change a logic for changing system volume using ducking APIs Change-Id: I7ddf0a47c4ea483f8b8bb19e5957c0ae7595d24d Signed-off-by: sooyeon.kim (cherry picked from commit f5e97e754e5e8aac40c03291ce14f3cbfe1a37db) --- client/stt.c | 254 ++++++++++++++++++++++++++++++------------------- include/stt_internal.h | 4 + 2 files changed, 162 insertions(+), 96 deletions(-) diff --git a/client/stt.c b/client/stt.c index a99e423..c3f5f70 100644 --- a/client/stt.c +++ b/client/stt.c @@ -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 diff --git a/include/stt_internal.h b/include/stt_internal.h index 334c3f5..e84ff2b 100644 --- a/include/stt_internal.h +++ b/include/stt_internal.h @@ -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, -- 2.7.4