hal: Add dynamic enablement of AEC/NS for VoIP
Add capability to dynamically enable or disable AEC/NS audio effects
on DSP for a VoIP call.
Bug: 70805651
Test: manual
Change-Id: I16f1f6664b39afaedfca92afbc87002685f6e369
diff --git a/hal/Android.mk b/hal/Android.mk
index 236ed11..7f93710 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -197,7 +197,6 @@
LOCAL_SRC_FILES += audio_extn/sndmonitor.c
endif
-
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_USB_SERVICE_INTERVAL)), true)
LOCAL_CFLAGS += -DUSB_SERVICE_INTERVAL_ENABLED
endif
@@ -215,6 +214,10 @@
LOCAL_CFLAGS += -DBG_CODEC_CAL
endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DYNAMIC_ECNS)),true)
+ LOCAL_CFLAGS += -DDYNAMIC_ECNS_ENABLED
+endif
+
LOCAL_SHARED_LIBRARIES += libbase libhidlbase libhwbinder libutils android.hardware.power@1.2 liblog
LOCAL_SRC_FILES += audio_perf.cpp
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 5af3897..e1d5309 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -807,6 +807,147 @@
return 0;
}
+#ifdef DYNAMIC_ECNS_ENABLED
+static int send_effect_enable_disable_mixer_ctl(struct audio_device *adev,
+ struct stream_in *in,
+ struct audio_effect_config effect_config,
+ unsigned int param_value)
+{
+ char mixer_ctl_name[] = "Audio Effect";
+ long set_values[6];
+
+ struct mixer_ctl *ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get mixer ctl - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+
+ set_values[0] = 1; //0:Rx 1:Tx
+ set_values[1] = in->app_type_cfg.app_type;
+ set_values[2] = (long)effect_config.module_id;
+ set_values[3] = (long)effect_config.instance_id;
+ set_values[4] = (long)effect_config.param_id;
+ set_values[5] = param_value;
+
+ mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+
+ return 0;
+
+}
+
+static int update_effect_param_ecns(struct audio_usecase *usecase,
+ unsigned int module_id, int effect_type,
+ unsigned int *param_value)
+{
+ int ret = 0;
+ struct audio_effect_config other_effect_config;
+ struct stream_in *in = NULL;
+
+ if (!usecase)
+ return -EINVAL;
+
+ in = usecase->stream.in;
+
+ /* Get the effect config data of the other effect */
+ ret = platform_get_effect_config_data(usecase->in_snd_device,
+ &other_effect_config,
+ effect_type == EFFECT_AEC ? EFFECT_NS : EFFECT_AEC);
+ if (ret < 0) {
+ ALOGE("%s Failed to get effect params %d", __func__, ret);
+ return ret;
+ }
+
+ if (module_id == other_effect_config.module_id) {
+ //Same module id for AEC/NS. Values need to be combined
+ if (((effect_type == EFFECT_AEC) && (in->enable_ns)) ||
+ ((effect_type == EFFECT_NS) && (in->enable_aec)))
+ *param_value |= other_effect_config.param_value;
+ }
+
+ return ret;
+}
+
+static int enable_disable_effect(struct audio_device *adev, struct stream_in *in,
+ int effect_type, bool enable)
+{
+ struct audio_effect_config effect_config;
+ struct audio_usecase *usecase = NULL;
+ int ret = 0;
+ unsigned int param_value = 0;
+
+ if (!in) {
+ ALOGE("%s: Invalid input stream", __func__);
+ return -EINVAL;
+ }
+
+ ALOGD("%s: effect_type:%d enable:%d", __func__, effect_type, enable);
+
+ usecase = get_usecase_from_list(adev, in->usecase);
+
+ ret = platform_get_effect_config_data(usecase->in_snd_device,
+ &effect_config, effect_type);
+ if (ret < 0) {
+ ALOGE("%s Failed to get module id %d", __func__, ret);
+ return ret;
+ }
+ ALOGV("%s: module %d app_type %d usecase->id:%d usecase->in_snd_device:%d",
+ __func__, effect_config.module_id, in->app_type_cfg.app_type,
+ usecase->id, usecase->in_snd_device);
+
+ if (enable)
+ param_value = effect_config.param_value;
+
+ /*Special handling for AEC & NS effects Param values need to be
+ updated if module ids are same*/
+
+ if ((effect_type == EFFECT_AEC) || (effect_type == EFFECT_NS)) {
+ ret = update_effect_param_ecns(usecase, effect_config.module_id,
+ effect_type, ¶m_value);
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = send_effect_enable_disable_mixer_ctl(adev, in,
+ effect_config, param_value);
+
+ return ret;
+}
+
+static int check_and_enable_effect(struct audio_device *adev)
+{
+ int ret = 0;
+
+ struct listnode *node;
+ struct stream_in *in = NULL;
+
+ list_for_each(node, &adev->usecase_list)
+ {
+ struct audio_usecase *usecase = node_to_item(node, struct audio_usecase, list);
+ if (usecase->type == PCM_CAPTURE && usecase->stream.in != NULL) {
+ in = usecase->stream.in;
+
+ if (in->standby)
+ continue;
+
+ if (in->enable_aec) {
+ ret = enable_disable_effect(adev, in, EFFECT_AEC, true);
+ }
+
+ if (in->enable_ns &&
+ in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
+ ret = enable_disable_effect(adev, in, EFFECT_NS, true);
+ }
+ }
+ }
+
+ return ret;
+}
+#else
+#define enable_disable_effect(w, x, y, z) -ENOSYS
+#define check_and_enable_effect(x) -ENOSYS
+#endif
+
/*
legend:
uc - existing usecase
@@ -1543,6 +1684,11 @@
audio_extn_ma_set_device(usecase);
+ /* If input stream is already running the effect needs to be
+ applied on the new input device that's being enabled here. */
+ if (in_snd_device != SND_DEVICE_NONE)
+ check_and_enable_effect(adev);
+
/* Applicable only on the targets that has external modem.
* Enable device command should be sent to modem only after
* enabling voice call mixer controls
@@ -1708,6 +1854,7 @@
}
}
register_in_stream(in);
+ check_and_enable_effect(adev);
audio_streaming_hint_end();
audio_extn_perf_lock_release();
ALOGV("%s: exit", __func__);
@@ -3954,6 +4101,8 @@
effect_descriptor_t desc;
status = (*effect)->get_descriptor(effect, &desc);
+ ALOGV("%s: status %d in->standby %d enable:%d", __func__, status, in->standby, enable);
+
if (status != 0)
return status;
@@ -3978,14 +4127,18 @@
select_devices(adev, usecase->id);
}
}
- if (!in->standby)
+ if (!in->standby
+ && enable_disable_effect(in->dev, in, EFFECT_AEC, enable) == -ENOSYS)
select_devices(in->dev, in->usecase);
}
if (in->enable_ns != enable &&
(memcmp(&desc.type, FX_IID_NS, sizeof(effect_uuid_t)) == 0)) {
in->enable_ns = enable;
- if (!in->standby)
- select_devices(in->dev, in->usecase);
+ if (!in->standby) {
+ if (in->source != AUDIO_SOURCE_VOICE_COMMUNICATION
+ || enable_disable_effect(in->dev, in, EFFECT_NS, enable) == -ENOSYS)
+ select_devices(in->dev, in->usecase);
+ }
}
pthread_mutex_unlock(&in->dev->lock);
pthread_mutex_unlock(&in->lock);
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 56220e1..7d35ff5 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -81,6 +81,8 @@
#define TOSTRING_(x) #x
#define TOSTRING(x) TOSTRING_(x)
+#define GET_IN_DEVICE_INDEX(SND_DEVICE) ((SND_DEVICE) - (SND_DEVICE_IN_BEGIN))
+
char cal_name_info[WCD9XXX_MAX_CAL][MAX_CAL_NAME] = {
[WCD9XXX_MBHC_CAL] = "mbhc_cal",
};
@@ -301,6 +303,34 @@
[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
};
+static struct audio_effect_config \
+ effect_config_table[GET_IN_DEVICE_INDEX(SND_DEVICE_MAX)][EFFECT_COUNT] = {
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)][EFFECT_AEC] = \
+ {TX_VOICE_FLUENCE_PROV2, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)][EFFECT_NS] = \
+ {TX_VOICE_FLUENCE_PROV2, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)][EFFECT_AEC] = \
+ {TX_VOICE_DM_FV5_BROADSIDE, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)][EFFECT_NS] = \
+ {TX_VOICE_DM_FV5_BROADSIDE, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)][EFFECT_AEC] = \
+ {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)][EFFECT_NS] = \
+ {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)][EFFECT_AEC] = \
+ {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)][EFFECT_NS] = \
+ {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)][EFFECT_AEC] = \
+ {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)][EFFECT_NS] = \
+ {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)][EFFECT_AEC] = \
+ {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)][EFFECT_NS] = \
+ {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x02},
+};
+
/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
static int acdb_device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_NONE] = -1,
@@ -1416,6 +1446,35 @@
return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
}
+int platform_get_effect_config_data(snd_device_t snd_device,
+ struct audio_effect_config *effect_config,
+ effect_type_t effect_type)
+{
+ int ret = 0;
+
+ if ((snd_device < SND_DEVICE_IN_BEGIN) || (snd_device >= SND_DEVICE_MAX) ||
+ (effect_type <= EFFECT_NONE) || (effect_type >= EFFECT_COUNT)) {
+ ALOGE("%s: Invalid snd_device = %d or effect_type = %d",
+ __func__, snd_device, effect_type);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (effect_config == NULL) {
+ ALOGE("%s: Invalid effect_config", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ALOGV("%s: snd_device = %d module_id = %d",
+ __func__, snd_device,
+ effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type].module_id);
+ *effect_config = effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type];
+
+done:
+ return ret;
+}
+
void platform_add_operator_specific_device(snd_device_t snd_device,
const char *operator,
const char *mixer_path,
@@ -1499,6 +1558,27 @@
}
}
return key;
+
+int platform_set_effect_config_data(snd_device_t snd_device,
+ struct audio_effect_config effect_config,
+ effect_type_t effect_type)
+{
+ int ret = 0;
+
+ if ((snd_device < SND_DEVICE_IN_BEGIN) || (snd_device >= SND_DEVICE_MAX) ||
+ (effect_type <= EFFECT_NONE) || (effect_type >= EFFECT_COUNT)) {
+ ALOGE("%s: Invalid snd_device = %d or effect_type = %d",
+ __func__, snd_device, effect_type);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ALOGV("%s 0x%x 0x%x 0x%x 0x%x", __func__, effect_config.module_id,
+ effect_config.instance_id, effect_config.param_id,
+ effect_config.param_value);
+ effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type] = effect_config;
+done:
+ return ret;
}
int platform_get_default_app_type_v2(void *platform, usecase_type_t type, int *app_type)
@@ -1930,6 +2010,139 @@
return snd_device;
}
+#ifdef DYNAMIC_ECNS_ENABLED
+static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+ struct stream_in *in __unused,
+ audio_devices_t out_device,
+ audio_devices_t in_device)
+{
+ struct audio_device *adev = my_data->adev;
+ snd_device_t snd_device = SND_DEVICE_NONE;
+
+ if (my_data->fluence_type != FLUENCE_NONE) {
+ switch(AUDIO_DEVICE_BIT_IN | in_device) {
+ case AUDIO_DEVICE_IN_BACK_MIC:
+ if (my_data->fluence_in_spkr_mode) {
+ if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
+ } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ if (my_data->fluence_mode == FLUENCE_BROADSIDE)
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
+ else
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
+ }
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
+ break;
+ case AUDIO_DEVICE_IN_BUILTIN_MIC:
+ if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
+ break;
+ default:
+ ALOGE("%s: Unsupported in_device %#x", __func__, in_device);
+ break;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ }
+
+ return snd_device;
+}
+#else
+static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+ struct stream_in *in,
+ audio_devices_t out_device,
+ audio_devices_t in_device)
+{
+ struct audio_device *adev = my_data->adev;
+ snd_device_t snd_device = SND_DEVICE_NONE;
+
+ if (my_data->fluence_type != FLUENCE_NONE &&
+ in->enable_aec &&
+ in->enable_ns) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode) {
+ if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
+ } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ if (my_data->fluence_mode == FLUENCE_BROADSIDE)
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
+ else
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
+ }
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ } else if (my_data->fluence_type != FLUENCE_NONE &&
+ in->enable_aec) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode) {
+ if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
+ } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ if (my_data->fluence_mode == FLUENCE_BROADSIDE)
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
+ else
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
+ }
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ } else if (my_data->fluence_type != FLUENCE_NONE &&
+ in->enable_ns) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode) {
+ if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
+ } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ if (my_data->fluence_mode == FLUENCE_BROADSIDE)
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
+ else
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
+ }
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
+ }
+ platform_set_echo_reference(adev, false, out_device);
+ } else
+ platform_set_echo_reference(adev, false, out_device);
+
+ return snd_device;
+}
+#endif //DYNAMIC_ECNS_ENABLED
+
snd_device_t platform_get_input_snd_device(void *platform,
struct stream_in *in,
audio_devices_t out_device)
@@ -2056,85 +2269,10 @@
(mode == AUDIO_MODE_IN_COMMUNICATION)) {
if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
in_device = AUDIO_DEVICE_IN_BACK_MIC;
+
if (in) {
- if (my_data->fluence_type != FLUENCE_NONE &&
- in->enable_aec &&
- in->enable_ns) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_in_spkr_mode) {
- if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
- snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
- } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
- if (my_data->fluence_mode == FLUENCE_BROADSIDE)
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
- else
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
- }
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- }
- platform_set_echo_reference(adev, true, out_device);
- } else if (my_data->fluence_type != FLUENCE_NONE &&
- in->enable_aec) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_in_spkr_mode) {
- if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
- snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
- } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
- if (my_data->fluence_mode == FLUENCE_BROADSIDE)
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
- else
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
- }
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- }
- platform_set_echo_reference(adev, true, out_device);
- } else if (my_data->fluence_type != FLUENCE_NONE &&
- in->enable_ns) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_in_spkr_mode) {
- if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
- snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
- } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
- if (my_data->fluence_mode == FLUENCE_BROADSIDE)
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
- else
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
- }
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- }
- platform_set_echo_reference(adev, false, out_device);
- } else
- platform_set_echo_reference(adev, false, out_device);
+ snd_device = get_snd_device_for_voice_comm(my_data, in,
+ out_device, in_device);
}
} else if (source == AUDIO_SOURCE_FM_TUNER) {
snd_device = SND_DEVICE_IN_CAPTURE_FM;
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 9913322..f3dbc3d 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -250,6 +250,11 @@
#define AUDIO_MAKE_STRING_FROM_ENUM(X) { #X, X }
+#define TX_VOICE_FLUENCE_PROV2 0x10F17
+#define TX_VOICE_DM_FV5_BROADSIDE 0x10F18
+#define TX_VOICE_FV5ECNS_SM 0x10F09
+#define TX_VOICE_FV5ECNS_DM 0x10F0A
+
#define LIB_CSD_CLIENT "libcsd-client.so"
/* CSD-CLIENT related functions */
typedef int (*init_t)();
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 481b57d..f03356b 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -72,6 +72,8 @@
#define TOSTRING_(x) #x
#define TOSTRING(x) TOSTRING_(x)
+#define GET_IN_DEVICE_INDEX(SND_DEVICE) ((SND_DEVICE) - (SND_DEVICE_IN_BEGIN))
+
struct audio_block_header
{
int reserved;
@@ -368,6 +370,32 @@
[SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = "camcorder-mic",
[SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = "camcorder-mic",
[SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = "camcorder-mic",
+ [SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
+ [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
+};
+
+static struct audio_effect_config \
+ effect_config_table[GET_IN_DEVICE_INDEX(SND_DEVICE_MAX)][EFFECT_COUNT] = {
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)][EFFECT_AEC] = \
+ {TX_VOICE_FLUENCE_PROV2, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)][EFFECT_NS] = \
+ {TX_VOICE_FLUENCE_PROV2, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)][EFFECT_AEC] = \
+ {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)][EFFECT_NS] = \
+ {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)][EFFECT_AEC] = \
+ {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)][EFFECT_NS] = \
+ {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)][EFFECT_AEC] = \
+ {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)][EFFECT_NS] = \
+ {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)][EFFECT_AEC] = \
+ {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)][EFFECT_NS] = \
+ {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x02},
};
/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
@@ -491,6 +519,8 @@
[SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = 61,
[SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = 61,
[SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = 61,
+ [SND_DEVICE_IN_SPEAKER_QMIC_NS] = 129,
+ [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
};
// Platform specific backend bit width table
@@ -627,6 +657,8 @@
{TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT)},
/* For legacy xml file parsing */
{TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
};
static char * backend_tag_table[SND_DEVICE_MAX] = {0};
@@ -1342,6 +1374,8 @@
hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_DMIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_DMIC_TMUS] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_SPEAKER_QMIC_NS] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_MIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = strdup("SLIMBUS_0_TX");
@@ -2067,6 +2101,57 @@
return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
}
+int platform_get_effect_config_data(snd_device_t snd_device,
+ struct audio_effect_config *effect_config,
+ effect_type_t effect_type)
+{
+ int ret = 0;
+
+ if ((snd_device < SND_DEVICE_IN_BEGIN) || (snd_device >= SND_DEVICE_MAX) ||
+ (effect_type <= EFFECT_NONE) || (effect_type >= EFFECT_COUNT)) {
+ ALOGE("%s: Invalid snd_device = %d or effect_type = %d",
+ __func__, snd_device, effect_type);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (effect_config == NULL) {
+ ALOGE("%s: Invalid effect_config", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ALOGV("%s: snd_device = %d module_id = %d",
+ __func__, snd_device, effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type].module_id);
+ *effect_config = effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type];
+
+done:
+ return ret;
+}
+
+int platform_set_effect_config_data(snd_device_t snd_device,
+ struct audio_effect_config effect_config,
+ effect_type_t effect_type)
+{
+ int ret = 0;
+
+ if ((snd_device < SND_DEVICE_IN_BEGIN) || (snd_device >= SND_DEVICE_MAX) ||
+ (effect_type <= EFFECT_NONE) || (effect_type >= EFFECT_COUNT)) {
+ ALOGE("%s: Invalid snd_device = %d or effect_type = %d",
+ __func__, snd_device, effect_type);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ALOGV("%s 0x%x 0x%x 0x%x 0x%x", __func__, effect_config.module_id,
+ effect_config.instance_id, effect_config.param_id,
+ effect_config.param_value);
+ effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type] = effect_config;
+
+done:
+ return ret;
+}
+
void platform_add_operator_specific_device(snd_device_t snd_device,
const char *operator,
const char *mixer_path,
@@ -2865,6 +2950,126 @@
return snd_device;
}
+#ifdef DYNAMIC_ECNS_ENABLED
+static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+ struct stream_in *in __unused,
+ audio_devices_t out_device,
+ audio_devices_t in_device)
+{
+ struct audio_device *adev = my_data->adev;
+ snd_device_t snd_device = SND_DEVICE_NONE;
+
+ if (my_data->fluence_type != FLUENCE_DISABLE) {
+ switch(AUDIO_DEVICE_BIT_IN | in_device) {
+ case AUDIO_DEVICE_IN_BACK_MIC:
+ if (my_data->fluence_in_spkr_mode) {
+ if ((my_data->fluence_type & FLUENCE_PRO_ENABLE) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
+ } else if (((my_data->fluence_type & FLUENCE_PRO_ENABLE) ||
+ (my_data->fluence_type & FLUENCE_ENABLE)) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
+ }
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
+ break;
+ case AUDIO_DEVICE_IN_BUILTIN_MIC:
+ if (((my_data->fluence_type & FLUENCE_PRO_ENABLE) ||
+ (my_data->fluence_type & FLUENCE_ENABLE)) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
+ break;
+ default:
+ ALOGE("%s: Unsupported in_device %#x", __func__, in_device);
+ break;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ }
+
+ return snd_device;
+}
+#else
+static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+ struct stream_in *in,
+ audio_devices_t out_device,
+ audio_devices_t in_device)
+{
+ struct audio_device *adev = my_data->adev;
+ snd_device_t snd_device = SND_DEVICE_NONE;
+
+ if (in->enable_aec &&
+ in->enable_ns) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode &&
+ my_data->fluence_in_voice_comm &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
+ } else {
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
+ }
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if (my_data->fluence_in_voice_comm &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
+ } else {
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
+ }
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
+ } else if (audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
+ snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ } else if (in->enable_aec) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode &&
+ my_data->fluence_in_voice_comm &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
+ } else {
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
+ }
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if (my_data->fluence_in_voice_comm &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
+ } else {
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
+ }
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
+ } else if (audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
+ snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ } else if (in->enable_ns) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode &&
+ my_data->fluence_in_voice_comm &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
+ } else {
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
+ }
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if (my_data->fluence_in_voice_comm &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
+ } else {
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
+ }
+ }
+ }
+
+ return snd_device;
+}
+#endif //DYNAMIC_ECNS_ENABLED
+
snd_device_t platform_get_input_snd_device(void *platform,
struct stream_in *in,
audio_devices_t out_device)
@@ -3091,70 +3296,9 @@
!audio_extn_usb_is_capture_supported())) {
in_device = AUDIO_DEVICE_IN_BACK_MIC;
}
+
if (in) {
- if (in->enable_aec &&
- in->enable_ns) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_in_spkr_mode &&
- my_data->fluence_in_voice_comm &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
- } else {
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
- }
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_in_voice_comm &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
- } else {
- snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
- }
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
- } else if (audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
- snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
- }
- platform_set_echo_reference(adev, true, out_device);
- } else if (in->enable_aec) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_in_spkr_mode &&
- my_data->fluence_in_voice_comm &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
- } else {
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
- }
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_in_voice_comm &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
- } else {
- snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
- }
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
- } else if (audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
- snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
- }
- platform_set_echo_reference(adev, true, out_device);
- } else if (in->enable_ns) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_in_spkr_mode &&
- my_data->fluence_in_voice_comm &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
- } else {
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
- }
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_in_voice_comm &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
- } else {
- snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
- }
- }
- }
+ snd_device = get_snd_device_for_voice_comm(my_data, in, out_device, in_device);
}
} else if (source == AUDIO_SOURCE_DEFAULT) {
goto exit;
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index f6c5a58..a885f27 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -190,6 +190,8 @@
SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE,
SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE,
SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT,
+ SND_DEVICE_IN_SPEAKER_QMIC_NS,
+ SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS,
SND_DEVICE_IN_END,
SND_DEVICE_MAX = SND_DEVICE_IN_END,
@@ -343,6 +345,11 @@
#define HFP_ASM_RX_TX 24
#endif
+#define TX_VOICE_FLUENCE_PROV2 0x10F17
+#define TX_VOICE_DM_FV5_BROADSIDE 0x10F18
+#define TX_VOICE_FV5ECNS_SM 0x10F09
+#define TX_VOICE_FV5ECNS_DM 0x10F0A
+
#define LIB_CSD_CLIENT "libcsd-client.so"
#define LIB_MDM_DETECT "libmdmdetect.so"
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 3cd2b8d..5e5b662 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -27,6 +27,20 @@
#define SAMPLE_RATE_11025 11025
#define sample_rate_multiple(sr, base) ((sr % base)== 0?true:false)
+typedef enum {
+ EFFECT_NONE = 0,
+ EFFECT_AEC,
+ EFFECT_NS,
+ EFFECT_COUNT
+} effect_type_t;
+
+struct audio_effect_config {
+ uint32_t module_id;
+ uint32_t instance_id;
+ uint32_t param_id;
+ uint32_t param_value;
+};
+
struct amp_db_and_gain_table {
float amp;
float db;
@@ -56,6 +70,12 @@
int platform_get_snd_device_index(char *snd_device_index_name);
int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id);
int platform_get_snd_device_acdb_id(snd_device_t snd_device);
+int platform_set_effect_config_data(snd_device_t snd_device,
+ struct audio_effect_config effect_config,
+ effect_type_t effect_type);
+int platform_get_effect_config_data(snd_device_t snd_device,
+ struct audio_effect_config *effect_config,
+ effect_type_t effect_type);
int platform_send_audio_calibration(void *platform, snd_device_t snd_device);
int platform_send_audio_calibration_v2(void *platform, struct audio_usecase *usecase,
int app_type, int sample_rate);
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 0695592..233e120 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -38,6 +38,9 @@
typedef enum {
ROOT,
ACDB,
+ MODULE,
+ AEC,
+ NS,
PCM_ID,
BACKEND_NAME,
CONFIG_PARAMS,
@@ -56,6 +59,9 @@
typedef void (* section_process_fn)(const XML_Char **attr);
static void process_acdb_id(const XML_Char **attr);
+static void process_audio_effect(const XML_Char **attr, effect_type_t effect_type);
+static void process_effect_aec(const XML_Char **attr);
+static void process_effect_ns(const XML_Char **attr);
static void process_pcm_id(const XML_Char **attr);
static void process_backend_name(const XML_Char **attr);
static void process_config_params(const XML_Char **attr);
@@ -71,6 +77,8 @@
static section_process_fn section_table[] = {
[ROOT] = process_root,
[ACDB] = process_acdb_id,
+ [AEC] = process_effect_aec,
+ [NS] = process_effect_ns,
[PCM_ID] = process_pcm_id,
[BACKEND_NAME] = process_backend_name,
[CONFIG_PARAMS] = process_config_params,
@@ -185,6 +193,11 @@
* ...
* ...
* </acdb_ids>
+ * <module_ids>
+ * <device name="???" module_id="???"/>
+ * ...
+ * ...
+ * </module_ids>
* <backend_names>
* <device name="???" backend="???"/>
* ...
@@ -216,6 +229,77 @@
{
}
+static void process_audio_effect(const XML_Char **attr, effect_type_t effect_type)
+{
+ int index;
+ struct audio_effect_config effect_config;
+
+ if (strncmp(attr[0], "name", strlen("name")) != 0) {
+ ALOGE("%s: 'name' not found, no MODULE ID set!", __func__);
+ goto done;
+ }
+
+ index = platform_get_snd_device_index((char *)attr[1]);
+ if (index < 0) {
+ ALOGE("%s: Device %s in platform info xml not found, no MODULE ID set!",
+ __func__, attr[1]);
+ goto done;
+ }
+
+ if (strncmp(attr[2], "module_id", strlen("module_id")) != 0) {
+ ALOGE("%s: Device %s in platform info xml has no module_id, no MODULE ID set!",
+ __func__, attr[2]);
+ goto done;
+ }
+
+ if (strncmp(attr[4], "instance_id", strlen("instance_id")) != 0) {
+ ALOGE("%s: Device %s in platform info xml has no instance_id, no INSTANCE ID set!",
+ __func__, attr[4]);
+ goto done;
+ }
+
+ if (strncmp(attr[6], "param_id", strlen("param_id")) != 0) {
+ ALOGE("%s: Device %s in platform info xml has no param_id, no PARAM ID set!",
+ __func__, attr[6]);
+ goto done;
+ }
+
+ if (strncmp(attr[8], "param_value", strlen("param_value")) != 0) {
+ ALOGE("%s: Device %s in platform info xml has no param_value, no PARAM VALUE set!",
+ __func__, attr[8]);
+ goto done;
+ }
+
+ effect_config = (struct audio_effect_config){strtol((char *)attr[3], NULL, 0),
+ strtol((char *)attr[5], NULL, 0),
+ strtol((char *)attr[7], NULL, 0),
+ strtol((char *)attr[9], NULL, 0)};
+
+
+ if (platform_set_effect_config_data(index, effect_config, effect_type) < 0) {
+ ALOGE("%s: Effect = %d Device %s, MODULE/INSTANCE/PARAM ID %u %u %u %u was not set!",
+ __func__, effect_type, attr[1], effect_config.module_id,
+ effect_config.instance_id, effect_config.param_id,
+ effect_config.param_value);
+ goto done;
+ }
+
+done:
+ return;
+}
+
+static void process_effect_aec(const XML_Char **attr)
+{
+ process_audio_effect(attr, EFFECT_AEC);
+ return;
+}
+
+static void process_effect_ns(const XML_Char **attr)
+{
+ process_audio_effect(attr, EFFECT_NS);
+ return;
+}
+
/* mapping from usecase to pcm dev id */
static void process_pcm_id(const XML_Char **attr)
{
@@ -717,6 +801,8 @@
if (my_data.do_full_parse) {
if (strcmp(tag_name, "acdb_ids") == 0) {
section = ACDB;
+ } else if (strncmp(tag_name, "module_ids", strlen("module_ids")) == 0) {
+ section = MODULE;
} else if (strcmp(tag_name, "pcm_ids") == 0) {
section = PCM_ID;
} else if (strcmp(tag_name, "backend_names") == 0) {
@@ -736,8 +822,9 @@
} else if(strcmp(tag_name, "acdb_metainfo_key") == 0) {
section = ACDB_METAINFO_KEY;
} else if (strcmp(tag_name, "device") == 0) {
- if ((section != ACDB) && (section != BACKEND_NAME) && (section != OPERATOR_SPECIFIC)) {
- ALOGE("device tag only supported for acdb/backend names");
+ if ((section != ACDB) && (section != AEC) && (section != NS) &&
+ (section != BACKEND_NAME) && (section != OPERATOR_SPECIFIC)) {
+ ALOGE("device tag only supported for acdb/backend/aec/ns/operator_specific names");
return;
}
@@ -814,6 +901,20 @@
section_process_fn fn = section_table[MIC_INFO];
fn(attr);
}
+ else if (strncmp(tag_name, "aec", strlen("aec")) == 0) {
+ if (section != MODULE) {
+ ALOGE("aec tag only supported with MODULE section");
+ return;
+ }
+ section = AEC;
+ }
+ else if (strncmp(tag_name, "ns", strlen("ns")) == 0) {
+ if (section != MODULE) {
+ ALOGE("ns tag only supported with MODULE section");
+ return;
+ }
+ section = NS;
+ }
} else {
if(strcmp(tag_name, "config_params") == 0) {
section = CONFIG_PARAMS;
@@ -835,6 +936,12 @@
{
if (strcmp(tag_name, "acdb_ids") == 0) {
section = ROOT;
+ } else if (strncmp(tag_name, "module_ids", strlen("module_ids")) == 0) {
+ section = ROOT;
+ } else if (strncmp(tag_name, "aec", strlen("aec")) == 0) {
+ section = MODULE;
+ } else if (strncmp(tag_name, "ns", strlen("ns")) == 0) {
+ section = MODULE;
} else if (strcmp(tag_name, "pcm_ids") == 0) {
section = ROOT;
} else if (strcmp(tag_name, "backend_names") == 0) {