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.

Change-Id: I9cb2b6cf95d936d770eda47bd87db02534f302b4
This commit is contained in:
Vikram Panduranga 2017-08-03 18:04:55 -07:00
parent ac0c72b3bd
commit df59cae166
13 changed files with 750 additions and 187 deletions

View File

@ -41,6 +41,24 @@
<device name="SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2" acdb_id="10"/>
<device name="SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET" acdb_id="45"/>
</acdb_ids>
<module_ids>
<aec>
<device name="SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS" module_id="0x10F17" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
<device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE" module_id="0x10F18" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
<device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
<device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
<device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
<device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
</aec>
<ns>
<device name="SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS" module_id="0x10F17" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
<device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE" module_id="0x10F18" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
<device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
<device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
<device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
<device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
</ns>
</module_ids>
<bit_width_configs>
<device name="SND_DEVICE_OUT_SPEAKER" bit_width="24"/>
</bit_width_configs>

View File

@ -7,6 +7,7 @@ ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
USE_CUSTOM_AUDIO_POLICY := 1
AUDIO_FEATURE_ENABLED_COMPRESS_CAPTURE := false
AUDIO_FEATURE_ENABLED_COMPRESS_VOIP := true
AUDIO_FEATURE_ENABLED_DYNAMIC_ECNS := false
AUDIO_FEATURE_ENABLED_EXTN_FORMATS := true
AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER := true
AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER := true

View File

@ -37,6 +37,26 @@
<device name="SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_2" acdb_id="152"/>
<device name="SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC" acdb_id="133"/>
</acdb_ids>
<module_ids>
<aec>
<device name="SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS" module_id="0x10F17" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
<device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE" module_id="0x10F18" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
<device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
<device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
<device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
<device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
</aec>
<ns>
<device name="SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS" module_id="0x10F17" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
<device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE" module_id="0x10F18" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
<device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
<device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
<device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
<device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
</ns>
</module_ids>
<bit_width_configs>
<device name="SND_DEVICE_OUT_SPEAKER" bit_width="24"/>
</bit_width_configs>

View File

@ -7,6 +7,7 @@ ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
USE_CUSTOM_AUDIO_POLICY := 1
AUDIO_FEATURE_ENABLED_COMPRESS_CAPTURE := false
AUDIO_FEATURE_ENABLED_COMPRESS_VOIP := false
AUDIO_FEATURE_ENABLED_DYNAMIC_ECNS := false
AUDIO_FEATURE_ENABLED_EXTN_FORMATS := true
AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER := true
AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER := true

View File

@ -368,6 +368,10 @@ ifeq ($(strip $($AUDIO_FEATURE_IP_HDLR_ENABLED)),true)
LOCAL_SRC_FILES += audio_extn/ip_hdlr_intf.c
endif
ifeq ($(strip $($AUDIO_FEATURE_ENABLED_DYNAMIC_ECNS)),true)
LOCAL_CFLAGS += -DDYNAMIC_ECNS_ENABLED
endif
LOCAL_CFLAGS += -Wall -Werror
LOCAL_COPY_HEADERS_TO := mm-audio

View File

@ -803,6 +803,126 @@ static void check_and_set_asrc_mode(struct audio_device *adev,
}
}
#ifdef DYNAMIC_ECNS_ENABLED
static int send_effect_enable_disable_mixer_ctl(struct audio_device *adev,
struct audio_effect_config effect_config,
unsigned int param_value)
{
char mixer_ctl_name[] = "Audio Effect";
struct mixer_ctl *ctl;
long set_values[6];
struct stream_in *in = adev->active_input;
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_device *adev, unsigned int module_id,
int effect_type, unsigned int *param_value)
{
int ret = 0;
struct audio_effect_config other_effect_config;
struct audio_usecase *usecase = NULL;
struct stream_in *in = adev->active_input;
usecase = get_usecase_from_list(adev, in->usecase);
if (!usecase)
return -EINVAL;
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, int effect_type, bool enable)
{
struct audio_effect_config effect_config;
struct audio_usecase *usecase = NULL;
int ret = 0;
unsigned int param_value = 0;
struct stream_in *in = adev->active_input;
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: %d %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(adev, effect_config.module_id, effect_type, &param_value);
if (ret < 0)
return ret;
}
ret = send_effect_enable_disable_mixer_ctl(adev, effect_config, param_value);
return ret;
}
static void check_and_enable_effect(struct audio_device *adev)
{
if (adev->active_input->enable_aec) {
enable_disable_effect(adev, EFFECT_AEC, true);
}
if (adev->active_input->enable_ns &&
adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
enable_disable_effect(adev, EFFECT_NS, true);
}
}
#else
#define enable_disable_effect(x, y, z) ENOSYS
#define check_and_enable_effect(x) ENOSYS
#endif
int pcm_ioctl(struct pcm *pcm, int request, ...)
{
va_list ap;
@ -2110,6 +2230,11 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id)
}
enable_audio_route(adev, usecase);
/* If input stream is already running then effect needs to be
applied on the new input device that's being enabled here. */
if ((in_snd_device != SND_DEVICE_NONE) && (!adev->active_input->standby))
check_and_enable_effect(adev);
if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL) {
/* Enable aanc only if voice call exists */
if (voice_is_call_state_active(adev))
@ -2342,6 +2467,8 @@ int start_input_stream(struct stream_in *in)
}
}
check_and_enable_effect(adev);
done_open:
audio_extn_perf_lock_release(&adev->perf_lock_handle);
ALOGD("%s: exit", __func__);
@ -5091,6 +5218,8 @@ static int add_remove_audio_effect(const struct audio_stream *stream,
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;
@ -5100,14 +5229,22 @@ static int add_remove_audio_effect(const struct audio_stream *stream,
in->enable_aec != enable &&
(memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
in->enable_aec = enable;
if (!in->standby)
select_devices(in->dev, in->usecase);
if (!in->standby) {
if (enable_disable_effect(in->dev, 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) {
if (enable_disable_effect(in->dev, EFFECT_NS, enable) == ENOSYS)
select_devices(in->dev, in->usecase);
} else
select_devices(in->dev, in->usecase);
}
}
pthread_mutex_unlock(&in->dev->lock);
pthread_mutex_unlock(&in->lock);

View File

@ -90,6 +90,19 @@
#define MAX_PERF_LOCK_OPTS 20
#define MAX_STREAM_PROFILE_STR_LEN 32
typedef enum {
EFFECT_NONE = 0,
EFFECT_AEC,
EFFECT_NS,
EFFECT_MAX
} effect_type_t;
struct audio_effect_config {
uint32_t module_id;
uint32_t instance_id;
uint32_t param_id;
uint32_t param_value;
};
#define MAX_MIXER_PATH_LEN 64

View File

@ -165,6 +165,8 @@
#define MAX_CAL_NAME 20
#define MAX_MIME_TYPE_LENGTH 30
#define GET_IN_DEVICE_INDEX(SND_DEVICE) ((SND_DEVICE) - (SND_DEVICE_IN_BEGIN))
char cal_name_info[WCD9XXX_MAX_CAL][MAX_CAL_NAME] = {
[WCD9XXX_ANC_CAL] = "anc_cal",
[WCD9XXX_MBHC_CAL] = "mbhc_cal",
@ -550,6 +552,23 @@ static const char * const device_table[SND_DEVICE_MAX] = {
// Platform specific backend bit width table
static int backend_bit_width_table[SND_DEVICE_MAX] = {0};
static struct audio_effect_config effect_config_table[GET_IN_DEVICE_INDEX(SND_DEVICE_MAX)][EFFECT_MAX] = {
[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,
@ -2885,6 +2904,35 @@ int platform_get_usecase_index(const char *usecase_name)
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_MAX)) {
ALOGE("%s: Invalid snd_device = %d",
__func__, snd_device);
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);
memcpy(effect_config, &effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type],
sizeof(struct audio_effect_config));
done:
return ret;
}
int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
{
int ret = 0;
@ -2903,6 +2951,29 @@ 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_MAX)) {
ALOGE("%s: Invalid snd_device = %d",
__func__, snd_device);
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_set_acdb_metainfo_key(void *platform, char *name, int key)
{
struct meta_key_list *key_info;
@ -3997,6 +4068,148 @@ exit:
return snd_device;
}
#ifdef DYNAMIC_ECNS_ENABLED
static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
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) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(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;
} 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);
}
return snd_device;
}
#else
static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
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 && adev->active_input->enable_aec &&
adev->active_input->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) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(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;
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
} else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
} else if (my_data->fluence_type != FLUENCE_NONE &&
adev->active_input->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) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(my_data->source_mic_type & SOURCE_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;
} else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
} else if (my_data->fluence_type != FLUENCE_NONE &&
adev->active_input->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) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(my_data->source_mic_type & SOURCE_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, audio_devices_t out_device)
{
struct platform_data *my_data = (struct platform_data *)platform;
@ -4222,97 +4435,7 @@ snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_d
if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
in_device = AUDIO_DEVICE_IN_BACK_MIC;
if (adev->active_input) {
if (my_data->fluence_type != FLUENCE_NONE &&
adev->active_input->enable_aec &&
adev->active_input->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) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(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;
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
} else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
} else if (my_data->fluence_type != FLUENCE_NONE &&
adev->active_input->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) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(my_data->source_mic_type & SOURCE_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;
} else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
} else if (my_data->fluence_type != FLUENCE_NONE &&
adev->active_input->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) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(my_data->source_mic_type & SOURCE_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, out_device, in_device);
}
} else if (source == AUDIO_SOURCE_MIC) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&

View File

@ -383,6 +383,11 @@ enum {
#define PLATFORM_MAX_MIC_COUNT "input_mic_max_count"
#define PLATFORM_DEFAULT_MIC_COUNT 2
#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)();

View File

@ -140,6 +140,8 @@
#define MAX_CAL_NAME 20
#define MAX_MIME_TYPE_LENGTH 30
#define GET_IN_DEVICE_INDEX(SND_DEVICE) ((SND_DEVICE) - (SND_DEVICE_IN_BEGIN))
#ifdef DYNAMIC_LOG_ENABLED
extern void log_utils_init(void);
extern void log_utils_deinit(void);
@ -524,6 +526,23 @@ static const char * const device_table[SND_DEVICE_MAX] = {
// Platform specific backend bit width table
static int backend_bit_width_table[SND_DEVICE_MAX] = {0};
static struct audio_effect_config effect_config_table[GET_IN_DEVICE_INDEX(SND_DEVICE_MAX)][EFFECT_MAX] = {
[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,
@ -2646,6 +2665,35 @@ int platform_get_usecase_index(const char *usecase_name)
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_MAX)) {
ALOGE("%s: Invalid snd_device = %d",
__func__, snd_device);
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);
memcpy(effect_config, &effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type],
sizeof(struct audio_effect_config));
done:
return ret;
}
int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
{
int ret = 0;
@ -2664,6 +2712,29 @@ 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_MAX)) {
ALOGE("%s: Invalid snd_device = %d",
__func__, snd_device);
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_set_acdb_metainfo_key(void *platform, char *name, int key)
{
struct meta_key_list *key_info;
@ -3730,6 +3801,148 @@ exit:
return snd_device;
}
#ifdef DYNAMIC_ECNS_ENABLED
static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
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) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(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;
} 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);
}
return snd_device;
}
#else
static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
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 && adev->active_input->enable_aec &&
adev->active_input->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) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(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;
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
} else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
} else if (my_data->fluence_type != FLUENCE_NONE &&
adev->active_input->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) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(my_data->source_mic_type & SOURCE_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;
} else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
} else if (my_data->fluence_type != FLUENCE_NONE &&
adev->active_input->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) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(my_data->source_mic_type & SOURCE_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, audio_devices_t out_device)
{
struct platform_data *my_data = (struct platform_data *)platform;
@ -3969,97 +4182,7 @@ snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_d
if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
in_device = AUDIO_DEVICE_IN_BACK_MIC;
if (adev->active_input) {
if (my_data->fluence_type != FLUENCE_NONE &&
adev->active_input->enable_aec &&
adev->active_input->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) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(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;
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
} else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
} else if (my_data->fluence_type != FLUENCE_NONE &&
adev->active_input->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) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(my_data->source_mic_type & SOURCE_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;
} else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
} else if (my_data->fluence_type != FLUENCE_NONE &&
adev->active_input->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) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_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) &&
(my_data->source_mic_type & SOURCE_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, out_device, in_device);
}
} else if (source == AUDIO_SOURCE_MIC) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&

View File

@ -500,6 +500,11 @@ enum {
#define PLATFORM_MAX_MIC_COUNT "input_mic_max_count"
#define PLATFORM_DEFAULT_MIC_COUNT 2
#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)(bool);

View File

@ -100,6 +100,12 @@ int platform_get_fluence_type(void *platform, char *value, uint32_t len);
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_snd_device_bit_width(snd_device_t snd_device, unsigned int bit_width);
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_get_snd_device_bit_width(snd_device_t snd_device);
int platform_set_acdb_metainfo_key(void *platform, char *name, int key);
int platform_get_meta_info_key_from_list(void *platform, char *mod_name);

View File

@ -52,6 +52,9 @@
typedef enum {
ROOT,
ACDB,
MODULE,
AEC,
NS,
BITWIDTH,
PCM_ID,
BACKEND_NAME,
@ -64,6 +67,9 @@ typedef enum {
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_bit_width(const XML_Char **attr);
static void process_pcm_id(const XML_Char **attr);
static void process_backend_name(const XML_Char **attr);
@ -76,6 +82,8 @@ static void process_acdb_metainfo_key(const XML_Char **attr);
static section_process_fn section_table[] = {
[ROOT] = process_root,
[ACDB] = process_acdb_id,
[AEC] = process_effect_aec,
[NS] = process_effect_ns,
[BITWIDTH] = process_bit_width,
[PCM_ID] = process_pcm_id,
[BACKEND_NAME] = process_backend_name,
@ -102,6 +110,11 @@ static struct platform_info my_data;
* ...
* ...
* </acdb_ids>
* <module_ids>
* <device name="???" module_id="???"/>
* ...
* ...
* </module_ids>
* <backend_names>
* <device name="???" backend="???"/>
* ...
@ -279,6 +292,77 @@ done:
return;
}
static void process_audio_effect(const XML_Char **attr, effect_type_t effect_type)
{
int index;
struct audio_effect_config effect_config;
if (strcmp(attr[0], "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 (strcmp(attr[2], "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 (strcmp(attr[4], "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 (strcmp(attr[6], "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 (strcmp(attr[8], "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 %lu %lu %lu %lu was not set!",
__func__, effect_type, attr[1], strtol((char *)attr[3], NULL, 0),
strtol((char *)attr[5], NULL, 0), strtol((char *)attr[7], NULL, 0),
strtol((char *)attr[9], NULL, 0));
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;
}
static void process_bit_width(const XML_Char **attr)
{
int index;
@ -418,6 +502,8 @@ static void start_tag(void *userdata __unused, const XML_Char *tag_name,
section = BITWIDTH;
} else if (strcmp(tag_name, "acdb_ids") == 0) {
section = ACDB;
} else if (strcmp(tag_name, "module_ids") == 0) {
section = MODULE;
} else if (strcmp(tag_name, "pcm_ids") == 0) {
section = PCM_ID;
} else if (strcmp(tag_name, "backend_names") == 0) {
@ -431,7 +517,8 @@ static void start_tag(void *userdata __unused, const XML_Char *tag_name,
} 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 != BITWIDTH) &&
if ((section != ACDB) && (section != AEC) && (section != NS) &&
(section != BACKEND_NAME) && (section != BITWIDTH) &&
(section != INTERFACE_NAME)) {
ALOGE("device tag only supported for acdb/backend names/bitwitdh/interface names");
return;
@ -465,6 +552,20 @@ static void start_tag(void *userdata __unused, const XML_Char *tag_name,
section_process_fn fn = section_table[section];
fn(attr);
}
else if (strcmp(tag_name, "aec") == 0) {
if (section != MODULE) {
ALOGE("aec tag only supported with MODULE section");
return;
}
section = AEC;
}
else if (strcmp(tag_name, "ns") == 0) {
if (section != MODULE) {
ALOGE("ns tag only supported with MODULE section");
return;
}
section = NS;
}
} else {
ALOGE("%s: unknown caller!", __func__);
}
@ -477,6 +578,12 @@ static void end_tag(void *userdata __unused, const XML_Char *tag_name)
section = ROOT;
} else if (strcmp(tag_name, "acdb_ids") == 0) {
section = ROOT;
} else if (strcmp(tag_name, "module_ids") == 0) {
section = ROOT;
} else if (strcmp(tag_name, "aec") == 0) {
section = MODULE;
} else if (strcmp(tag_name, "ns") == 0) {
section = MODULE;
} else if (strcmp(tag_name, "pcm_ids") == 0) {
section = ROOT;
} else if (strcmp(tag_name, "backend_names") == 0) {