#include <cynara-error.h>
#include <cynara-session.h>
#include <pthread.h>
-#include <sound_manager.h>
-#include <sound_manager_internal.h>
#include <math.h>
#include "vc_cmd_db.h"
#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"
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;
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");
}
*/
+ 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");
}
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");
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");
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");
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
--- /dev/null
+/*
+* 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 <sound_manager.h>
+
+#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;
+}