[automerger skipped] Merge "DO NOT MERGE - Merge pie-platform-release (PPRL.190105.001) into master" am: d895cc82f8 -s ours am: 050abd84e0 -s ours
am: 019506dd32 -s ours
am skip reason: subject contains skip directive
Change-Id: I4f05ea84f56a66c5033830ec6dd0d74b294df46e
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_extn/a2dp.c b/hal/audio_extn/a2dp.c
index 671fe59..7c2e4db 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -141,6 +141,7 @@
enc_codec_t *codec_type);
typedef int (*audio_check_a2dp_ready_t)(void);
typedef int (*audio_is_scrambling_enabled_t)(void);
+typedef uint16_t (*audio_get_a2dp_sink_latency_t)(void);
enum A2DP_STATE {
A2DP_STATE_CONNECTED,
@@ -221,6 +222,8 @@
audio_check_a2dp_ready_t audio_check_a2dp_ready;
/* Check if scrambling is enabled on BTSoC */
audio_is_scrambling_enabled_t audio_is_scrambling_enabled;
+ /* Get sink latency from Bluetooth stack */
+ audio_get_a2dp_sink_latency_t audio_get_a2dp_sink_latency;
/* Internal A2DP state identifier */
enum A2DP_STATE bt_state;
/* A2DP codec type configured */
@@ -713,6 +716,8 @@
dlsym(a2dp.bt_lib_handle,"audio_check_a2dp_ready");
a2dp.audio_is_scrambling_enabled = (audio_is_scrambling_enabled_t)
dlsym(a2dp.bt_lib_handle,"audio_is_scrambling_enabled");
+ a2dp.audio_get_a2dp_sink_latency = (audio_get_a2dp_sink_latency_t)
+ dlsym(a2dp.bt_lib_handle,"audio_get_a2dp_sink_latency");
}
}
@@ -1714,7 +1719,7 @@
uint32_t audio_extn_a2dp_get_encoder_latency()
{
- uint32_t latency = 0;
+ uint32_t latency_ms = 0;
int avsync_runtime_prop = 0;
int sbc_offset = 0, aptx_offset = 0, aptxhd_offset = 0,
aac_offset = 0, ldac_offset = 0;
@@ -1731,36 +1736,41 @@
}
}
+ uint32_t slatency_ms = 0;
+ if (a2dp.audio_get_a2dp_sink_latency && a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
+ slatency_ms = a2dp.audio_get_a2dp_sink_latency();
+ }
+
switch (a2dp.bt_encoder_format) {
case ENC_CODEC_TYPE_SBC:
- latency = (avsync_runtime_prop > 0) ? sbc_offset : ENCODER_LATENCY_SBC;
- latency += DEFAULT_SINK_LATENCY_SBC;
+ latency_ms = (avsync_runtime_prop > 0) ? sbc_offset : ENCODER_LATENCY_SBC;
+ latency_ms += (slatency_ms == 0) ? DEFAULT_SINK_LATENCY_SBC : slatency_ms;
break;
case ENC_CODEC_TYPE_APTX:
- latency = (avsync_runtime_prop > 0) ? aptx_offset : ENCODER_LATENCY_APTX;
- latency += DEFAULT_SINK_LATENCY_APTX;
+ latency_ms = (avsync_runtime_prop > 0) ? aptx_offset : ENCODER_LATENCY_APTX;
+ latency_ms += (slatency_ms == 0) ? DEFAULT_SINK_LATENCY_APTX : slatency_ms;
break;
case ENC_CODEC_TYPE_APTX_HD:
- latency = (avsync_runtime_prop > 0) ? aptxhd_offset : ENCODER_LATENCY_APTX_HD;
- latency += DEFAULT_SINK_LATENCY_APTX_HD;
+ latency_ms = (avsync_runtime_prop > 0) ? aptxhd_offset : ENCODER_LATENCY_APTX_HD;
+ latency_ms += (slatency_ms == 0) ? DEFAULT_SINK_LATENCY_APTX_HD : slatency_ms;
break;
case ENC_CODEC_TYPE_AAC:
- latency = (avsync_runtime_prop > 0) ? aac_offset : ENCODER_LATENCY_AAC;
- latency += DEFAULT_SINK_LATENCY_AAC;
+ latency_ms = (avsync_runtime_prop > 0) ? aac_offset : ENCODER_LATENCY_AAC;
+ latency_ms += (slatency_ms == 0) ? DEFAULT_SINK_LATENCY_AAC : slatency_ms;
break;
case ENC_CODEC_TYPE_LDAC:
- latency = (avsync_runtime_prop > 0) ? ldac_offset : ENCODER_LATENCY_LDAC;
- latency += DEFAULT_SINK_LATENCY_LDAC;
+ latency_ms = (avsync_runtime_prop > 0) ? ldac_offset : ENCODER_LATENCY_LDAC;
+ latency_ms += (slatency_ms == 0) ? DEFAULT_SINK_LATENCY_LDAC : slatency_ms;
break;
case ENC_CODEC_TYPE_PCM:
- latency = ENCODER_LATENCY_PCM;
- latency += DEFAULT_SINK_LATENCY_PCM;
+ latency_ms = ENCODER_LATENCY_PCM;
+ latency_ms += DEFAULT_SINK_LATENCY_PCM;
break;
default:
- latency = DEFAULT_ENCODER_LATENCY;
+ latency_ms = DEFAULT_ENCODER_LATENCY;
break;
}
- return latency;
+ return latency_ms;
}
int audio_extn_a2dp_get_parameters(struct str_parms *query,
diff --git a/hal/audio_extn/maxxaudio.c b/hal/audio_extn/maxxaudio.c
index 2fd188d..69c4606 100644
--- a/hal/audio_extn/maxxaudio.c
+++ b/hal/audio_extn/maxxaudio.c
@@ -43,13 +43,15 @@
#define MA_QDSP_PARAM_INIT "maxxaudio_qdsp_initialize"
#define MA_QDSP_PARAM_DEINIT "maxxaudio_qdsp_uninitialize"
+#define MA_QDSP_IS_FEATURE_USED "maxxaudio_qdsp_is_feature_supported"
#define MA_QDSP_SET_LR_SWAP "maxxaudio_qdsp_set_lr_swap"
+#define MA_QDSP_SET_ORIENTATION "maxxaudio_qdsp_set_orientation"
#define MA_QDSP_SET_MODE "maxxaudio_qdsp_set_sound_mode"
#define MA_QDSP_SET_VOL "maxxaudio_qdsp_set_volume"
#define MA_QDSP_SET_VOLT "maxxaudio_qdsp_set_volume_table"
#define MA_QDSP_SET_PARAM "maxxaudio_qdsp_set_parameter"
-#define SUPPORT_DEV "Blackbird"
+#define SUPPORT_DEV "18d1:5033" // Blackbird usbid
#define SUPPORTED_USB 0x01
typedef unsigned int effective_scope_flag_t;
@@ -87,6 +89,8 @@
MA_CMD_VOL,
MA_CMD_SWAP_ENABLE,
MA_CMD_SWAP_DISABLE,
+ MA_CMD_ROTATE_ENABLE,
+ MA_CMD_ROTATE_DISABLE,
MA_CMD_SOFT_MUTE_ENABLE,
MA_CMD_SOFT_MUTE_DISABLE,
} ma_cmd_t;
@@ -120,9 +124,14 @@
typedef bool (*ma_param_deinit_t)(ma_audio_cal_handle_t *);
+typedef bool (*ma_is_feature_used_t)(ma_audio_cal_handle_t, const char *);
+
typedef bool (*ma_set_lr_swap_t)(ma_audio_cal_handle_t,
const struct ma_audio_cal_settings *, bool);
+typedef bool (*ma_set_orientation_t)(ma_audio_cal_handle_t,
+ const struct ma_audio_cal_settings *, int);
+
typedef bool (*ma_set_sound_mode_t)(ma_audio_cal_handle_t,
const struct ma_audio_cal_settings *,
unsigned int);
@@ -144,11 +153,16 @@
pthread_mutex_t lock;
ma_param_init_t ma_param_init;
ma_param_deinit_t ma_param_deinit;
+ ma_is_feature_used_t ma_is_feature_used;
ma_set_lr_swap_t ma_set_lr_swap;
+ ma_set_orientation_t ma_set_orientation;
ma_set_sound_mode_t ma_set_sound_mode;
ma_set_volume_t ma_set_volume;
ma_set_volume_table_t ma_set_volume_table;
ma_set_param_t ma_set_param;
+ bool speaker_lr_swap;
+ bool orientation_used;
+ int dispaly_orientation;
};
ma_audio_cal_handle_t g_ma_audio_cal_handle = NULL;
@@ -171,6 +185,13 @@
audio_cal_settings, swap);
}
+static bool ma_set_orientation_l(
+ const struct ma_audio_cal_settings *audio_cal_settings, int orientation)
+{
+ return my_data->ma_set_orientation(g_ma_audio_cal_handle,
+ audio_cal_settings, orientation);
+}
+
static bool ma_set_sound_mode_l(
const struct ma_audio_cal_settings *audio_cal_settings, int sound_mode)
{
@@ -211,8 +232,10 @@
(usecase->id == USECASE_AUDIO_PLAYBACK_OFFLOAD)) &&
/* support devices */
((usecase->devices & AUDIO_DEVICE_OUT_SPEAKER) ||
- (usecase->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE)))
- /* TODO: enable A2DP/USB when it is ready */
+ (usecase->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
+ (audio_is_usb_out_device(usecase->devices) &&
+ audio_extn_ma_supported_usb())))
+ /* TODO: enable A2DP when it is ready */
return true;
@@ -281,11 +304,14 @@
break;
case MA_CMD_SWAP_ENABLE:
- ret = ma_set_lr_swap_l(&ma_cal, true);
- if (ret)
- ALOGV("ma_set_lr_swap_l enable returned with success.");
- else
- ALOGE("ma_set_lr_swap_l enable returned with error.");
+ /* lr swap only enable for speaker path */
+ if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER) {
+ ret = ma_set_lr_swap_l(&ma_cal, true);
+ if (ret)
+ ALOGV("ma_set_lr_swap_l enable returned with success.");
+ else
+ ALOGE("ma_set_lr_swap_l enable returned with error.");
+ }
break;
case MA_CMD_SWAP_DISABLE:
@@ -296,6 +322,24 @@
ALOGE("ma_set_lr_swap_l disable returned with error.");
break;
+ case MA_CMD_ROTATE_ENABLE:
+ if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER) {
+ ret = ma_set_orientation_l(&ma_cal, my_data->dispaly_orientation);
+ if (ret)
+ ALOGV("ma_set_orientation_l %d returned with success.", my_data->dispaly_orientation);
+ else
+ ALOGE("ma_set_orientation_l %d returned with error.", my_data->dispaly_orientation);
+ }
+ break;
+
+ case MA_CMD_ROTATE_DISABLE:
+ ret = ma_set_orientation_l(&ma_cal, 0);
+ if (ret)
+ ALOGV("ma_set_orientation_l 0 returned with success.");
+ else
+ ALOGE("ma_set_orientation_l 0 returned with error.");
+ break;
+
case MA_CMD_SOFT_MUTE_ENABLE:
if (usecase->id == USECASE_AUDIO_PLAYBACK_LOW_LATENCY) break;
@@ -351,20 +395,20 @@
static void ma_set_swap_l(struct audio_device *adev, bool enable)
{
- // do platform LR swap if it enables on Waves effect
- // but there is no Waves implementation
- if (!my_data) {
- platform_check_and_set_swap_lr_channels(adev, enable);
- ALOGV("%s: maxxaudio isn't initialized.", __func__);
- return;
- }
-
if (enable)
check_and_send_all_audio_cal(adev, MA_CMD_SWAP_ENABLE);
else
check_and_send_all_audio_cal(adev, MA_CMD_SWAP_DISABLE);
}
+static void ma_set_rotation_l(struct audio_device *adev, int orientation)
+{
+ if (orientation != 0)
+ check_and_send_all_audio_cal(adev, MA_CMD_ROTATE_ENABLE);
+ else
+ check_and_send_all_audio_cal(adev, MA_CMD_ROTATE_DISABLE);
+}
+
static void ma_support_usb(bool enable, int card)
{
char path[128];
@@ -374,7 +418,7 @@
char *idd;
if (enable) {
- ret = snprintf(path, sizeof(path), "/proc/asound/card%u/id", card);
+ ret = snprintf(path, sizeof(path), "/proc/asound/card%u/usbid", card);
if (ret < 0) {
ALOGE("%s: failed on snprintf (%d) to path %s\n",
__func__, ret, path);
@@ -394,10 +438,10 @@
idd = strtok(id, "\n");
if (find_sup_dev(idd)) {
- ALOGV("%s: support device name is %s", __func__, id);
+ ALOGV("%s: support usbid is %s", __func__, id);
g_supported_dev |= SUPPORTED_USB;
} else
- ALOGV("%s: device %s isn't found from %s", __func__, id, SUPPORT_DEV);
+ ALOGV("%s: usbid %s isn't found from %s", __func__, id, SUPPORT_DEV);
} else {
g_supported_dev &= ~SUPPORTED_USB;
}
@@ -459,6 +503,18 @@
goto error;
}
+ my_data->ma_is_feature_used = (ma_is_feature_used_t)dlsym(my_data->waves_handle,
+ MA_QDSP_IS_FEATURE_USED);
+ if (!my_data->ma_is_feature_used) {
+ ALOGV("%s: dlsym error %s for ma_is_feature_used", __func__, dlerror());
+ }
+
+ my_data->ma_set_orientation = (ma_set_orientation_t)dlsym(my_data->waves_handle,
+ MA_QDSP_SET_ORIENTATION);
+ if (!my_data->ma_set_orientation) {
+ ALOGV("%s: dlsym error %s for ma_set_orientation", __func__, dlerror());
+ }
+
my_data->ma_set_lr_swap = (ma_set_lr_swap_t)dlsym(my_data->waves_handle,
MA_QDSP_SET_LR_SWAP);
if (!my_data->ma_set_lr_swap) {
@@ -556,6 +612,14 @@
ma_cur_state_table[i].active = false;
}
+ my_data->speaker_lr_swap = false;
+ my_data->orientation_used = false;
+ my_data->dispaly_orientation = 0;
+
+ if (g_ma_audio_cal_handle && my_data->ma_is_feature_used) {
+ my_data->orientation_used = my_data->ma_is_feature_used(g_ma_audio_cal_handle, "SET_ORIENTATION");
+ }
+
return;
error:
@@ -657,6 +721,19 @@
pthread_mutex_lock(&my_data->lock);
if (is_active()) {
+
+ if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (my_data->orientation_used)
+ ma_set_rotation_l(usecase->stream.out->dev, my_data->dispaly_orientation);
+ else
+ ma_set_swap_l(usecase->stream.out->dev, my_data->speaker_lr_swap);
+ } else {
+ if (my_data->orientation_used)
+ ma_set_rotation_l(usecase->stream.out->dev, 0);
+ else
+ ma_set_swap_l(usecase->stream.out->dev, false);
+ }
+
ALOGV("%s: send volume table === Start", __func__);
for (i = 0; i < STREAM_MAX_TYPES; i++)
ALOGV("%s: stream(%d) volume(%f) active(%s)", __func__, i,
@@ -686,16 +763,27 @@
// do LR swap and usb recognition
ret = str_parms_get_int(parms, "rotation", &val);
if (ret >= 0) {
+ if (!my_data) {
+ ALOGV("%s: maxxaudio isn't initialized.", __func__);
+ return;
+ }
+
switch (val) {
case 270:
- ma_set_swap_l(adev, true);
+ my_data->speaker_lr_swap = true;
break;
case 0:
case 90:
case 180:
- ma_set_swap_l(adev, false);
+ my_data->speaker_lr_swap = false;
break;
}
+ my_data->dispaly_orientation = val;
+
+ if (my_data->orientation_used)
+ ma_set_rotation_l(adev, my_data->dispaly_orientation);
+ else
+ ma_set_swap_l(adev, my_data->speaker_lr_swap);
}
// check connect status
diff --git a/hal/audio_extn/sndmonitor.c b/hal/audio_extn/sndmonitor.c
index 2e8fd43..85a8c94 100644
--- a/hal/audio_extn/sndmonitor.c
+++ b/hal/audio_extn/sndmonitor.c
@@ -194,7 +194,8 @@
if ((strncasecmp(card_id, "msm", 3) != 0) &&
(strncasecmp(card_id, "sdm", 3) != 0) &&
(strncasecmp(card_id, "sdc", 3) != 0) &&
- (strncasecmp(card_id, "apq", 3) != 0)) {
+ (strncasecmp(card_id, "apq", 3) != 0) &&
+ (strncasecmp(card_id, "sm8150", 6) != 0)) {
ALOGW("Skip over non-ADSP snd card %s", card_id);
continue;
}
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 73de0ab..3a1877b 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -281,6 +281,10 @@
usecase->out_snd_device,
out->sample_rate,
sample_rate);
+ } else if (out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ audio_extn_a2dp_get_sample_rate(sample_rate);
+ ALOGI("%s: Using sample rate %d for A2DP CoPP", __func__,
+ *sample_rate);
}
app_type_cfg->mode = flags_to_mode(0 /*playback*/, out->flags);
@@ -577,7 +581,7 @@
}
/* Initialize snd card name specific ids and/or backends*/
- if (snd_card_info_init(platform_info_file, my_data,
+ if (platform_info_init(platform_info_file, my_data, false,
&acdb_set_parameters) < 0) {
ALOGE("Failed to find platform_info_file");
goto cleanup;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index f315b5e..00cf661 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -225,7 +225,7 @@
#define AFE_PROXY_CHANNEL_COUNT 2
#define AFE_PROXY_SAMPLING_RATE 48000
-#define AFE_PROXY_PLAYBACK_PERIOD_SIZE 768
+#define AFE_PROXY_PLAYBACK_PERIOD_SIZE 256
#define AFE_PROXY_PLAYBACK_PERIOD_COUNT 4
struct pcm_config pcm_config_afe_proxy_playback = {
@@ -239,7 +239,7 @@
.avail_min = AFE_PROXY_PLAYBACK_PERIOD_SIZE,
};
-#define AFE_PROXY_RECORD_PERIOD_SIZE 768
+#define AFE_PROXY_RECORD_PERIOD_SIZE 256
#define AFE_PROXY_RECORD_PERIOD_COUNT 4
struct pcm_config pcm_config_afe_proxy_record = {
@@ -615,7 +615,7 @@
struct audio_usecase *usecase)
{
snd_device_t snd_device;
- char mixer_path[50];
+ char mixer_path[MIXER_PATH_MAX_LENGTH];
if (usecase == NULL)
return -EINVAL;
@@ -628,8 +628,13 @@
snd_device = usecase->out_snd_device;
audio_extn_utils_send_app_type_cfg(adev, usecase);
audio_extn_utils_send_audio_calibration(adev, usecase);
- strcpy(mixer_path, use_case_table[usecase->id]);
+
+ // we shouldn't truncate mixer_path
+ ALOGW_IF(strlcpy(mixer_path, use_case_table[usecase->id], sizeof(mixer_path))
+ >= sizeof(mixer_path), "%s: truncation on mixer path", __func__);
+ // this also appends to mixer_path
platform_add_backend_name(adev->platform, mixer_path, snd_device);
+
audio_extn_sound_trigger_update_stream_status(usecase, ST_EVENT_STREAM_BUSY);
ALOGD("%s: usecase(%d) apply and update mixer path: %s", __func__, usecase->id, mixer_path);
audio_route_apply_and_update_path(adev->audio_route, mixer_path);
@@ -642,7 +647,7 @@
struct audio_usecase *usecase)
{
snd_device_t snd_device;
- char mixer_path[50];
+ char mixer_path[MIXER_PATH_MAX_LENGTH];
if (usecase == NULL)
return -EINVAL;
@@ -652,9 +657,14 @@
snd_device = usecase->in_snd_device;
else
snd_device = usecase->out_snd_device;
- strcpy(mixer_path, use_case_table[usecase->id]);
+
+ // we shouldn't truncate mixer_path
+ ALOGW_IF(strlcpy(mixer_path, use_case_table[usecase->id], sizeof(mixer_path))
+ >= sizeof(mixer_path), "%s: truncation on mixer path", __func__);
+ // this also appends to mixer_path
platform_add_backend_name(adev->platform, mixer_path, snd_device);
ALOGD("%s: usecase(%d) reset and update mixer path: %s", __func__, usecase->id, mixer_path);
+
audio_route_reset_and_update_path(adev->audio_route, mixer_path);
audio_extn_sound_trigger_update_stream_status(usecase, ST_EVENT_STREAM_FREE);
@@ -797,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
@@ -1022,6 +1173,10 @@
if (usecase->type != PCM_PLAYBACK &&
usecase != uc_info &&
usecase->in_snd_device != snd_device &&
+ ((uc_info->type == VOICE_CALL &&
+ usecase->devices == AUDIO_DEVICE_IN_VOICE_CALL) ||
+ platform_check_backends_match(snd_device,\
+ usecase->in_snd_device)) &&
(usecase->id != USECASE_AUDIO_SPKR_CALIB_TX)) {
ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
__func__, use_case_table[usecase->id],
@@ -1134,8 +1289,14 @@
// audio_channel_in_mask_from_count() does the right conversion to either positional or
// indexed mask
for ( ; channel_count <= channels && num_masks < max_masks; channel_count++) {
- supported_channel_masks[num_masks++] =
+ const audio_channel_mask_t mask =
audio_channel_in_mask_from_count(channel_count);
+ supported_channel_masks[num_masks++] = mask;
+ const audio_channel_mask_t index_mask =
+ audio_channel_mask_for_index_assignment_from_count(channel_count);
+ if (mask != index_mask && num_masks < max_masks) { // ensure index mask added.
+ supported_channel_masks[num_masks++] = index_mask;
+ }
}
}
#ifdef NDEBUG
@@ -1270,6 +1431,44 @@
return false;
}
+struct stream_in *adev_get_active_input(const struct audio_device *adev)
+{
+ struct listnode *node;
+ struct stream_in *last_active_in = NULL;
+
+ /* Get last added active input.
+ * TODO: We may use a priority mechanism to pick highest priority active source */
+ 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) {
+ last_active_in = usecase->stream.in;
+ }
+ }
+
+ return last_active_in;
+}
+
+struct stream_in *get_voice_communication_input(const struct audio_device *adev)
+{
+ struct listnode *node;
+
+ /* First check active inputs with voice communication source and then
+ * any input if audio mode is in communication */
+ 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 &&
+ usecase->stream.in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
+ return usecase->stream.in;
+ }
+ }
+ if (adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
+ return adev_get_active_input(adev);
+ }
+ return NULL;
+}
+
int select_devices(struct audio_device *adev,
audio_usecase_t uc_id)
{
@@ -1294,7 +1493,9 @@
(usecase->type == PCM_HFP_CALL)) {
out_snd_device = platform_get_output_snd_device(adev->platform,
usecase->stream.out->devices);
- in_snd_device = platform_get_input_snd_device(adev->platform, usecase->stream.out->devices);
+ in_snd_device = platform_get_input_snd_device(adev->platform,
+ NULL,
+ usecase->stream.out->devices);
usecase->devices = usecase->stream.out->devices;
} else {
/*
@@ -1326,6 +1527,7 @@
in_snd_device = SND_DEVICE_NONE;
if (out_snd_device == SND_DEVICE_NONE) {
struct stream_out *voip_out = adev->primary_output;
+ struct stream_in *voip_in = get_voice_communication_input(adev);
out_snd_device = platform_get_output_snd_device(adev->platform,
usecase->stream.out->devices);
@@ -1333,11 +1535,8 @@
if (voip_usecase)
voip_out = voip_usecase->stream.out;
- if (usecase->stream.out == voip_out &&
- adev->active_input &&
- (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
- adev->mode == AUDIO_MODE_IN_COMMUNICATION)) {
- select_devices(adev, adev->active_input->usecase);
+ if (usecase->stream.out == voip_out && voip_in != NULL) {
+ select_devices(adev, voip_in->usecase);
}
}
} else if (usecase->type == PCM_CAPTURE) {
@@ -1345,9 +1544,9 @@
out_snd_device = SND_DEVICE_NONE;
if (in_snd_device == SND_DEVICE_NONE) {
audio_devices_t out_device = AUDIO_DEVICE_NONE;
- if (adev->active_input &&
- (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
- adev->mode == AUDIO_MODE_IN_COMMUNICATION)) {
+ struct stream_in *voip_in = get_voice_communication_input(adev);
+
+ if (voip_in != NULL) {
struct audio_usecase *voip_usecase = get_usecase_from_list(adev,
USECASE_AUDIO_PLAYBACK_VOIP);
@@ -1361,7 +1560,9 @@
out_device = adev->primary_output->devices;
}
}
- in_snd_device = platform_get_input_snd_device(adev->platform, out_device);
+ in_snd_device = platform_get_input_snd_device(adev->platform,
+ usecase->stream.in,
+ out_device);
}
}
}
@@ -1487,6 +1688,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
@@ -1518,17 +1724,6 @@
ALOGV("%s: enter: usecase(%d: %s)", __func__,
in->usecase, use_case_table[in->usecase]);
- if (adev->active_input) {
- if (adev->active_input->usecase == in->usecase) {
- adev->active_input = NULL;
- } else {
- ALOGW("%s adev->active_input->usecase %s, v/s in->usecase %s",
- __func__,
- use_case_table[adev->active_input->usecase],
- use_case_table[in->usecase]);
- }
- }
-
uc_info = get_usecase_from_list(adev, in->usecase);
if (uc_info == NULL) {
ALOGE("%s: Could not find the usecase (%d) in the list",
@@ -1586,7 +1781,6 @@
goto error_config;
}
- adev->active_input = in;
uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
uc_info->id = in->usecase;
uc_info->type = PCM_CAPTURE;
@@ -1664,6 +1858,7 @@
}
}
register_in_stream(in);
+ check_and_enable_effect(adev);
audio_streaming_hint_end();
audio_extn_perf_lock_release();
ALOGV("%s: exit", __func__);
@@ -1676,7 +1871,6 @@
audio_extn_perf_lock_release();
error_config:
- adev->active_input = NULL;
ALOGW("%s: exit: status(%d)", __func__, ret);
return ret;
}
@@ -1727,15 +1921,15 @@
struct stream_out *out = (struct stream_out *) context;
struct listnode *item;
- out->offload_state = OFFLOAD_STATE_IDLE;
- out->playback_started = 0;
-
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
set_sched_policy(0, SP_FOREGROUND);
prctl(PR_SET_NAME, (unsigned long)"Offload Callback", 0, 0, 0);
ALOGV("%s", __func__);
+
lock_output_stream(out);
+ out->offload_state = OFFLOAD_STATE_IDLE;
+ out->playback_started = 0;
for (;;) {
struct offload_cmd *cmd = NULL;
stream_callback_event_t event;
@@ -1994,6 +2188,9 @@
audio_low_latency_hint_end();
}
+ if (out->usecase == USECASE_INCALL_MUSIC_UPLINK)
+ voice_set_device_mute_flag(adev, false);
+
/* 1. Get and set stream specific mixer controls */
disable_audio_route(adev, uc_info);
@@ -2117,6 +2314,9 @@
audio_extn_extspk_update(adev->extspk);
+ if (out->usecase == USECASE_INCALL_MUSIC_UPLINK)
+ voice_set_device_mute_flag(adev, true);
+
ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)",
__func__, adev->snd_card, out->pcm_device_id, out->config.format);
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
@@ -2546,10 +2746,13 @@
// otherwise audio is no longer played on the new usb devices.
// By forcing the stream in standby, the usb stack refcount drops to 0
// and the driver is closed.
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD && val == AUDIO_DEVICE_NONE &&
+ if (val == AUDIO_DEVICE_NONE &&
audio_is_usb_out_device(out->devices)) {
- ALOGD("%s() putting the usb device in standby after disconnection", __func__);
- out_standby_l(&out->stream.common);
+ if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ ALOGD("%s() putting the usb device in standby after disconnection", __func__);
+ out_standby_l(&out->stream.common);
+ }
+ val = AUDIO_DEVICE_OUT_SPEAKER;
}
pthread_mutex_lock(&adev->lock);
@@ -2712,7 +2915,7 @@
struct str_parms *reply,
audio_channel_mask_t *supported_channel_masks) {
int ret = -1;
- char value[256];
+ char value[ARRAY_SIZE(channels_name_to_enum_table) * 32 /* max channel name size */];
bool first = true;
size_t i, j;
@@ -3902,6 +4105,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;
@@ -3926,14 +4131,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);
@@ -4153,6 +4362,21 @@
return ret;
}
+static int in_set_microphone_direction(const struct audio_stream_in *stream,
+ audio_microphone_direction_t dir) {
+ (void)stream;
+ (void)dir;
+ ALOGVV("%s", __func__);
+ return -ENOSYS;
+}
+
+static int in_set_microphone_field_dimension(const struct audio_stream_in *stream, float zoom) {
+ (void)stream;
+ (void)zoom;
+ ALOGVV("%s", __func__);
+ return -ENOSYS;
+}
+
static int adev_open_output_stream(struct audio_hw_device *dev,
audio_io_handle_t handle,
audio_devices_t devices,
@@ -5030,7 +5254,10 @@
devices,
flags,
source);
- ALOGV("%s: enter", __func__);
+ ALOGV("%s: enter: flags %#x, is_usb_dev %d, may_use_hifi_record %d,"
+ " sample_rate %u, channel_mask %#x, format %#x",
+ __func__, flags, is_usb_dev, may_use_hifi_record,
+ config->sample_rate, config->channel_mask, config->format);
*stream_in = NULL;
if (is_usb_dev && !is_usb_ready(adev, false /* is_playback */)) {
@@ -5077,6 +5304,8 @@
in->stream.get_input_frames_lost = in_get_input_frames_lost;
in->stream.get_capture_position = in_get_capture_position;
in->stream.get_active_microphones = in_get_active_microphones;
+ in->stream.set_microphone_direction = in_set_microphone_direction;
+ in->stream.set_microphone_field_dimension = in_set_microphone_field_dimension;
in->device = devices;
in->source = source;
@@ -5085,7 +5314,7 @@
in->capture_handle = handle;
in->flags = flags;
- ALOGV("%s: source = %d, config->channel_mask = %d", __func__, source, config->channel_mask);
+ ALOGV("%s: source %d, config->channel_mask %#x", __func__, source, config->channel_mask);
if (source == AUDIO_SOURCE_VOICE_UPLINK ||
source == AUDIO_SOURCE_VOICE_DOWNLINK) {
/* Force channel config requested to mono if incall
@@ -5401,13 +5630,10 @@
uc_info.id = audio_usecase;
uc_info.type = usecase_type;
if (dir) {
- adev->active_input = ∈
memset(&in, 0, sizeof(in));
in.device = audio_device;
in.source = AUDIO_SOURCE_VOICE_COMMUNICATION;
uc_info.stream.in = ∈
- } else {
- adev->active_input = NULL;
}
memset(&out, 0, sizeof(out));
out.devices = audio_device; /* only field needed in select_devices */
@@ -5441,7 +5667,6 @@
list_remove(&uc_info.list);
}
}
- adev->active_input = NULL; /* restore adev state */
return 0;
}
@@ -5646,7 +5871,6 @@
/* Set the default route before the PCM stream is opened */
pthread_mutex_lock(&adev->lock);
adev->mode = AUDIO_MODE_NORMAL;
- adev->active_input = NULL;
adev->primary_output = NULL;
adev->bluetooth_nrec = true;
adev->acdb_settings = TTY_MODE_OFF;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 0b3b028..cc24c45 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -340,7 +340,6 @@
pthread_mutex_t lock; /* see note below on mutex acquisition order */
struct mixer *mixer;
audio_mode_t mode;
- struct stream_in *active_input;
struct stream_out *primary_output;
struct stream_out *voice_tx_output;
struct stream_out *current_call_output;
@@ -357,6 +356,7 @@
bool enable_voicerx;
bool enable_hfp;
bool mic_break_enabled;
+ bool use_voice_device_mute;
int snd_card;
void *platform;
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 750d4e5..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,
@@ -1132,7 +1162,8 @@
/* Initialize ACDB and PCM ID's */
strlcpy(platform_info_path, PLATFORM_INFO_XML_PATH, MAX_MIXER_XML_PATH);
resolve_config_file(platform_info_path);
- platform_info_init(platform_info_path, my_data);
+ platform_info_init(platform_info_path, my_data,
+ true, &platform_set_parameters);
my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
if (my_data->acdb_handle == NULL) {
@@ -1415,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,
@@ -1498,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)
@@ -1651,6 +1732,7 @@
struct audio_device *adev = my_data->adev;
struct mixer_ctl *ctl;
const char *mixer_ctl_name = "Voice Rx Gain";
+ const char *mute_mixer_ctl_name = "Voice Rx Device Mute";
int vol_index = 0, ret = 0;
uint32_t set_values[ ] = {0,
ALL_SESSION_VSID,
@@ -1661,7 +1743,6 @@
// But this values don't changed in kernel. So, below change is need.
vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, my_data->max_vol_index);
set_values[0] = vol_index;
-
ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
if (!ctl) {
ALOGE("%s: Could not get ctl for mixer cmd - %s",
@@ -1671,6 +1752,23 @@
ALOGV("Setting voice volume index: %d", set_values[0]);
ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+ // Send mute command in case volume index is max since indexes are inverted
+ // for mixer controls.
+ if (vol_index == my_data->max_vol_index) {
+ set_values[0] = 1;
+ }
+ else {
+ set_values[0] = 0;
+ }
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, mute_mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mute_mixer_ctl_name);
+ return -EINVAL;
+ }
+ ALOGV("%s: Setting RX Device Mute to: %d", __func__, set_values[0]);
+ mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
return ret;
}
@@ -1780,10 +1878,6 @@
audio_mode_t mode = adev->mode;
snd_device_t snd_device = SND_DEVICE_NONE;
- audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
- AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
- int channel_count = popcount(channel_mask);
-
ALOGV("%s: enter: output devices(%#x)", __func__, devices);
if (devices == AUDIO_DEVICE_NONE ||
devices & AUDIO_DEVICE_BIT_IN) {
@@ -1916,21 +2010,157 @@
return snd_device;
}
-snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_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)
{
struct platform_data *my_data = (struct platform_data *)platform;
struct audio_device *adev = my_data->adev;
- audio_source_t source = (adev->active_input == NULL) ?
- AUDIO_SOURCE_DEFAULT : adev->active_input->source;
-
- audio_mode_t mode = adev->mode;
- audio_devices_t in_device = ((adev->active_input == NULL) ?
- AUDIO_DEVICE_NONE : adev->active_input->device)
- & ~AUDIO_DEVICE_BIT_IN;
- audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
- AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
+ audio_mode_t mode = adev->mode;
snd_device_t snd_device = SND_DEVICE_NONE;
- int channel_count = popcount(channel_mask);
+
+ if (in == NULL) {
+ in = adev_get_active_input(adev);
+ }
+
+ audio_source_t source = (in == NULL) ? AUDIO_SOURCE_DEFAULT : in->source;
+ audio_devices_t in_device =
+ ((in == NULL) ? AUDIO_DEVICE_NONE : in->device) & ~AUDIO_DEVICE_BIT_IN;
+ audio_channel_mask_t channel_mask = (in == NULL) ? AUDIO_CHANNEL_IN_MONO : in->channel_mask;
+ int channel_count = audio_channel_count_from_in_mask(channel_mask);
ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
__func__, out_device, in_device);
@@ -2025,7 +2255,7 @@
if (channel_count == 2) {
snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
adev->acdb_settings |= DMIC_FLAG;
- } else if (adev->active_input->enable_ns)
+ } else if (in->enable_ns)
snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
else if (my_data->fluence_type != FLUENCE_NONE &&
my_data->fluence_in_voice_rec) {
@@ -2039,85 +2269,10 @@
(mode == AUDIO_MODE_IN_COMMUNICATION)) {
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) {
- 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 &&
- 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) {
- 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 &&
- 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) {
- 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);
+
+ if (in) {
+ 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/msm8960/platform.c b/hal/msm8960/platform.c
index bd8c41c..be2b95e 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -729,21 +729,24 @@
return snd_device;
}
-snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
+snd_device_t platform_get_input_snd_device(void *platform,
+ struct stream_in *in,
+ audio_devices_t out_device)
{
struct platform_data *my_data = (struct platform_data *)platform;
struct audio_device *adev = my_data->adev;
- audio_source_t source = (adev->active_input == NULL) ?
- AUDIO_SOURCE_DEFAULT : adev->active_input->source;
-
- audio_mode_t mode = adev->mode;
- audio_devices_t in_device = ((adev->active_input == NULL) ?
- AUDIO_DEVICE_NONE : adev->active_input->device)
- & ~AUDIO_DEVICE_BIT_IN;
- audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
- AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
+ audio_mode_t mode = adev->mode;
snd_device_t snd_device = SND_DEVICE_NONE;
+ if (in == NULL) {
+ in = adev_get_active_input(adev);
+ }
+
+ audio_source_t source = (in == NULL) ? AUDIO_SOURCE_DEFAULT : in->source;
+ audio_devices_t in_device =
+ ((in == NULL) ? AUDIO_DEVICE_NONE : in->device) & ~AUDIO_DEVICE_BIT_IN;
+ audio_channel_mask_t channel_mask = (in == NULL) ? AUDIO_CHANNEL_IN_MONO : in->channel_mask;
+
ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
__func__, out_device, in_device);
if ((out_device != AUDIO_DEVICE_NONE) && voice_is_in_call(adev)) {
@@ -827,8 +830,8 @@
mode == AUDIO_MODE_IN_COMMUNICATION) {
if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
in_device = AUDIO_DEVICE_IN_BACK_MIC;
- if (adev->active_input) {
- if (adev->active_input->enable_aec) {
+ if (in) {
+ if (in != NULL && in->enable_aec) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
} else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 5a36f0c..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;
@@ -125,6 +127,10 @@
uint32_t sampling_rate;
uint32_t cal_type;
uint32_t module_id;
+#ifdef PLATFORM_SM8150
+ uint16_t instance_id;
+ uint16_t reserved;
+#endif
uint32_t param_id;
} acdb_audio_cal_cfg_t;
@@ -364,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 */
@@ -487,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
@@ -623,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};
@@ -911,7 +947,9 @@
if (cal.dev_id) {
if (audio_is_input_device(cal.dev_id)) {
- cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id);
+ // FIXME: why pass an input device whereas
+ // platform_get_input_snd_device() expects as an output device?
+ cal.snd_dev_id = platform_get_input_snd_device(platform, NULL, cal.dev_id);
} else {
cal.snd_dev_id = platform_get_output_snd_device(platform, cal.dev_id);
}
@@ -1336,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");
@@ -1649,7 +1689,8 @@
my_data->declared_mic_count = 0;
/* Initialize platform specific ids and/or backends*/
- platform_info_init(platform_info_file, my_data);
+ platform_info_init(platform_info_file, my_data,
+ true, &platform_set_parameters);
ALOGD("%s: Loading mixer file: %s", __func__, mixer_xml_file);
adev->audio_route = audio_route_init(snd_card_num, mixer_xml_file);
@@ -2060,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,
@@ -2512,7 +2604,7 @@
__func__, mixer_ctl_name);
return -EINVAL;
}
- ALOGV("Setting voice mute state: %d", state);
+ ALOGV("%s: Setting voice mute state: %d", __func__, state);
mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
if (my_data->csd != NULL) {
@@ -2858,24 +2950,148 @@
return snd_device;
}
-snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_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)
{
struct platform_data *my_data = (struct platform_data *)platform;
struct audio_device *adev = my_data->adev;
- audio_source_t source = (adev->active_input == NULL) ?
- AUDIO_SOURCE_DEFAULT : adev->active_input->source;
-
- audio_mode_t mode = adev->mode;
- audio_devices_t in_device = ((adev->active_input == NULL) ?
- AUDIO_DEVICE_NONE : adev->active_input->device)
- & ~AUDIO_DEVICE_BIT_IN;
- audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
- AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
+ audio_mode_t mode = adev->mode;
snd_device_t snd_device = SND_DEVICE_NONE;
- int channel_count = popcount(channel_mask);
+
+ if (in == NULL) {
+ in = adev_get_active_input(adev);
+ }
+
+ audio_source_t source = (in == NULL) ? AUDIO_SOURCE_DEFAULT : in->source;
+ audio_devices_t in_device =
+ ((in == NULL) ? AUDIO_DEVICE_NONE : in->device) & ~AUDIO_DEVICE_BIT_IN;
+ audio_channel_mask_t channel_mask = (in == NULL) ? AUDIO_CHANNEL_IN_MONO : in->channel_mask;
+ int channel_count = audio_channel_count_from_in_mask(channel_mask);
ALOGV("%s: enter: out_device(%#x) in_device(%#x) channel_count (%d) channel_mask (0x%x)",
__func__, out_device, in_device, channel_count, channel_mask);
+
if ((out_device != AUDIO_DEVICE_NONE) && (voice_is_in_call(adev) ||
audio_extn_hfp_is_active(adev))) {
if (adev->voice.tty_mode != TTY_MODE_OFF) {
@@ -3004,20 +3220,20 @@
if (my_data->fluence_in_voice_rec && channel_count == 1) {
if ((my_data->fluence_type == FLUENCE_PRO_ENABLE) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
- if (adev->active_input->enable_aec)
+ if (in->enable_aec)
snd_device = SND_DEVICE_IN_HANDSET_QMIC_AEC;
else
snd_device = SND_DEVICE_IN_HANDSET_QMIC;
} else if ((my_data->fluence_type == FLUENCE_PRO_ENABLE) &&
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
- if (adev->active_input->enable_aec)
+ if (in->enable_aec)
snd_device = SND_DEVICE_IN_HANDSET_TMIC_AEC;
else
snd_device = SND_DEVICE_IN_HANDSET_TMIC;
} else if (((my_data->fluence_type == FLUENCE_PRO_ENABLE) ||
(my_data->fluence_type == FLUENCE_ENABLE)) &&
(my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- if (adev->active_input->enable_aec)
+ if (in->enable_aec)
snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
else
snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
@@ -3034,14 +3250,14 @@
snd_device = SND_DEVICE_IN_QUAD_MIC;
}
if (snd_device == SND_DEVICE_NONE) {
- if (adev->active_input->enable_aec) {
- if (adev->active_input->enable_ns) {
+ if (in->enable_aec) {
+ if (in->enable_ns) {
snd_device = SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS;
} else {
snd_device = SND_DEVICE_IN_VOICE_REC_MIC_AEC;
}
platform_set_echo_reference(adev, true, out_device);
- } else if (adev->active_input->enable_ns) {
+ } else if (in->enable_ns) {
snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
} else {
snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
@@ -3080,70 +3296,9 @@
!audio_extn_usb_is_capture_supported())) {
in_device = AUDIO_DEVICE_IN_BACK_MIC;
}
- if (adev->active_input) {
- if (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 &&
- 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 (adev->active_input->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 (adev->active_input->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;
- }
- }
- }
+
+ if (in) {
+ snd_device = get_snd_device_for_voice_comm(my_data, in, out_device, in_device);
}
} else if (source == AUDIO_SOURCE_DEFAULT) {
goto exit;
@@ -4743,7 +4898,7 @@
size_t actual_mic_count = 0;
snd_device_t active_input_snd_device =
- platform_get_input_snd_device(platform, usecase->stream.in->device);
+ platform_get_input_snd_device(platform, usecase->stream.in, AUDIO_DEVICE_NONE);
if (active_input_snd_device == SND_DEVICE_NONE) {
ALOGI("%s: No active microphones found", __func__);
goto end;
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 1a7d2c3..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);
@@ -82,7 +102,9 @@
int platform_get_sample_rate(void *platform, uint32_t *rate);
int platform_set_device_mute(void *platform, bool state, char *dir);
snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices);
-snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device);
+snd_device_t platform_get_input_snd_device(void *platform,
+ struct stream_in *in,
+ audio_devices_t out_device);
int platform_set_hdmi_channels(void *platform, int channel_count);
int platform_edid_get_max_channels(void *platform);
void platform_add_operator_specific_device(snd_device_t snd_device,
@@ -117,11 +139,11 @@
bool platform_sound_trigger_usecase_needs_event(audio_usecase_t uc_id);
-/* From platform_info.c */
-int platform_info_init(const char *filename, void *);
-
typedef int (*set_parameters_fn)(void *platform, struct str_parms *parms);
-int snd_card_info_init(const char *filename, void *, set_parameters_fn);
+
+/* From platform_info.c */
+int platform_info_init(const char *filename, void *,
+ bool do_full_parse, set_parameters_fn);
int platform_get_usecase_index(const char * usecase);
int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id);
@@ -182,4 +204,8 @@
int platform_get_usb_service_interval(void *platform,
bool playback,
unsigned long *service_interval);
+
+/* callback functions from platform to common audio HAL */
+struct stream_in *adev_get_active_input(const struct audio_device *adev);
+
#endif // AUDIO_PLATFORM_API_H
diff --git a/hal/platform_info.c b/hal/platform_info.c
index f5fbe3f..233e120 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -25,10 +25,22 @@
#include "platform_api.h"
#include <platform.h>
#include <math.h>
+#include <pthread.h>
+
+/*
+ * Mandatory microphone characteristics include: device_id, type, address, location, group,
+ * index_in_the_group, directionality, num_frequency_responses, frequencies and responses.
+ * MANDATORY_MICROPHONE_CHARACTERISTICS should be updated when mandatory microphone
+ * characteristics are changed.
+ */
+#define MANDATORY_MICROPHONE_CHARACTERISTICS (1 << 10) - 1
typedef enum {
ROOT,
ACDB,
+ MODULE,
+ AEC,
+ NS,
PCM_ID,
BACKEND_NAME,
CONFIG_PARAMS,
@@ -47,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);
@@ -62,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,
@@ -74,17 +91,19 @@
[ACDB_METAINFO_KEY] = process_acdb_metainfo_key,
};
-static set_parameters_fn set_parameters = &platform_set_parameters;
-
static section_t section;
struct platform_info {
+ pthread_mutex_t lock;
bool do_full_parse;
void *platform;
struct str_parms *kvpairs;
+ set_parameters_fn set_parameters;
};
-static struct platform_info my_data = {true, NULL, NULL};
+static struct platform_info my_data = {PTHREAD_MUTEX_INITIALIZER,
+ true, NULL, NULL,
+ &platform_set_parameters};
struct audio_string_to_enum {
const char* name;
@@ -145,17 +164,6 @@
AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DEFAULT),
};
-enum {
- AUDIO_MICROPHONE_CHARACTERISTIC_NONE = 0u, // 0x0
- AUDIO_MICROPHONE_CHARACTERISTIC_SENSITIVITY = 1u, // 0x1
- AUDIO_MICROPHONE_CHARACTERISTIC_MAX_SPL = 2u, // 0x2
- AUDIO_MICROPHONE_CHARACTERISTIC_MIN_SPL = 4u, // 0x4
- AUDIO_MICROPHONE_CHARACTERISTIC_ORIENTATION = 8u, // 0x8
- AUDIO_MICROPHONE_CHARACTERISTIC_GEOMETRIC_LOCATION = 16u, // 0x10
- AUDIO_MICROPHONE_CHARACTERISTIC_ALL = 31u, /* ((((SENSITIVITY | MAX_SPL) | MIN_SPL)
- | ORIENTATION) | GEOMETRIC_LOCATION) */
-};
-
static bool find_enum_by_string(const struct audio_string_to_enum * table, const char * name,
int32_t len, unsigned int *value)
{
@@ -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)
{
@@ -418,7 +502,7 @@
}
str_parms_add_str(my_data.kvpairs, (char*)attr[1], (char*)attr[3]);
- set_parameters(my_data.platform, my_data.kvpairs);
+ my_data.set_parameters(my_data.platform, my_data.kvpairs);
done:
return;
}
@@ -458,221 +542,165 @@
static void process_microphone_characteristic(const XML_Char **attr) {
struct audio_microphone_characteristic_t microphone;
- uint32_t curIdx = 0;
+ uint32_t index = 0;
+ uint32_t found_mandatory_characteristics = 0;
+ uint32_t num_frequencies = 0;
+ uint32_t num_responses = 0;
+ microphone.sensitivity = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN;
+ microphone.max_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
+ microphone.min_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
+ microphone.orientation.x = 0.0f;
+ microphone.orientation.y = 0.0f;
+ microphone.orientation.z = 0.0f;
+ microphone.geometric_location.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
+ microphone.geometric_location.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
+ microphone.geometric_location.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
- if (strcmp(attr[curIdx++], "valid_mask")) {
- ALOGE("%s: valid_mask not found", __func__);
- goto done;
- }
- uint32_t valid_mask = atoi(attr[curIdx++]);
-
- if (strcmp(attr[curIdx++], "device_id")) {
- ALOGE("%s: device_id not found", __func__);
- goto done;
- }
- if (strlen(attr[curIdx]) > AUDIO_MICROPHONE_ID_MAX_LEN) {
- ALOGE("%s: device_id %s is too long", __func__, attr[curIdx]);
- goto done;
- }
- strcpy(microphone.device_id, attr[curIdx++]);
-
- if (strcmp(attr[curIdx++], "type")) {
- ALOGE("%s: device not found", __func__);
- goto done;
- }
- if (!find_enum_by_string(device_in_types, (char*)attr[curIdx++],
- ARRAY_SIZE(device_in_types), µphone.device)) {
- ALOGE("%s: type %s in %s not found!",
- __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
- goto done;
- }
-
- if (strcmp(attr[curIdx++], "address")) {
- ALOGE("%s: address not found", __func__);
- goto done;
- }
- if (strlen(attr[curIdx]) > AUDIO_DEVICE_MAX_ADDRESS_LEN) {
- ALOGE("%s, address %s is too long", __func__, attr[curIdx]);
- goto done;
- }
- strcpy(microphone.address, attr[curIdx++]);
- if (strlen(microphone.address) == 0) {
- // If the address is empty, populate the address according to device type.
- if (microphone.device == AUDIO_DEVICE_IN_BUILTIN_MIC) {
- strcpy(microphone.address, AUDIO_BOTTOM_MICROPHONE_ADDRESS);
- } else if (microphone.device == AUDIO_DEVICE_IN_BACK_MIC) {
- strcpy(microphone.address, AUDIO_BACK_MICROPHONE_ADDRESS);
- }
- }
-
- if (strcmp(attr[curIdx++], "location")) {
- ALOGE("%s: location not found", __func__);
- goto done;
- }
- if (!find_enum_by_string(mic_locations, (char*)attr[curIdx++],
- AUDIO_MICROPHONE_LOCATION_CNT, µphone.location)) {
- ALOGE("%s: location %s in %s not found!",
- __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
- goto done;
- }
-
- if (strcmp(attr[curIdx++], "group")) {
- ALOGE("%s: group not found", __func__);
- goto done;
- }
- microphone.group = atoi(attr[curIdx++]);
-
- if (strcmp(attr[curIdx++], "index_in_the_group")) {
- ALOGE("%s: index_in_the_group not found", __func__);
- goto done;
- }
- microphone.index_in_the_group = atoi(attr[curIdx++]);
-
- if (strcmp(attr[curIdx++], "directionality")) {
- ALOGE("%s: directionality not found", __func__);
- goto done;
- }
- if (!find_enum_by_string(mic_directionalities, (char*)attr[curIdx++],
- AUDIO_MICROPHONE_DIRECTIONALITY_CNT, µphone.directionality)) {
- ALOGE("%s: directionality %s in %s not found!",
- __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
- goto done;
- }
-
- if (strcmp(attr[curIdx++], "num_frequency_responses")) {
- ALOGE("%s: num_frequency_responses not found", __func__);
- goto done;
- }
- microphone.num_frequency_responses = atoi(attr[curIdx++]);
- if (microphone.num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
- ALOGE("%s: num_frequency_responses is too large", __func__);
- goto done;
- }
- if (microphone.num_frequency_responses > 0) {
- if (strcmp(attr[curIdx++], "frequencies")) {
- ALOGE("%s: frequencies not found", __func__);
- goto done;
- }
- char *token = strtok((char *)attr[curIdx++], " ");
- uint32_t num_frequencies = 0;
- while (token) {
- microphone.frequency_responses[0][num_frequencies++] = atof(token);
- if (num_frequencies > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
- ALOGE("%s: num %u of frequency is too large", __func__, num_frequencies);
+ while (attr[index] != NULL) {
+ const char *attribute = attr[index++];
+ char value[strlen(attr[index]) + 1];
+ strcpy(value, attr[index++]);
+ if (strcmp(attribute, "device_id") == 0) {
+ if (strlen(value) > AUDIO_MICROPHONE_ID_MAX_LEN) {
+ ALOGE("%s: device_id %s is too long", __func__, value);
goto done;
}
- token = strtok(NULL, " ");
- }
-
- if (strcmp(attr[curIdx++], "responses")) {
- ALOGE("%s: responses not found", __func__);
- goto done;
- }
- token = strtok((char *)attr[curIdx++], " ");
- uint32_t num_responses = 0;
- while (token) {
- microphone.frequency_responses[1][num_responses++] = atof(token);
- if (num_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
- ALOGE("%s: num %u of response is too large", __func__, num_responses);
+ strcpy(microphone.device_id, value);
+ found_mandatory_characteristics |= 1;
+ } else if (strcmp(attribute, "type") == 0) {
+ if (!find_enum_by_string(device_in_types, value,
+ ARRAY_SIZE(device_in_types), µphone.device)) {
+ ALOGE("%s: type %s in %s not found!",
+ __func__, value, PLATFORM_INFO_XML_PATH);
goto done;
}
- token = strtok(NULL, " ");
- }
-
- if (num_frequencies != num_responses
- || num_frequencies != microphone.num_frequency_responses) {
- ALOGE("%s: num of frequency and response not match: %u, %u, %u",
- __func__, num_frequencies, num_responses, microphone.num_frequency_responses);
- goto done;
- }
- }
-
- if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_SENSITIVITY) {
- if (strcmp(attr[curIdx++], "sensitivity")) {
- ALOGE("%s: sensitivity not found", __func__);
- goto done;
- }
- microphone.sensitivity = atof(attr[curIdx++]);
- } else {
- microphone.sensitivity = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN;
- }
-
- if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_MAX_SPL) {
- if (strcmp(attr[curIdx++], "max_spl")) {
- ALOGE("%s: max_spl not found", __func__);
- goto done;
- }
- microphone.max_spl = atof(attr[curIdx++]);
- } else {
- microphone.max_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
- }
-
- if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_MIN_SPL) {
- if (strcmp(attr[curIdx++], "min_spl")) {
- ALOGE("%s: min_spl not found", __func__);
- goto done;
- }
- microphone.min_spl = atof(attr[curIdx++]);
- } else {
- microphone.min_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
- }
-
- if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_ORIENTATION) {
- if (strcmp(attr[curIdx++], "orientation")) {
- ALOGE("%s: orientation not found", __func__);
- goto done;
- }
- char *token = strtok((char *)attr[curIdx++], " ");
- float orientation[3];
- uint32_t idx = 0;
- while (token) {
- orientation[idx++] = atof(token);
- if (idx > 3) {
+ found_mandatory_characteristics |= (1 << 1);
+ } else if (strcmp(attribute, "address") == 0) {
+ if (strlen(value) > AUDIO_DEVICE_MAX_ADDRESS_LEN) {
+ ALOGE("%s, address %s is too long", __func__, value);
+ goto done;
+ }
+ strcpy(microphone.address, value);
+ if (strlen(microphone.address) == 0) {
+ // If the address is empty, populate the address according to device type.
+ if (microphone.device == AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ strcpy(microphone.address, AUDIO_BOTTOM_MICROPHONE_ADDRESS);
+ } else if (microphone.device == AUDIO_DEVICE_IN_BACK_MIC) {
+ strcpy(microphone.address, AUDIO_BACK_MICROPHONE_ADDRESS);
+ }
+ }
+ found_mandatory_characteristics |= (1 << 2);
+ } else if (strcmp(attribute, "location") == 0) {
+ if (!find_enum_by_string(mic_locations, value,
+ AUDIO_MICROPHONE_LOCATION_CNT, µphone.location)) {
+ ALOGE("%s: location %s in %s not found!",
+ __func__, value, PLATFORM_INFO_XML_PATH);
+ goto done;
+ }
+ found_mandatory_characteristics |= (1 << 3);
+ } else if (strcmp(attribute, "group") == 0) {
+ microphone.group = atoi(value);
+ found_mandatory_characteristics |= (1 << 4);
+ } else if (strcmp(attribute, "index_in_the_group") == 0) {
+ microphone.index_in_the_group = atoi(value);
+ found_mandatory_characteristics |= (1 << 5);
+ } else if (strcmp(attribute, "directionality") == 0) {
+ if (!find_enum_by_string(mic_directionalities, value,
+ AUDIO_MICROPHONE_DIRECTIONALITY_CNT, µphone.directionality)) {
+ ALOGE("%s: directionality %s in %s not found!",
+ __func__, attr[index], PLATFORM_INFO_XML_PATH);
+ goto done;
+ }
+ found_mandatory_characteristics |= (1 << 6);
+ } else if (strcmp(attribute, "num_frequency_responses") == 0) {
+ microphone.num_frequency_responses = atoi(value);
+ if (microphone.num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+ ALOGE("%s: num_frequency_responses is too large", __func__);
+ goto done;
+ }
+ found_mandatory_characteristics |= (1 << 7);
+ } else if (strcmp(attribute, "frequencies") == 0) {
+ char *token = strtok(value, " ");
+ while (token) {
+ microphone.frequency_responses[0][num_frequencies++] = atof(token);
+ if (num_frequencies > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+ ALOGE("%s: num %u of frequency is too large", __func__, num_frequencies);
+ goto done;
+ }
+ token = strtok(NULL, " ");
+ }
+ found_mandatory_characteristics |= (1 << 8);
+ } else if (strcmp(attribute, "responses") == 0) {
+ char *token = strtok(value, " ");
+ while (token) {
+ microphone.frequency_responses[1][num_responses++] = atof(token);
+ if (num_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+ ALOGE("%s: num %u of response is too large", __func__, num_responses);
+ goto done;
+ }
+ token = strtok(NULL, " ");
+ }
+ found_mandatory_characteristics |= (1 << 9);
+ } else if (strcmp(attribute, "sensitivity") == 0) {
+ microphone.sensitivity = atof(value);
+ } else if (strcmp(attribute, "max_spl") == 0) {
+ microphone.max_spl = atof(value);
+ } else if (strcmp(attribute, "min_spl") == 0) {
+ microphone.min_spl = atof(value);
+ } else if (strcmp(attribute, "orientation") == 0) {
+ char *token = strtok(value, " ");
+ float orientation[3];
+ uint32_t idx = 0;
+ while (token) {
+ orientation[idx++] = atof(token);
+ if (idx > 3) {
+ ALOGE("%s: orientation invalid", __func__);
+ goto done;
+ }
+ token = strtok(NULL, " ");
+ }
+ if (idx != 3) {
ALOGE("%s: orientation invalid", __func__);
goto done;
}
- token = strtok(NULL, " ");
- }
- if (idx != 3) {
- ALOGE("%s: orientation invalid", __func__);
- goto done;
- }
- microphone.orientation.x = orientation[0];
- microphone.orientation.y = orientation[1];
- microphone.orientation.z = orientation[2];
- } else {
- microphone.orientation.x = 0.0f;
- microphone.orientation.y = 0.0f;
- microphone.orientation.z = 0.0f;
- }
-
- if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_GEOMETRIC_LOCATION) {
- if (strcmp(attr[curIdx++], "geometric_location")) {
- ALOGE("%s: geometric_location not found", __func__);
- goto done;
- }
- char *token = strtok((char *)attr[curIdx++], " ");
- float geometric_location[3];
- uint32_t idx = 0;
- while (token) {
- geometric_location[idx++] = atof(token);
- if (idx > 3) {
+ microphone.orientation.x = orientation[0];
+ microphone.orientation.y = orientation[1];
+ microphone.orientation.z = orientation[2];
+ } else if (strcmp(attribute, "geometric_location") == 0) {
+ char *token = strtok(value, " ");
+ float geometric_location[3];
+ uint32_t idx = 0;
+ while (token) {
+ geometric_location[idx++] = atof(token);
+ if (idx > 3) {
+ ALOGE("%s: geometric_location invalid", __func__);
+ goto done;
+ }
+ token = strtok(NULL, " ");
+ }
+ if (idx != 3) {
ALOGE("%s: geometric_location invalid", __func__);
goto done;
}
- token = strtok(NULL, " ");
+ microphone.geometric_location.x = geometric_location[0];
+ microphone.geometric_location.y = geometric_location[1];
+ microphone.geometric_location.z = geometric_location[2];
+ } else {
+ ALOGW("%s: unknown attribute of microphone characteristics: %s",
+ __func__, attribute);
}
- if (idx != 3) {
- ALOGE("%s: geometric_location invalid", __func__);
- goto done;
- }
- microphone.geometric_location.x = geometric_location[0];
- microphone.geometric_location.y = geometric_location[1];
- microphone.geometric_location.z = geometric_location[2];
- } else {
- microphone.geometric_location.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
- microphone.geometric_location.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
- microphone.geometric_location.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
+ }
+
+ if (num_frequencies != num_responses
+ || num_frequencies != microphone.num_frequency_responses) {
+ ALOGE("%s: num of frequency and response not match: %u, %u, %u",
+ __func__, num_frequencies, num_responses, microphone.num_frequency_responses);
+ goto done;
+ }
+
+ if (found_mandatory_characteristics != MANDATORY_MICROPHONE_CHARACTERISTICS) {
+ ALOGE("%s: some of mandatory microphone characteriscts are missed: %u",
+ __func__, found_mandatory_characteristics);
}
platform_set_microphone_characteristic(my_data.platform, microphone);
@@ -773,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) {
@@ -792,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;
}
@@ -870,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;
@@ -891,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) {
@@ -916,14 +967,8 @@
}
}
-int snd_card_info_init(const char *filename, void *platform, set_parameters_fn fn)
-{
- set_parameters = fn;
- my_data.do_full_parse = false;
- return platform_info_init(filename, platform);
-}
-
-int platform_info_init(const char *filename, void *platform)
+int platform_info_init(const char *filename, void *platform,
+ bool do_full_parse, set_parameters_fn fn)
{
XML_Parser parser;
FILE *file;
@@ -932,7 +977,6 @@
void *buf;
static const uint32_t kBufSize = 1024;
char platform_info_file_name[MIXER_PATH_MAX_LENGTH]= {0};
- section = ROOT;
if (filename == NULL) {
strlcpy(platform_info_file_name, PLATFORM_INFO_XML_PATH, MIXER_PATH_MAX_LENGTH);
@@ -958,8 +1002,12 @@
goto err_close_file;
}
+ pthread_mutex_lock(&my_data.lock);
+ section = ROOT;
+ my_data.do_full_parse = do_full_parse;
my_data.platform = platform;
my_data.kvpairs = str_parms_create();
+ my_data.set_parameters = fn;
XML_SetElementHandler(parser, start_tag, end_tag);
@@ -990,10 +1038,12 @@
break;
}
- set_parameters = &platform_set_parameters;
- my_data.do_full_parse = true;
-
err_free_parser:
+ if (my_data.kvpairs != NULL) {
+ str_parms_destroy(my_data.kvpairs);
+ my_data.kvpairs = NULL;
+ }
+ pthread_mutex_unlock(&my_data.lock);
XML_ParserFree(parser);
err_close_file:
fclose(file);
diff --git a/hal/voice.c b/hal/voice.c
index 09cb926..708ce6c 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -171,6 +171,7 @@
uc_info->devices = adev->current_call_output ->devices;
uc_info->in_snd_device = SND_DEVICE_NONE;
uc_info->out_snd_device = SND_DEVICE_NONE;
+ adev->use_voice_device_mute = false;
list_add_tail(&adev->usecase_list, &uc_info->list);
@@ -357,11 +358,19 @@
int voice_set_mic_mute(struct audio_device *adev, bool state)
{
int err = 0;
+ struct audio_usecase *usecase = NULL;
adev->voice.mic_mute = state;
if (adev->mode == AUDIO_MODE_IN_CALL ||
- adev->mode == AUDIO_MODE_IN_COMMUNICATION)
- err = platform_set_mic_mute(adev->platform, state);
+ adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
+ /* Use device mute if incall music delivery usecase is in progress */
+ if (adev->use_voice_device_mute)
+ err = platform_set_device_mute(adev->platform, state, "tx");
+ else
+ err = platform_set_mic_mute(adev->platform, state);
+ ALOGV("%s: voice mute status=%d, use_voice_device_mute_flag=%d",
+ __func__, state, adev->use_voice_device_mute);
+ }
return err;
}
@@ -371,6 +380,25 @@
return adev->voice.mic_mute;
}
+// Following function is called when incall music uplink usecase is
+// created or destroyed while mic is muted. If incall music uplink
+// usecase is active, apply voice device mute to mute only voice Tx
+// path and not the mixed voice Tx + inncall-music path. Revert to
+// voice stream mute once incall music uplink usecase is inactive
+void voice_set_device_mute_flag (struct audio_device *adev, bool state)
+{
+ if (adev->voice.mic_mute) {
+ if (state) {
+ platform_set_device_mute(adev->platform, true, "tx");
+ platform_set_mic_mute(adev->platform, false);
+ } else {
+ platform_set_mic_mute(adev->platform, true);
+ platform_set_device_mute(adev->platform, false, "tx");
+ }
+ }
+ adev->use_voice_device_mute = state;
+}
+
int voice_set_volume(struct audio_device *adev, float volume)
{
int vol, err = 0;
@@ -517,6 +545,8 @@
adev->voice.volume = 1.0f;
adev->voice.mic_mute = false;
adev->voice.in_call = false;
+ adev->use_voice_device_mute = false;
+
for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
adev->voice.session[i].pcm_rx = NULL;
adev->voice.session[i].pcm_tx = NULL;
diff --git a/hal/voice.h b/hal/voice.h
index 469a3b5..71e096b 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -95,4 +95,6 @@
snd_device_t out_snd_device,
bool enable);
bool voice_is_call_state_active(struct audio_device *adev);
+void voice_set_device_mute_flag (struct audio_device *adev, bool state);
+
#endif //VOICE_H