hal: Adding support for AudioControl HAL's mute and duck features
* Add support for ducking and unducking in Auto HAL
* Add support for muting and unmuting in Auto HAL
* Route adev_set_parameters to Auto HAL
Change-Id: I266c13869219e6f7ffe4f5f2f3d3df16e9da4415
diff --git a/hal/audio_extn/Android.mk b/hal/audio_extn/Android.mk
index 7fc02cb..d43bbe7 100644
--- a/hal/audio_extn/Android.mk
+++ b/hal/audio_extn/Android.mk
@@ -1189,7 +1189,8 @@
libcutils \
libdl \
libexpat \
- liblog
+ liblog \
+ libtinyalsa
LOCAL_C_INCLUDES := \
$(PRIMARY_HAL_PATH) \
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index c4fa9ac..eb07557 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -6370,6 +6370,7 @@
auto_hal_init_config.fp_platform_set_echo_reference = platform_set_echo_reference;
auto_hal_init_config.fp_platform_get_eccarstate = platform_get_eccarstate;
auto_hal_init_config.fp_generate_patch_handle = generate_patch_handle;
+ auto_hal_init_config.fp_platform_get_pcm_device_id = platform_get_pcm_device_id;
return auto_hal_init(adev, auto_hal_init_config);
}
else
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 057d9a8..75ef7f2 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -1422,6 +1422,7 @@
fp_platform_set_echo_reference_t fp_platform_set_echo_reference;
fp_platform_get_eccarstate_t fp_platform_get_eccarstate;
fp_generate_patch_handle_t fp_generate_patch_handle;
+ fp_platform_get_pcm_device_id_t fp_platform_get_pcm_device_id;
} auto_hal_init_config_t;
// END: AUTO_HAL FEATURE ==================================================
diff --git a/hal/audio_extn/auto_hal.c b/hal/audio_extn/auto_hal.c
index 903bc13..037b0e5 100644
--- a/hal/audio_extn/auto_hal.c
+++ b/hal/audio_extn/auto_hal.c
@@ -34,6 +34,7 @@
#include <log/log.h>
#include <math.h>
#include <audio_hw.h>
+#include <tinyalsa/asoundlib.h>
#include "audio_extn.h"
#include "platform_api.h"
#include "platform.h"
@@ -46,6 +47,17 @@
#include <log_utils.h>
#endif
+#define MAX_VOLUME 1.995262
+#define DSP_MAX_VOLUME 0x2000
+#define DUCKED_VOLUME 0.0035
+
+enum {
+ AUDIO_DEVICE_DUCKED = 0,
+ AUDIO_DEVICE_UNDUCKED,
+ AUDIO_DEVICE_MUTED,
+ AUDIO_DEVICE_UNMUTED
+};
+
//external feature dependency
static fp_audio_extn_ext_hw_plugin_usecase_start_t fp_audio_extn_ext_hw_plugin_usecase_start;
static fp_audio_extn_ext_hw_plugin_usecase_stop_t fp_audio_extn_ext_hw_plugin_usecase_stop;
@@ -59,6 +71,7 @@
static fp_platform_set_echo_reference_t fp_platform_set_echo_reference;
static fp_platform_get_eccarstate_t fp_platform_get_eccarstate;
static fp_generate_patch_handle_t fp_generate_patch_handle;
+static fp_platform_get_pcm_device_id_t fp_platform_get_pcm_device_id;
/* Auto hal module struct */
static struct auto_hal_module *auto_hal = NULL;
@@ -669,11 +682,84 @@
return ret;
}
-void auto_hal_set_parameters(struct audio_device *adev __unused,
+
+static int auto_hal_out_set_pcm_volume(struct stream_out *out, float volume)
+{
+ /* Volume control for pcm playback */
+ char mixer_ctl_name[128];
+ struct audio_device *adev = out->dev;
+ struct mixer_ctl *ctl;
+ int pcm_device_id = fp_platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "Playback %d Volume", pcm_device_id);
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s : Could not get ctl for mixer cmd - %s", __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+
+ int dsp_vol = (int) (volume * DSP_MAX_VOLUME);
+ int ret = mixer_ctl_set_value(ctl, 0, dsp_vol);
+ if (ret < 0) {
+ ALOGE("%s: Could not set ctl, error:%d ", __func__, ret);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void auto_hal_set_mute_duck_state(struct audio_device *adev,
+ char* duck_mute_value,
+ int duck_mute_state)
+{
+ struct listnode *node = NULL;
+ char *ptr = NULL;
+ char *saveptr = NULL;
+ struct stream_out *out = NULL;
+ int car_audio_stream = -1;
+
+ for (ptr = strtok_r(duck_mute_value, ",", &saveptr);
+ ptr != NULL; ptr = strtok_r(NULL, ",", &saveptr)) {
+ list_for_each(node, &adev->active_outputs_list) {
+ streams_output_ctxt_t *out_ctxt = node_to_item(node,
+ streams_output_ctxt_t,
+ list);
+ out = out_ctxt->output;
+ car_audio_stream = auto_hal_get_car_audio_stream_from_address(ptr);
+ if (car_audio_stream == out->car_audio_stream) {
+ switch(duck_mute_state) {
+ case AUDIO_DEVICE_DUCKED:
+ ALOGD("%s: Ducking BUS device %s", __func__, ptr);
+ auto_hal_out_set_pcm_volume(out, DUCKED_VOLUME);
+ break;
+
+ case AUDIO_DEVICE_UNDUCKED:
+ ALOGD("%s: Unducking BUS device %s", __func__, ptr);
+ auto_hal_out_set_pcm_volume(out, out->volume_l);
+ break;
+
+ case AUDIO_DEVICE_MUTED:
+ ALOGD("%s: Muting BUS device %s", __func__, ptr);
+ out->muted = true;
+ break;
+
+ case AUDIO_DEVICE_UNMUTED:
+ ALOGD("%s: Unmuting BUS device %s", __func__, ptr);
+ out->muted = false;
+ break;
+ }
+ }
+ }
+ }
+
+}
+
+void auto_hal_set_parameters(struct audio_device *adev,
struct str_parms *parms)
{
int ret = 0;
char value[32]={0};
+ char duck_mute_value[128] = {0};
+ char *ptr = NULL;
ALOGV("%s: enter", __func__);
@@ -689,6 +775,22 @@
}
}
+ ret = str_parms_get_str(parms, "DevicesToDuck", duck_mute_value, sizeof(duck_mute_value));
+ if (ret >= 0)
+ auto_hal_set_mute_duck_state(adev, duck_mute_value, AUDIO_DEVICE_DUCKED);
+
+ ret = str_parms_get_str(parms, "DevicesToUnduck", duck_mute_value, sizeof(duck_mute_value));
+ if (ret >= 0)
+ auto_hal_set_mute_duck_state(adev, duck_mute_value, AUDIO_DEVICE_UNDUCKED);
+
+ ret = str_parms_get_str(parms, "DevicesToMute", duck_mute_value, sizeof(duck_mute_value));
+ if (ret >= 0)
+ auto_hal_set_mute_duck_state(adev, duck_mute_value, AUDIO_DEVICE_MUTED);
+
+ ret = str_parms_get_str(parms, "DevicesToUnmute", duck_mute_value, sizeof(duck_mute_value));
+ if (ret >= 0)
+ auto_hal_set_mute_duck_state(adev, duck_mute_value, AUDIO_DEVICE_UNMUTED);
+
ALOGV("%s: exit", __func__);
}
@@ -1031,6 +1133,7 @@
fp_platform_set_echo_reference = init_config.fp_platform_set_echo_reference;
fp_platform_get_eccarstate = init_config.fp_platform_get_eccarstate;
fp_generate_patch_handle = init_config.fp_generate_patch_handle;
+ fp_platform_get_pcm_device_id = init_config.fp_platform_get_pcm_device_id;
return ret;
}
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 5a284ea..ccabe30 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -9422,6 +9422,7 @@
}
}
+ audio_extn_auto_hal_set_parameters(adev, parms);
audio_extn_set_parameters(adev, parms);
done:
str_parms_destroy(parms);