From: Suyeon Hwang Date: Fri, 5 Aug 2022 03:45:42 +0000 (+0900) Subject: Add vc_mgr_ducking files X-Git-Tag: submit/tizen/20220826.042422~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0f687bdbd1b56df8284d08c5f0611bbc780f98e0;p=platform%2Fcore%2Fuifw%2Fvoice-control.git Add vc_mgr_ducking files This patch is cherry-picked from next commit: https://review.tizen.org/gerrit/c/platform/core/uifw/voice-control/+/230142 Change-Id: I13d3c62eb06bdc0368b6c0b1bb3a6627dd4c70ef Signed-off-by: Suyeon Hwang --- diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 17a0edd..7b3a3d2 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -1,4 +1,4 @@ -SET(SRCS +SET(SRCS vc.c vc_data.cpp vc_client.c @@ -44,6 +44,7 @@ SET(MANAGER_SRCS vc_mgr_tidl.c vc_mgr_proxy.c vc_mgr_stub.c + vc_mgr_ducking.c ../common/vc_cmd_db.c ../common/vc_command.c ../common/vc_command_util.c diff --git a/client/vc_mgr.c b/client/vc_mgr.c index 295fcf4..f3e65bb 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include #include "vc_cmd_db.h" @@ -34,6 +32,7 @@ #include "vc_mgr_tidl.h" #include "vc_mgr_data.h" #include "vc_mgr_player.h" +#include "vc_mgr_ducking.h" #include "voice_control_command.h" #include "voice_control_command_expand.h" #include "voice_control_common.h" @@ -70,10 +69,6 @@ static pthread_mutex_t g_cynara_mutex = PTHREAD_MUTEX_INITIALIZER; 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; - /* for TTS feedback */ static int g_feedback_rate = 16000; static vc_audio_channel_e g_feedback_audio_channel = 0; @@ -322,6 +317,12 @@ int vc_mgr_initialize(void) SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to initialize VC mgr player : %d", ret); } */ + + ret = vc_mgr_ducking_create(); + if (VC_ERROR_NONE != ret) { + SLOG(LOG_INFO, TAG_VCM, "[INFO] Fail to ducking create : %d", ret); + } + SLOG(LOG_ERROR, TAG_VCM, "[Success] pid(%d)", g_vc_m->handle); SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Initialize DONE"); @@ -406,6 +407,11 @@ int vc_mgr_deinitialize(void) } */ + ret = vc_mgr_ducking_destory(); + if (VC_ERROR_NONE != ret) { + SLOG(LOG_INFO, TAG_VCM, "[INFO] Fail to ducking destory : %d", ret); + } + if (0 != vc_mgr_tidl_close_connection()) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to close connection"); } @@ -3767,116 +3773,59 @@ int vc_mgr_set_audio_streaming_mode(vc_audio_streaming_mode_e mode) return VC_ERROR_NONE; } -int __vc_change_system_volume(vc_system_volume_event_e volume_event) +//TODO it's internal api, so will remove it. +int vc_mgr_change_system_volume(vc_system_volume_event_e event) { - int stream_type = -1; - if (VC_SYSTEM_VOLUME_EVENT_CHANGE_FOR_FARFIELD == volume_event) { - stream_type = SOUND_STREAM_TYPE_VOICE_RECOGNITION; - } else if (VC_SYSTEM_VOLUME_EVENT_CHANGE_FOR_NEARFIELD == volume_event) { - stream_type = SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE; - } else { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] volume type is invalid, type(%d)", volume_event); - return VC_ERROR_INVALID_PARAMETER; - } - - SLOG(LOG_INFO, TAG_VCM, "[INFO] Change system volume, volume_type(%d)", volume_event); + return vc_mgr_change_background_volume(event); +} - int ret = VC_ERROR_NONE; - /* destroy virtual - destroy stream info - create stream info - create virtual */ - if (g_virtual_sound_stream_h) { - SLOG(LOG_INFO, TAG_VCM, "[INFO] Virtual stream is already created, destroy virtual stream)"); - ret = sound_manager_stop_virtual_stream(g_virtual_sound_stream_h); - if (0 != ret) { - SLOG(LOG_WARN, TAG_VCM, "[WARNING] Fail to stop virtual stream, ret(%d)", ret); - } - ret = sound_manager_destroy_virtual_stream(g_virtual_sound_stream_h); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to destroy virtual stream, ret(%d)", ret); - } - g_virtual_sound_stream_h = NULL; - } +//TODO it's internal api, so will remove it. +int vc_mgr_recover_system_volume(void) +{ + return vc_mgr_reset_background_volume(); +} - if (g_stream_for_volume_h) { - SLOG(LOG_INFO, TAG_VCM, "[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_VCM, "[ERROR] Fail to destroy stream information, ret(%d)", ret); - } - g_stream_for_volume_h = NULL; - } +int vc_mgr_change_background_volume(vc_background_volume_event_e event) +{ + SLOG(LOG_INFO, TAG_VCM, "[Manager] Change system volume"); - ret = sound_manager_create_stream_information_internal(stream_type, NULL, NULL, &g_stream_for_volume_h); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to create stream information, ret(%d)", ret); - return VC_ERROR_OPERATION_FAILED; - } + int ret; + ret = __check_mgr_feature_privilege(); + if (VC_ERROR_NONE != ret) + return ret; - ret = sound_manager_create_virtual_stream(g_stream_for_volume_h, &g_virtual_sound_stream_h); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCM, "[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_VCM, "[ERROR] Fail to destroy stream information, ret(%d)", ret); - } - g_stream_for_volume_h = NULL; - return VC_ERROR_OPERATION_FAILED; + if (VC_BACKGROUND_VOLUME_EVENT_CHANGE_FOR_NEARFIELD > event || VC_BACKGROUND_VOLUME_EVENT_CHANGE_FOR_FARFIELD < event) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] event is invalid parameter (%d)", event); + return VC_ERROR_INVALID_PARAMETER; } - ret = sound_manager_start_virtual_stream(g_virtual_sound_stream_h); + vc_state_e state = VC_STATE_NONE; + ret = vc_mgr_client_get_client_state(g_vc_m, &state); if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCM, "[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_VCM, "[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_VCM, "[ERROR] Fail to destroy stream information, ret(%d)", ret); - } - g_stream_for_volume_h = NULL; - - return VC_ERROR_OPERATION_FAILED; + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available"); + return VC_ERROR_INVALID_STATE; } - SLOG(LOG_INFO, TAG_VCM, "[SUCCESS] Change system volume"); - return VC_ERROR_NONE; -} - -int __vc_recover_system_volume() -{ - SLOG(LOG_INFO, TAG_VCM, "[INFO] Recover system volume"); - - int ret = VC_ERROR_NONE; - - if (g_virtual_sound_stream_h) { - ret = sound_manager_stop_virtual_stream(g_virtual_sound_stream_h); - if (0 != ret) { - SLOG(LOG_WARN, TAG_VCM, "[WARNING] Fail to stop virtual stream, ret(%d)", ret); - } - ret = sound_manager_destroy_virtual_stream(g_virtual_sound_stream_h); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to destroy virtual stream, ret(%d)", ret); - return VC_ERROR_OPERATION_FAILED; - } - g_virtual_sound_stream_h = NULL; + if (state != VC_STATE_READY && state != VC_STATE_INITIALIZED) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY' and not 'INITIALIZED', state(%d)", state); + return VC_ERROR_INVALID_STATE; } - if (g_stream_for_volume_h) { - ret = sound_manager_destroy_stream_information(g_stream_for_volume_h); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to destroy stream information, ret(%d)", ret); - return VC_ERROR_OPERATION_FAILED; - } - g_stream_for_volume_h = NULL; - } + double ratio = 0.0; + if (VC_BACKGROUND_VOLUME_EVENT_CHANGE_FOR_FARFIELD == event) + ratio = 0.0; + else if (VC_BACKGROUND_VOLUME_EVENT_CHANGE_FOR_NEARFIELD == event) + ratio = 0.7; - SLOG(LOG_INFO, TAG_VCM, "[SUCCESS] Recover system volume"); - return VC_ERROR_NONE; + ret = vc_mgr_ducking_activate(ratio); + if (0 != ret) + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to change volume"); + else + SLOG(LOG_INFO, TAG_VCM, "[DEBUG] Success to change volume"); + return ret; } -int vc_mgr_change_system_volume(vc_system_volume_event_e event) +int vc_mgr_change_background_volume_by_ratio(double ratio) { SLOG(LOG_INFO, TAG_VCM, "[Manager] Change system volume"); @@ -3885,12 +3834,12 @@ int vc_mgr_change_system_volume(vc_system_volume_event_e event) if (VC_ERROR_NONE != ret) return ret; - if (VC_SYSTEM_VOLUME_EVENT_CHANGE_FOR_NEARFIELD > event || VC_SYSTEM_VOLUME_EVENT_CHANGE_FOR_FARFIELD < event) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] event is invalid parameter (%d)", event); + if (0.0 > ratio || 1.0 < ratio) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] ratio is invalid parameter (%lf)", ratio); return VC_ERROR_INVALID_PARAMETER; } - vc_state_e state; + vc_state_e state = VC_STATE_NONE; ret = vc_mgr_client_get_client_state(g_vc_m, &state); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available"); @@ -3902,15 +3851,15 @@ int vc_mgr_change_system_volume(vc_system_volume_event_e event) return VC_ERROR_INVALID_STATE; } - ret = __vc_change_system_volume(event); + ret = vc_mgr_ducking_activate(ratio); if (0 != ret) - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to change volume"); + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to set ratio"); else - SLOG(LOG_INFO, TAG_VCM, "[DEBUG] Success to change volume"); + SLOG(LOG_INFO, TAG_VCM, "[DEBUG] Success to set ratio"); return ret; } -int vc_mgr_recover_system_volume(void) +int vc_mgr_reset_background_volume(void) { SLOG(LOG_INFO, TAG_VCM, "[Manager] recover system volume"); @@ -3931,8 +3880,7 @@ int vc_mgr_recover_system_volume(void) return VC_ERROR_INVALID_STATE; } - /* recover volume */ - ret = __vc_recover_system_volume(); + ret = vc_mgr_ducking_deactivate(); if (0 != ret) SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to recover volume"); else diff --git a/client/vc_mgr_ducking.c b/client/vc_mgr_ducking.c new file mode 100644 index 0000000..a8555ad --- /dev/null +++ b/client/vc_mgr_ducking.c @@ -0,0 +1,223 @@ +/* +* Copyright (c) 2020 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 +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "vc_main.h" +#include "voice_control_common.h" +#include "vc_mgr_ducking.h" +#include + +#define SND_MGR_DUCKING_DURATION 500 + +/* for changing volume on each sound stream */ +static sound_stream_ducking_h g_media_stream_h = NULL; +static sound_stream_ducking_h g_system_stream_h = NULL; +static sound_stream_ducking_h g_notification_stream_h = NULL; +static sound_stream_ducking_h g_alarm_stream_h = NULL; + +static char *__get_ducking_stream(sound_stream_type_e stream_type); +static int __activate_ducking_sound_stream(sound_stream_type_e type, sound_stream_ducking_h header, double ratio); +static int __deactivate_ducking_sound_stream(sound_stream_type_e type, sound_stream_ducking_h header); + +int vc_mgr_ducking_create(void) +{ + int ret = VC_ERROR_NONE; + + if (g_media_stream_h) { + SLOG(LOG_INFO, TAG_VCM, "Ducking handle for media stream is already created"); + } else { + ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_MEDIA, NULL, NULL, &g_media_stream_h); + if (SOUND_MANAGER_ERROR_NONE != ret) { + g_media_stream_h = NULL; + SLOG(LOG_ERROR, TAG_VCM, "Fail to create stream ducking for type media, ret(%d)", ret); + return ret; + } + } + + if (g_system_stream_h) { + SLOG(LOG_INFO, TAG_VCM, "Ducking handle for system stream is already created"); + } else { + ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_SYSTEM, NULL, NULL, &g_system_stream_h); + if (SOUND_MANAGER_ERROR_NONE != ret) { + sound_manager_destroy_stream_ducking(g_media_stream_h); + g_media_stream_h = NULL; + g_system_stream_h = NULL; + SLOG(LOG_ERROR, TAG_VCM, "Fail to create stream ducking for type system, ret(%d)", ret); + return ret; + } + } + + if (g_notification_stream_h) { + SLOG(LOG_INFO, TAG_VCM, "Ducking handle for notification stream is already created"); + } else { + ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_NOTIFICATION, NULL, NULL, &g_notification_stream_h); + if (SOUND_MANAGER_ERROR_NONE != ret) { + sound_manager_destroy_stream_ducking(g_media_stream_h); + sound_manager_destroy_stream_ducking(g_system_stream_h); + g_media_stream_h = NULL; + g_system_stream_h = NULL; + g_notification_stream_h = NULL; + SLOG(LOG_ERROR, TAG_VCM, "Fail to create stream ducking for type notification, ret(%d)", ret); + return ret; + } + } + + if (g_alarm_stream_h) { + SLOG(LOG_INFO, TAG_VCM, "Ducking handle for alarm stream is already created"); + } else { + ret = sound_manager_create_stream_ducking(SOUND_STREAM_TYPE_ALARM, NULL, NULL, &g_alarm_stream_h); + if (SOUND_MANAGER_ERROR_NONE != ret) { + sound_manager_destroy_stream_ducking(g_media_stream_h); + sound_manager_destroy_stream_ducking(g_system_stream_h); + sound_manager_destroy_stream_ducking(g_system_stream_h); + g_media_stream_h = NULL; + g_system_stream_h = NULL; + g_notification_stream_h = NULL; + g_alarm_stream_h = NULL; + SLOG(LOG_ERROR, TAG_VCM, "Fail to create stream ducking for type media, ret(%d)", ret); + return ret; + } + } + + return VC_ERROR_NONE; +} + +int vc_mgr_ducking_destory(void) +{ + int ret = VC_ERROR_NONE; + + if (g_media_stream_h) { + ret = sound_manager_destroy_stream_ducking(g_media_stream_h); + if (SOUND_MANAGER_ERROR_NONE != ret) + SLOG(LOG_WARN, TAG_VCM, "Fail to destroy media stream ducking, ret(%d)", ret); + g_media_stream_h = NULL; + } else { + SLOG(LOG_INFO, TAG_VCM, "[Volume INFO] Ducking handle for media stream is already created"); + } + + if (g_system_stream_h) { + ret = sound_manager_destroy_stream_ducking(g_system_stream_h); + if (SOUND_MANAGER_ERROR_NONE != ret) + SLOG(LOG_WARN, TAG_VCM, "[Volume WARNING] Fail to destroy system stream ducking, ret(%d)", ret); + g_system_stream_h = NULL; + } else { + SLOG(LOG_INFO, TAG_VCM, "[Volume INFO] Ducking handle for system stream is already created"); + } + + if (g_notification_stream_h) { + ret = sound_manager_destroy_stream_ducking(g_notification_stream_h); + if (SOUND_MANAGER_ERROR_NONE != ret) + SLOG(LOG_WARN, TAG_VCM, "[Volume WARNING] Fail to destroy notification stream ducking, ret(%d)", ret); + g_notification_stream_h = NULL; + } else { + SLOG(LOG_INFO, TAG_VCM, "[Volume INFO] Ducking handle for notification stream is already created"); + } + + if (g_alarm_stream_h) { + ret = sound_manager_destroy_stream_ducking(g_alarm_stream_h); + if (SOUND_MANAGER_ERROR_NONE != ret) + SLOG(LOG_WARN, TAG_VCM, "[Volume WARNING] Fail to destroy alarm stream ducking, ret(%d)", ret); + g_alarm_stream_h = NULL; + } else { + SLOG(LOG_INFO, TAG_VCM, "[Volume INFO] Ducking handle for alarm stream is already created"); + } + + return VC_ERROR_NONE; +} + +int vc_mgr_ducking_activate(double ratio) +{ + SLOG(LOG_INFO, TAG_VCM, "vc_mgr_ducking_activate ratio(%lf)", ratio); + + int ret = VC_ERROR_NONE; + ret = __activate_ducking_sound_stream(SOUND_STREAM_TYPE_MEDIA, g_media_stream_h, ratio); + if (SOUND_MANAGER_ERROR_NONE != ret) + return ret; + ret = __activate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_h, ratio); + if (SOUND_MANAGER_ERROR_NONE != ret) + return ret; + ret = __activate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_h, ratio); + if (SOUND_MANAGER_ERROR_NONE != ret) + return ret; + ret = __activate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_h, ratio); + return ret; +} + +int vc_mgr_ducking_deactivate(void) +{ + SLOG(LOG_INFO, TAG_VCM, "vc_mgr_ducking_deactivate"); + + int ret = VC_ERROR_NONE; + ret = __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_MEDIA, g_media_stream_h); + if (SOUND_MANAGER_ERROR_NONE != ret) + return ret; + ret = __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_SYSTEM, g_system_stream_h); + if (SOUND_MANAGER_ERROR_NONE != ret) + return ret; + ret = __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_NOTIFICATION, g_notification_stream_h); + if (SOUND_MANAGER_ERROR_NONE != ret) + return ret; + ret = __deactivate_ducking_sound_stream(SOUND_STREAM_TYPE_ALARM, g_alarm_stream_h); + return ret; +} + +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 type, sound_stream_ducking_h header, double ratio) +{ + bool is_ducked = false; + int ret = SOUND_MANAGER_ERROR_NONE; + ret = sound_manager_is_ducked(header, &is_ducked); + if (is_ducked) { + SLOG(LOG_DEBUG, TAG_VCM, "The %s is already ducked", __get_ducking_stream(type)); + return ret; + } + + ret = sound_manager_activate_ducking(header, SND_MGR_DUCKING_DURATION, ratio); + if (SOUND_MANAGER_ERROR_NONE != ret) + SLOG(LOG_ERROR, TAG_VCM, "Fail to activate ducking for %s", __get_ducking_stream(type)); + else + SLOG(LOG_INFO, TAG_VCM, "Activate ducking for %s", __get_ducking_stream(type)); + return ret; +} + +static int __deactivate_ducking_sound_stream(sound_stream_type_e type, sound_stream_ducking_h header) +{ + bool is_ducked = false; + int ret = SOUND_MANAGER_ERROR_NONE; + ret = sound_manager_is_ducked(header, &is_ducked); + if (false == is_ducked) { + SLOG(LOG_DEBUG, TAG_VCM, "The %s is already recovered from ducking", __get_ducking_stream(type)); + return ret; + } + + ret = sound_manager_deactivate_ducking(header); + if (SOUND_MANAGER_ERROR_NONE != ret) + SLOG(LOG_ERROR, TAG_VCM, "Fail to deactivate ducking for %s", __get_ducking_stream(type)); + else + SLOG(LOG_INFO, TAG_VCM, "Deactivate ducking for %s", __get_ducking_stream(type)); + return ret; +} diff --git a/client/vc_mgr_ducking.h b/client/vc_mgr_ducking.h new file mode 100644 index 0000000..56ada10 --- /dev/null +++ b/client/vc_mgr_ducking.h @@ -0,0 +1,19 @@ + +#ifndef __VC_MGR_DUCKING_H__ +#define __VC_MGR_DUCKING_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int vc_mgr_ducking_create(void); +int vc_mgr_ducking_destory(void); + +int vc_mgr_ducking_activate(double ratio); +int vc_mgr_ducking_deactivate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __VC_MGR_DUCKING_H__ */