Merge " "configs: enable 3D audio feature.""
diff --git a/configs/atoll/sound_trigger_platform_info.xml b/configs/atoll/sound_trigger_platform_info.xml
index 00ba7ec..dbbcb5f 100644
--- a/configs/atoll/sound_trigger_platform_info.xml
+++ b/configs/atoll/sound_trigger_platform_info.xml
@@ -130,7 +130,7 @@
<!-- LPI: This mode type will be used for LPI usecases. -->
<param lpi_mode="NON_LPI_BARGE_IN" />
<param app_type="2" /> <!-- app type used in ACDB -->
- <param in_channels="5"/> <!-- Module input channels -->
+ <param in_channels="3"/> <!-- Module input channels -->
<param load_sound_model_ids="0x00012C1C, 0x0, 0x00012C14" />
<param unload_sound_model_ids="0x00012C1C, 0x0, 0x00012C15" />
<param confidence_levels_ids="0x00012C1C, 0x0, 0x00012C07" />
@@ -359,6 +359,6 @@
<param app_type="69947" />
<param sample_rate="16000" />
<param bit_width="16" />
- <param out_channels="5"/>
+ <param out_channels="3"/>
</adm_config>
</sound_trigger_platform_info>
diff --git a/configs/kona/audio_policy_configuration.xml b/configs/kona/audio_policy_configuration.xml
index d47ee6e..75b91a0 100755
--- a/configs/kona/audio_policy_configuration.xml
+++ b/configs/kona/audio_policy_configuration.xml
@@ -179,6 +179,11 @@
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</mixPort>
+ <mixPort name="quad mic" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000"
+ channelMasks="AUDIO_CHANNEL_INDEX_MASK_4"/>
+ </mixPort>
<mixPort name="voip_tx" role="sink"
flags="AUDIO_INPUT_FLAG_VOIP_TX">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
@@ -363,6 +368,8 @@
sources="Wired Headset Mic,BT SCO Headset Mic,FM Tuner,USB Device In,USB Headset In,Telephony Rx"/>
<route type="mix" sink="fast input"
sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
+ <route type="mix" sink="quad mic"
+ sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
<route type="mix" sink="voip_tx"
sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
<route type="mix" sink="usb_surround_sound"
diff --git a/configs/kona/sound_trigger_platform_info.xml b/configs/kona/sound_trigger_platform_info.xml
index b4a611f..d8604b6 100644
--- a/configs/kona/sound_trigger_platform_info.xml
+++ b/configs/kona/sound_trigger_platform_info.xml
@@ -120,7 +120,7 @@
<!-- fluence_type: "FLUENCE_MIC", "FLUENCE_DMIC", "FLUENCE_TMIC" -->
<!-- "FLUENCE_QMIC". Param value is valid when adm_cfg_profile -->
<!-- is FFECNS -->
- <param fluence_type="FLUENCE_TMIC" />
+ <param fluence_type="FLUENCE_DMIC" />
<param execution_mode="ADSP" />
<!-- lpi_mode: "NON_LPI_BARGE_IN", "NON_LPI", "LPI" -->
<!-- NON_LPI_BARGE_IN: Default non-LPI mode type. lsm_usecase -->
@@ -131,7 +131,7 @@
<!-- LPI: This mode type will be used for LPI usecases. -->
<param lpi_mode="NON_LPI_BARGE_IN" />
<param app_type="2" /> <!-- app type used in ACDB -->
- <param in_channels="5"/> <!-- Module input channels -->
+ <param in_channels="3"/> <!-- Module input channels -->
<param load_sound_model_ids="0x00012C1C, 0x0, 0x00012C14" />
<param unload_sound_model_ids="0x00012C1C, 0x0, 0x00012C15" />
<param confidence_levels_ids="0x00012C1C, 0x0, 0x00012C07" />
@@ -149,7 +149,7 @@
<!-- fluence_type: "FLUENCE_MIC", "FLUENCE_DMIC", "FLUENCE_TMIC" -->
<!-- "FLUENCE_QMIC". Param value is valid when adm_cfg_profile -->
<!-- is FFECNS -->
- <param fluence_type="FLUENCE_TMIC" />
+ <param fluence_type="FLUENCE_DMIC" />
<param execution_mode="ADSP" />
<!-- lpi_mode: "NON_LPI_BARGE_IN", "NON_LPI", "LPI" -->
<!-- NON_LPI_BARGE_IN: Default non-LPI mode type. lsm_usecase -->
@@ -160,7 +160,7 @@
<!-- LPI: This mode type will be used for LPI usecases. -->
<param lpi_mode="LPI" />
<param app_type="2" /> <!-- app type used in ACDB -->
- <param in_channels="3"/> <!-- Module input channels -->
+ <param in_channels="1"/> <!-- Module input channels -->
<param load_sound_model_ids="0x00012C1C, 0x0, 0x00012C14" />
<param unload_sound_model_ids="0x00012C1C, 0x0, 0x00012C15" />
<param confidence_levels_ids="0x00012C1C, 0x0, 0x00012C07" />
@@ -389,7 +389,7 @@
<param app_type="69947" />
<param sample_rate="16000" />
<param bit_width="16" />
- <param out_channels="5"/>
+ <param out_channels="3"/>
</adm_config>
<adm_config>
diff --git a/configs/lahaina/lahaina.mk b/configs/lahaina/lahaina.mk
index e065edd..f9ed3b9 100644
--- a/configs/lahaina/lahaina.mk
+++ b/configs/lahaina/lahaina.mk
@@ -505,3 +505,5 @@
PRODUCT_PACKAGES_DEBUG += \
libadpcmdec
endif
+
+AUDIO_FEATURE_ENABLED_GKI := true
diff --git a/configs/lito/audio_policy_configuration.xml b/configs/lito/audio_policy_configuration.xml
index 4095a6a..2ee18cd 100755
--- a/configs/lito/audio_policy_configuration.xml
+++ b/configs/lito/audio_policy_configuration.xml
@@ -179,6 +179,11 @@
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</mixPort>
+ <mixPort name="quad mic" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000"
+ channelMasks="AUDIO_CHANNEL_INDEX_MASK_4"/>
+ </mixPort>
<mixPort name="voip_tx" role="sink"
flags="AUDIO_INPUT_FLAG_VOIP_TX">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
@@ -363,6 +368,8 @@
sources="Wired Headset Mic,BT SCO Headset Mic,FM Tuner,USB Device In,USB Headset In,Telephony Rx"/>
<route type="mix" sink="fast input"
sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
+ <route type="mix" sink="quad mic"
+ sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
<route type="mix" sink="voip_tx"
sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
<route type="mix" sink="usb_surround_sound"
diff --git a/configs/lito/sound_trigger_platform_info.xml b/configs/lito/sound_trigger_platform_info.xml
index 00ba7ec..dbbcb5f 100644
--- a/configs/lito/sound_trigger_platform_info.xml
+++ b/configs/lito/sound_trigger_platform_info.xml
@@ -130,7 +130,7 @@
<!-- LPI: This mode type will be used for LPI usecases. -->
<param lpi_mode="NON_LPI_BARGE_IN" />
<param app_type="2" /> <!-- app type used in ACDB -->
- <param in_channels="5"/> <!-- Module input channels -->
+ <param in_channels="3"/> <!-- Module input channels -->
<param load_sound_model_ids="0x00012C1C, 0x0, 0x00012C14" />
<param unload_sound_model_ids="0x00012C1C, 0x0, 0x00012C15" />
<param confidence_levels_ids="0x00012C1C, 0x0, 0x00012C07" />
@@ -359,6 +359,6 @@
<param app_type="69947" />
<param sample_rate="16000" />
<param bit_width="16" />
- <param out_channels="5"/>
+ <param out_channels="3"/>
</adm_config>
</sound_trigger_platform_info>
diff --git a/hal/Android.mk b/hal/Android.mk
index 43f5c9c..3168ff9 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -131,6 +131,7 @@
audio_extn/source_track.c \
audio_extn/usb.c \
audio_extn/utils.c \
+ audio_extn/device_utils.c \
voice_extn/compress_voip.c \
voice_extn/voice_extn.c
@@ -326,6 +327,11 @@
LOCAL_CFLAGS += -DINSTANCE_ID_ENABLED
endif
+# Hardware specific feature
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_GKI)), true)
+ LOCAL_CFLAGS += -DAUDIO_GKI_ENABLED
+endif
+
# Legacy feature
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_KEEP_ALIVE_ARM_FFV)), true)
LOCAL_CFLAGS += -DRUN_KEEP_ALIVE_IN_ARM_FFV
diff --git a/hal/audio_extn/Android.mk b/hal/audio_extn/Android.mk
index b5c32cd..b889212 100644
--- a/hal/audio_extn/Android.mk
+++ b/hal/audio_extn/Android.mk
@@ -136,7 +136,8 @@
MULTIPLE_HW_VARIANTS_ENABLED := true
endif
-LOCAL_SRC_FILES:= ssr.c
+LOCAL_SRC_FILES:= ssr.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
@@ -383,7 +384,8 @@
endif
LOCAL_SRC_FILES:= \
- a2dp.c
+ a2dp.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
@@ -514,7 +516,8 @@
endif
LOCAL_SRC_FILES:= \
- hfp.c
+ hfp.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
@@ -577,7 +580,8 @@
endif
LOCAL_SRC_FILES:= \
- passthru.c
+ passthru.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
@@ -779,7 +783,8 @@
endif
LOCAL_SRC_FILES:= \
- maxxaudio.c
+ maxxaudio.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
@@ -840,7 +845,8 @@
endif
LOCAL_SRC_FILES:= \
- audiozoom.c
+ audiozoom.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
@@ -904,7 +910,8 @@
endif
LOCAL_SRC_FILES:= \
- auto_hal.c
+ auto_hal.c \
+ device_utils.c
LOCAL_CFLAGS += \
-Wall \
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index bffa3fd..e0aebf0 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -2786,7 +2786,7 @@
list_for_each(node, &a2dp.adev->usecase_list) {
uc_info = node_to_item(node, struct audio_usecase, list);
if (uc_info->stream.out && uc_info->type == PCM_PLAYBACK &&
- (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+ is_a2dp_out_device_type(&uc_info->stream.out->device_list)) {
pthread_mutex_unlock(&a2dp.adev->lock);
fp_check_a2dp_restore(a2dp.adev, uc_info->stream.out, false);
pthread_mutex_lock(&a2dp.adev->lock);
@@ -2827,7 +2827,7 @@
list_for_each(node, &a2dp.adev->usecase_list) {
uc_info = node_to_item(node, struct audio_usecase, list);
if (uc_info->stream.out && uc_info->type == PCM_PLAYBACK &&
- (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+ is_a2dp_out_device_type(&uc_info->stream.out->device_list)) {
pthread_mutex_unlock(&a2dp.adev->lock);
fp_check_a2dp_restore(a2dp.adev, uc_info->stream.out, true);
pthread_mutex_lock(&a2dp.adev->lock);
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 2d31509..620e7c6 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -1247,12 +1247,12 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.out && usecase->type != PCM_CAPTURE) {
- if (usecase->stream.out->devices == \
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- usecase->stream.out->devices == \
- AUDIO_DEVICE_OUT_WIRED_HEADSET ||
- usecase->stream.out->devices == \
- AUDIO_DEVICE_OUT_EARPIECE) {
+ if (is_single_device_type_equal(&usecase->stream.out->device_list,
+ AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
+ is_single_device_type_equal(&usecase->stream.out->device_list,
+ AUDIO_DEVICE_OUT_WIRED_HEADSET) ||
+ is_single_device_type_equal(&usecase->stream.out->device_list,
+ AUDIO_DEVICE_OUT_EARPIECE)) {
select_devices(adev, usecase->id);
ALOGV("%s: switching device completed", __func__);
break;
@@ -3036,6 +3036,114 @@
audio_extn_aptx_dec_set_license(adev);
}
+#ifdef AUDIO_GKI_ENABLED
+int get_wma_dec_info(struct stream_out *out, struct str_parms *parms) {
+ int ret = 0;
+ char value[32];
+
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma_dec.avg_bit_rate = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BLOCK_ALIGN, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma_dec.super_block_align = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BIT_PER_SAMPLE, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma_dec.bits_per_sample = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_CHANNEL_MASK, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma_dec.channelmask = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma_dec.encodeopt = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION1, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma_dec.encodeopt1 = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION2, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma_dec.encodeopt2 = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ALOGV("WMA params: fmt %x, bit rate %x, balgn %x, sr %d, chmsk %x"
+ " encop %x, op1 %x, op2 %x",
+ out->compr_config.codec->format,
+ out->compr_config.codec->options.wma_dec.avg_bit_rate,
+ out->compr_config.codec->options.wma_dec.super_block_align,
+ out->compr_config.codec->options.wma_dec.bits_per_sample,
+ out->compr_config.codec->options.wma_dec.channelmask,
+ out->compr_config.codec->options.wma_dec.encodeopt,
+ out->compr_config.codec->options.wma_dec.encodeopt1,
+ out->compr_config.codec->options.wma_dec.encodeopt2);
+
+ return ret;
+}
+#else
+int get_wma_info(struct stream_out *out, struct str_parms *parms) {
+ int ret = 0;
+ char value[32];
+
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma.avg_bit_rate = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BLOCK_ALIGN, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma.super_block_align = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BIT_PER_SAMPLE, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma.bits_per_sample = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_CHANNEL_MASK, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma.channelmask = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma.encodeopt = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION1, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma.encodeopt1 = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION2, value, sizeof(value));
+ if (ret >= 0) {
+ out->compr_config.codec->options.wma.encodeopt2 = atoi(value);
+ out->is_compr_metadata_avail = true;
+ }
+ ALOGV("WMA params: fmt %x, bit rate %x, balgn %x, sr %d, chmsk %x"
+ " encop %x, op1 %x, op2 %x",
+ out->compr_config.codec->format,
+ out->compr_config.codec->options.wma.avg_bit_rate,
+ out->compr_config.codec->options.wma.super_block_align,
+ out->compr_config.codec->options.wma.bits_per_sample,
+ out->compr_config.codec->options.wma.channelmask,
+ out->compr_config.codec->options.wma.encodeopt,
+ out->compr_config.codec->options.wma.encodeopt1,
+ out->compr_config.codec->options.wma.encodeopt2);
+
+ return ret;
+}
+#endif
+
int audio_extn_parse_compress_metadata(struct stream_out *out,
struct str_parms *parms)
{
@@ -3228,51 +3336,11 @@
out->compr_config.codec->format = atoi(value);
out->is_compr_metadata_avail = true;
}
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->options.wma.avg_bit_rate = atoi(value);
- out->is_compr_metadata_avail = true;
- }
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BLOCK_ALIGN, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->options.wma.super_block_align = atoi(value);
- out->is_compr_metadata_avail = true;
- }
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BIT_PER_SAMPLE, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->options.wma.bits_per_sample = atoi(value);
- out->is_compr_metadata_avail = true;
- }
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_CHANNEL_MASK, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->options.wma.channelmask = atoi(value);
- out->is_compr_metadata_avail = true;
- }
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->options.wma.encodeopt = atoi(value);
- out->is_compr_metadata_avail = true;
- }
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION1, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->options.wma.encodeopt1 = atoi(value);
- out->is_compr_metadata_avail = true;
- }
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION2, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->options.wma.encodeopt2 = atoi(value);
- out->is_compr_metadata_avail = true;
- }
- ALOGV("WMA params: fmt %x, bit rate %x, balgn %x, sr %d, chmsk %x"
- " encop %x, op1 %x, op2 %x",
- out->compr_config.codec->format,
- out->compr_config.codec->options.wma.avg_bit_rate,
- out->compr_config.codec->options.wma.super_block_align,
- out->compr_config.codec->options.wma.bits_per_sample,
- out->compr_config.codec->options.wma.channelmask,
- out->compr_config.codec->options.wma.encodeopt,
- out->compr_config.codec->options.wma.encodeopt1,
- out->compr_config.codec->options.wma.encodeopt2);
+#ifdef AUDIO_GKI_ENABLED
+ ret = get_wma_dec_info(out, parms);
+#else
+ ret = get_wma_info(out, parms);
+#endif
}
return ret;
@@ -3319,7 +3387,7 @@
/* validate input params. Avoid updated channel mask if loopback device */
if ((channel_count == 6) &&
(in->format == AUDIO_FORMAT_PCM_16_BIT) &&
- (!is_loopback_input_device(in->device))) {
+ (!is_loopback_input_device(get_device_types(&in->device_list)))) {
switch (max_mic_count) {
case 4:
config->channel_mask = AUDIO_CHANNEL_INDEX_MASK_4;
@@ -3594,13 +3662,13 @@
adev_device_cfg_ptr = adev->device_cfg_params;
/* Create an out stream to get snd device from audio device */
- out.devices = device_cfg_params->device;
+ reassign_device_list(&out.device_list, device_cfg_params->device, "");
out.sample_rate = device_cfg_params->sample_rate;
snd_device = platform_get_output_snd_device(adev->platform, &out);
backend_idx = platform_get_backend_index(snd_device);
ALOGV("%s:: device %d sample_rate %d snd_device %d backend_idx %d",
- __func__, out.devices, out.sample_rate, snd_device, backend_idx);
+ __func__, get_device_types(&out.device_list), out.sample_rate, snd_device, backend_idx);
ALOGV("%s:: Device Config Params from Client samplerate %d channels %d"
" bit_width %d format %d device %d channel_map[0] %d channel_map[1] %d"
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 986e24a..b01915a 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -680,7 +680,7 @@
typedef int (*fp_platform_set_mic_mute_t)(void *, bool);
//typedef int (*fp_platform_get_pcm_device_id_t)(audio_usecase_t, int);
typedef void (*fp_platform_set_echo_reference_t)(struct audio_device *, bool,
- audio_devices_t);
+ struct listnode *);
typedef int (*fp_select_devices_t)(struct audio_device *, audio_usecase_t);
typedef int (*fp_audio_extn_ext_hw_plugin_usecase_start_t)(void *,
struct audio_usecase *);
@@ -795,7 +795,7 @@
struct listnode *streams_input_cfg_list);
void audio_extn_utils_update_stream_output_app_type_cfg(void *platform,
struct listnode *streams_output_cfg_list,
- audio_devices_t devices,
+ struct listnode *devices,
audio_output_flags_t flags,
audio_format_t format,
uint32_t sample_rate,
@@ -805,7 +805,7 @@
struct stream_app_type_cfg *app_type_cfg);
void audio_extn_utils_update_stream_input_app_type_cfg(void *platform,
struct listnode *streams_input_cfg_list,
- audio_devices_t devices,
+ struct listnode *devices,
audio_input_flags_t flags,
audio_format_t format,
uint32_t sample_rate,
@@ -1063,7 +1063,7 @@
void audio_extn_gef_init(struct audio_device *adev);
void audio_extn_gef_deinit(struct audio_device *adev);
-void audio_extn_gef_notify_device_config(audio_devices_t audio_device,
+void audio_extn_gef_notify_device_config(struct listnode *audio_devices,
audio_channel_mask_t channel_mask, int sample_rate, int acdb_id, int app_type);
#ifndef INSTANCE_ID_ENABLED
int audio_extn_gef_send_audio_cal(void* adev, int acdb_dev_id, int acdb_device_type,
@@ -1126,7 +1126,8 @@
void audio_extn_fm_set_parameters(struct audio_device *adev,
struct str_parms *parms);
void audio_extn_fm_get_parameters(struct str_parms *query, struct str_parms *reply);
-void audio_extn_fm_route_on_selected_device(struct audio_device *adev, audio_devices_t device);
+void audio_extn_fm_route_on_selected_device(struct audio_device *adev,
+ struct listnode *devices);
#ifndef APTX_DECODER_ENABLED
#define audio_extn_aptx_dec_set_license(adev); (0)
diff --git a/hal/audio_extn/audiozoom.c b/hal/audio_extn/audiozoom.c
index 9958cc4..e2bde0f 100644
--- a/hal/audio_extn/audiozoom.c
+++ b/hal/audio_extn/audiozoom.c
@@ -203,7 +203,7 @@
qdsp_audiozoom.zoom_param_id == 0)
return -ENOSYS;
- str_parms_add_int(parms, "cal_devid", in->device);
+ str_parms_add_int(parms, "cal_devid", get_device_types(&in->device_list));
str_parms_add_int(parms, "cal_apptype", in->app_type_cfg.app_type);
str_parms_add_int(parms, "cal_topoid", qdsp_audiozoom.topo_id);
str_parms_add_int(parms, "cal_moduleid", qdsp_audiozoom.module_id);
diff --git a/hal/audio_extn/auto_hal.c b/hal/audio_extn/auto_hal.c
index 41b3762..580d446 100644
--- a/hal/audio_extn/auto_hal.c
+++ b/hal/audio_extn/auto_hal.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -230,7 +230,8 @@
ALOGV("Creating audio patch for external FM tuner");
uc_info->id = USECASE_AUDIO_FM_TUNER_EXT;
uc_info->type = PCM_PASSTHROUGH;
- uc_info->devices = AUDIO_DEVICE_IN_FM_TUNER;
+ reassign_device_list(&uc_info->device_list, AUDIO_DEVICE_IN_FM_TUNER,
+ sources->ext.device.address);
uc_info->in_snd_device = SND_DEVICE_IN_CAPTURE_FM;
uc_info->out_snd_device = SND_DEVICE_OUT_BUS_MEDIA;
break;
@@ -599,8 +600,10 @@
streams_output_ctxt_t,
list);
/* limit audio gain support for bus device only */
- if (out_ctxt->output->devices == AUDIO_DEVICE_OUT_BUS &&
- out_ctxt->output->devices == config->ext.device.type &&
+ if (is_single_device_type_equal(
+ &out_ctxt->output->device_list, AUDIO_DEVICE_OUT_BUS) &&
+ is_single_device_type_equal(&out_ctxt->output->device_list,
+ config->ext.device.type) &&
strcmp(out_ctxt->output->address,
config->ext.device.address) == 0) {
/* millibel = 1/100 dB = 1/1000 bel
@@ -710,7 +713,7 @@
uc_downlink_info->type = PCM_HFP_CALL;
uc_downlink_info->stream.out = adev->primary_output;
- uc_downlink_info->devices = adev->primary_output->devices;
+ assign_devices(&uc_downlink_info->device_list, &adev->primary_output->device_list);
uc_downlink_info->in_snd_device = SND_DEVICE_NONE;
uc_downlink_info->out_snd_device = SND_DEVICE_NONE;
@@ -790,12 +793,16 @@
audio_usecase_t uc_id)
{
snd_device_t snd_device = SND_DEVICE_NONE;
- audio_devices_t out_device = AUDIO_DEVICE_NONE;
+ struct listnode out_devices;
struct audio_usecase *usecase = NULL;
struct stream_in *in = fp_adev_get_active_input(adev);
- audio_devices_t in_device = ((in == NULL) ?
- AUDIO_DEVICE_NONE : in->device)
- & ~AUDIO_DEVICE_BIT_IN;
+ struct listnode in_devices;
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ list_init(&in_devices);
+ if (in != NULL)
+ assign_devices(&in_devices, &in->device_list);
if (uc_id == USECASE_INVALID) {
ALOGE("%s: Invalid usecase (%d)", __func__, uc_id);
@@ -813,17 +820,18 @@
return -EINVAL;
}
- out_device = usecase->stream.out->devices;
- if (out_device == AUDIO_DEVICE_NONE ||
- out_device & AUDIO_DEVICE_BIT_IN) {
- ALOGE("%s: Invalid output devices (%#x)", __func__, out_device);
+ list_init(&out_devices);
+ assign_devices(&out_devices, &usecase->stream.out->device_list);
+ if (list_empty(&out_devices) ||
+ compare_device_type(&out_devices, AUDIO_DEVICE_BIT_IN)) {
+ ALOGE("%s: Invalid output devices (%#x)", __func__, get_device_types(&out_devices));
return -EINVAL;
}
ALOGV("%s: output device(%#x), input device(%#x), usecase(%d)",
- __func__, out_device, in_device, uc_id);
+ __func__, get_device_types(&out_devices), get_device_types(&in_devices), uc_id);
- if (out_device & AUDIO_DEVICE_OUT_BUS) {
+ if (compare_device_type(&out_devices, AUDIO_DEVICE_OUT_BUS)) {
/* usecase->id is token as judgement for HFP calls */
switch (usecase->id) {
case USECASE_AUDIO_HFP_SCO:
@@ -834,7 +842,7 @@
snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP;
}
if (adev->enable_hfp)
- fp_platform_set_echo_reference(adev, true, out_device);
+ fp_platform_set_echo_reference(adev, false, &out_devices);
break;
case USECASE_AUDIO_HFP_SCO_DOWNLINK:
snd_device = SND_DEVICE_IN_BT_SCO_MIC;
@@ -850,7 +858,7 @@
return -EINVAL;
}
} else {
- ALOGE("%s: Output devices (%#x) not supported", __func__, out_device);
+ ALOGE("%s: Output devices (%#x) not supported", __func__, get_device_types(&out_devices));
return -EINVAL;
}
@@ -861,7 +869,7 @@
audio_usecase_t uc_id)
{
snd_device_t snd_device = SND_DEVICE_NONE;
- audio_devices_t devices = AUDIO_DEVICE_NONE;
+ struct listnode devices;
struct audio_usecase *usecase = NULL;
if (uc_id == USECASE_INVALID) {
@@ -880,16 +888,18 @@
return -EINVAL;
}
- devices = usecase->stream.out->devices;
- if (devices == AUDIO_DEVICE_NONE ||
- devices & AUDIO_DEVICE_BIT_IN) {
- ALOGE("%s: Invalid output devices (%#x)", __func__, devices);
+ list_init(&devices);
+ assign_devices(&devices, &usecase->stream.out->device_list);
+ if (list_empty(&devices) ||
+ compare_device_type(&devices, AUDIO_DEVICE_BIT_IN)) {
+ ALOGE("%s: Invalid output devices (%#x)", __func__, get_device_types(&devices));
return -EINVAL;
}
- ALOGV("%s: output devices(%#x), usecase(%d)", __func__, devices, uc_id);
+ ALOGV("%s: output devices(%#x), usecase(%d)", __func__,
+ get_device_types(&devices), uc_id);
- if (devices & AUDIO_DEVICE_OUT_BUS) {
+ if (compare_device_type(&devices, AUDIO_DEVICE_OUT_BUS)) {
/* usecase->id is token as judgement for HFP calls */
switch (usecase->id) {
case USECASE_AUDIO_HFP_SCO:
@@ -937,7 +947,7 @@
return -EINVAL;
}
} else {
- ALOGE("%s: Output devices (%#x) not supported", __func__, devices);
+ ALOGE("%s: Output devices (%#x) not supported", __func__, get_device_types(&devices));
return -EINVAL;
}
diff --git a/hal/audio_extn/compress_in.c b/hal/audio_extn/compress_in.c
index 6b525b0..fb8834d 100644
--- a/hal/audio_extn/compress_in.c
+++ b/hal/audio_extn/compress_in.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -281,6 +281,7 @@
struct audio_config config = {.format = 0};
int ret = 0, buffer_size = 0, meta_size = sizeof(struct snd_codec_metadata);
cin_private_data_t *cin_data = NULL;
+ uint32_t compr_passthr = 0, flags = 0;
if (!COMPRESSED_TIMESTAMP_FLAG &&
(in->flags & (AUDIO_INPUT_FLAG_TIMESTAMP | AUDIO_INPUT_FLAG_PASSTHROUGH))) {
@@ -326,17 +327,26 @@
cin_data->compr_config.codec->format = hal_format_to_alsa(in->format);
if (cin_data->compr_config.codec->id == SND_AUDIOCODEC_PCM)
- cin_data->compr_config.codec->compr_passthr = LEGACY_PCM;
+ compr_passthr = LEGACY_PCM;
else if (cin_data->compr_config.codec->id == SND_AUDIOCODEC_IEC61937)
- cin_data->compr_config.codec->compr_passthr = PASSTHROUGH_IEC61937;
+ compr_passthr = PASSTHROUGH_IEC61937;
else
- cin_data->compr_config.codec->compr_passthr = PASSTHROUGH_GEN;
+ compr_passthr = PASSTHROUGH_GEN;
if (in->flags & AUDIO_INPUT_FLAG_FAST) {
ALOGD("%s: Setting latency mode to true", __func__);
- cin_data->compr_config.codec->flags |= audio_extn_utils_get_perf_mode_flag();
+ flags |= audio_extn_utils_get_perf_mode_flag();
}
+#ifdef AUDIO_QGKI_ENABLED
+ /* out->compr_config.codec->reserved[0] is for compr_passthr */
+ cin_data->compr_config.codec->reserved[0] = compr_passthr;
+ /* out->compr_config.codec->reserved[1] is for flags */
+ cin_data->compr_config.codec->reserved[1] = flags;
+#else
+ cin_data->compr_config.codec->compr_passthr = compr_passthr;
+ cin_data->compr_config.codec->flags = flags;
+#endif
if ((in->flags & AUDIO_INPUT_FLAG_TIMESTAMP) ||
(in->flags & AUDIO_INPUT_FLAG_PASSTHROUGH)) {
compress_config_set_timstamp_flag(&cin_data->compr_config);
diff --git a/hal/audio_extn/device_utils.c b/hal/audio_extn/device_utils.c
new file mode 100644
index 0000000..e67676d
--- /dev/null
+++ b/hal/audio_extn/device_utils.c
@@ -0,0 +1,601 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "device_utils"
+/*#define LOG_NDEBUG 0*/
+#define LOG_NDDEBUG 0
+
+#include <errno.h>
+#include <stdlib.h>
+#include <hardware/audio.h>
+#include <cutils/list.h>
+#include <log/log.h>
+
+#include "device_utils.h"
+
+/*
+ * Below are the devices for which is back end is same, SLIMBUS_0_RX.
+ * All these devices are handled by the internal HW codec. We can
+ * enable any one of these devices at any time. An exception here is
+ * 44.1k headphone which uses different backend. This is filtered
+ * as different hal internal device in the code but remains same
+ * as standard android device AUDIO_DEVICE_OUT_WIRED_HEADPHONE
+ * for other layers.
+ */
+static const uint32_t AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND_ARRAY[] = {
+ AUDIO_DEVICE_OUT_EARPIECE,
+ AUDIO_DEVICE_OUT_SPEAKER,
+ AUDIO_DEVICE_OUT_WIRED_HEADSET,
+ AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
+ AUDIO_DEVICE_OUT_LINE,
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE,
+};
+
+/*
+ * Below are the input devices for which back end is same, SLIMBUS_0_TX.
+ * All these devices are handled by the internal HW codec. We can
+ * enable any one of these devices at any time
+ */
+static const uint32_t AUDIO_DEVICE_IN_ALL_CODEC_BACKEND_ARRAY[] = {
+ AUDIO_DEVICE_IN_BUILTIN_MIC,
+ AUDIO_DEVICE_IN_WIRED_HEADSET,
+ AUDIO_DEVICE_IN_VOICE_CALL,
+ AUDIO_DEVICE_IN_BACK_MIC,
+};
+
+static const uint32_t AUDIO_DEVICE_OUT_CODEC_BACKEND_CNT =
+ AUDIO_ARRAY_SIZE(AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND_ARRAY);
+static const uint32_t AUDIO_DEVICE_IN_CODEC_BACKEND_CNT =
+ AUDIO_ARRAY_SIZE(AUDIO_DEVICE_IN_ALL_CODEC_BACKEND_ARRAY);
+
+
+int list_length(struct listnode *list)
+{
+ struct listnode *node;
+ int length = 0;
+
+ if (list == NULL)
+ goto done;
+
+ for (node = list->next; node != list; node = node->next)
+ ++length;
+done:
+ return length;
+}
+
+/*
+ * Returns true if devices list contains input device type.
+ */
+bool is_audio_in_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_input_device(item->type)) {
+ ALOGV("%s: in device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if devices list contains output device type.
+ */
+bool is_audio_out_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_output_device(item->type)) {
+ ALOGV("%s: out device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if devices list contains codec backend
+ * input device type.
+ */
+bool is_codec_backend_in_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item == NULL)
+ return false;
+ for (int i = 0; i < AUDIO_DEVICE_IN_CODEC_BACKEND_CNT; i++) {
+ if (item->type == AUDIO_DEVICE_IN_ALL_CODEC_BACKEND_ARRAY[i]) {
+ ALOGV("%s: codec backend in device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if devices list contains codec backend
+ * output device type.
+ */
+bool is_codec_backend_out_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item == NULL)
+ return false;
+ for (int i = 0; i < AUDIO_DEVICE_OUT_CODEC_BACKEND_CNT; i++) {
+ if (item->type == AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND_ARRAY[i]) {
+ ALOGV("%s: codec backend out device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/* Returns true if USB input device is found in passed devices list */
+bool is_usb_in_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_usb_in_device(item->type)) {
+ ALOGV("%s: USB in device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if USB output device is found in passed devices list
+ */
+bool is_usb_out_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_usb_out_device(item->type)) {
+ ALOGV("%s: USB out device %#x address %s", __func__,
+ item->type, item->address);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns USB device address information (card, device)
+ */
+const char *get_usb_device_address(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && (audio_is_usb_out_device(item->type) ||
+ audio_is_usb_in_device(item->type))) {
+ ALOGV("%s: USB device %#x address %s", __func__,
+ item->type, item->address);
+ return (const char *)&item->address[0];
+ }
+ }
+ return "";
+}
+
+/*
+ * Returns true if SCO output device is found in passed devices list
+ */
+bool is_sco_in_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL &&
+ audio_is_bluetooth_in_sco_device(item->type)) {
+ ALOGV("%s: SCO in device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if SCO output device is found in passed devices list
+ */
+bool is_sco_out_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL &&
+ audio_is_bluetooth_out_sco_device(item->type)) {
+ ALOGV("%s: SCO out device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if A2DP input device is found in passed devices list
+ */
+bool is_a2dp_in_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_a2dp_in_device(item->type)) {
+ ALOGV("%s: A2DP in device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if A2DP output device is found in passed devices list
+ */
+bool is_a2dp_out_device_type(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_a2dp_out_device(item->type)) {
+ ALOGV("%s: A2DP out device %#x", __func__, item->type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Clear device list
+ * Operation: devices = {};
+ */
+
+int clear_devices(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return 0;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL) {
+ list_remove(&item->list);
+ free(item);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Check if a device with given type is present in devices list
+ */
+bool compare_device_type(struct listnode *devices, audio_devices_t device_type)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && (item->type == device_type)) {
+ ALOGV("%s: device types %d match", __func__, device_type);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if intersection of d1 and d2 is not NULL
+ */
+bool compare_devices_for_any_match(struct listnode *d1, struct listnode *d2)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (d1 == NULL || d2 == NULL)
+ return false;
+
+ list_for_each (node, d1) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && compare_device_type(d2, item->type))
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Returns all device types from list in bitfield
+ * ToDo: Use of this function is not recommended.
+ * It has been introduced for compatability with legacy functions.
+ * This can be removed once audio HAL switches to device
+ * list usage for all audio extensions.
+ */
+audio_devices_t get_device_types(struct listnode *devices)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+ audio_devices_t device_type = AUDIO_DEVICE_NONE;
+
+ if (devices == NULL)
+ return false;
+
+ list_for_each (node, devices) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL)
+ device_type |= item->type;
+ }
+ return device_type;
+}
+
+/*
+ * If single device in devices list is equal to passed type
+ * type should represent a single device.
+ */
+bool is_single_device_type_equal(struct listnode *devices,
+ audio_devices_t type)
+{
+ struct listnode *node = devices;
+ struct audio_device_info *item = NULL;
+
+ if (devices == NULL)
+ return false;
+
+ if (list_length(devices) == 1) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && (item->type == type))
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Returns true if lists are equal in terms of device type
+ * ToDO: Check if device addresses are also equal in the future
+ */
+bool compare_devices(struct listnode *d1, struct listnode *d2)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+
+ if (d1 == NULL && d2 == NULL)
+ return true;
+
+ if (d1 == NULL || d2 == NULL ||
+ (list_length(d1) != list_length(d2)))
+ return false;
+
+ list_for_each (node, d1) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && !compare_device_type(d2, item->type))
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Add or remove device from list denoted by head
+ */
+int update_device_list(struct listnode *head, audio_devices_t type,
+ const char* address, bool add_device)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+ struct audio_device_info *device = NULL;
+ int ret = 0;
+
+ if (head == NULL)
+ goto done;
+
+ if (type == AUDIO_DEVICE_NONE) {
+ ALOGE("%s: Invalid device: %#x", __func__, type);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ list_for_each (node, head) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && (item->type == type)) {
+ device = item;
+ break;
+ }
+ }
+
+ if (add_device) {
+ if (device == NULL) {
+ device = (struct audio_device_info *)
+ calloc (1, sizeof(struct audio_device_info));
+ if (!device) {
+ ALOGE("%s: Cannot allocate memory for device_info", __func__);
+ ret = -ENOMEM;
+ goto done;
+ }
+ device->type = type;
+ list_add_tail(head, &device->list);
+ }
+ strlcpy(device->address, address, AUDIO_DEVICE_MAX_ADDRESS_LEN);
+ ALOGV("%s: Added device type %#x, address %s", __func__, type, address);
+ } else {
+ if (device != NULL) {
+ list_remove(&device->list);
+ free(device);
+ ALOGV("%s: Removed device type %#x, address %s", __func__, type, address);
+ }
+ }
+done:
+ return ret;
+}
+
+/*
+ * Assign source device list to destination device list
+ * Operation: dest list = source list
+ */
+int assign_devices(struct listnode *dest, const struct listnode *source)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+ int ret = 0;
+
+ if (source == NULL || dest == NULL)
+ return ret;
+
+ if (!list_empty(dest))
+ clear_devices(dest);
+
+ list_for_each (node, source) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL)
+ ret = update_device_list(dest, item->type, item->address, true);
+ }
+ return ret;
+}
+
+/*
+ * Assign output devices from source device list to destination device list
+ * Operation: dest devices = source output devices
+ */
+int assign_output_devices(struct listnode *dest, const struct listnode *source)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+ int ret = 0;
+
+ if (source == NULL || dest == NULL)
+ return ret;
+
+ if (!list_empty(dest))
+ clear_devices(dest);
+
+ list_for_each (node, source) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL && audio_is_output_device(item->type))
+ ret = update_device_list(dest, item->type, item->address, true);
+ }
+ return ret;
+}
+
+/*
+ * Clear device list and replace it with single device
+ */
+int reassign_device_list(struct listnode *device_list,
+ audio_devices_t type, char *address)
+{
+ if (device_list == NULL)
+ return 0;
+
+ if (!list_empty(device_list))
+ clear_devices(device_list);
+
+ return update_device_list(device_list, type, address, true);
+}
+
+/*
+ * Append source devices to destination devices
+ * Operation: dest devices |= source devices
+ */
+int append_devices(struct listnode *dest, const struct listnode *source)
+{
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
+ int ret = 0;
+
+ if (source == NULL || dest == NULL)
+ return ret;
+
+ list_for_each (node, source) {
+ item = node_to_item(node, struct audio_device_info, list);
+ if (item != NULL)
+ ret = update_device_list(dest, item->type, item->address, true);
+ }
+ return ret;
+}
diff --git a/hal/audio_extn/device_utils.h b/hal/audio_extn/device_utils.h
new file mode 100644
index 0000000..b6d4c9b
--- /dev/null
+++ b/hal/audio_extn/device_utils.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AUDIO_HW_EXTN_DEVICE_UTILS_H
+#define AUDIO_HW_EXTN_DEVICE_UTILS_H
+
+struct audio_device_info {
+ struct listnode list;
+ audio_devices_t type;
+ char address[AUDIO_DEVICE_MAX_ADDRESS_LEN];
+};
+
+int list_length(struct listnode *list);
+bool is_audio_in_device_type(struct listnode *devices);
+bool is_audio_out_device_type(struct listnode *devices);
+bool is_codec_backend_in_device_type(struct listnode *devices);
+bool is_codec_backend_out_device_type(struct listnode *devices);
+bool is_usb_in_device_type(struct listnode *devices);
+bool is_usb_out_device_type(struct listnode *devices);
+const char *get_usb_device_address(struct listnode *devices);
+bool is_sco_in_device_type(struct listnode *devices);
+bool is_sco_out_device_type(struct listnode *devices);
+bool is_a2dp_in_device_type(struct listnode *devices);
+bool is_a2dp_out_device_type(struct listnode *devices);
+int clear_devices(struct listnode *devices);
+bool compare_device_type(struct listnode *devices, audio_devices_t device_type);
+bool compare_devices_for_any_match(struct listnode *d1, struct listnode *d2);
+audio_devices_t get_device_types(struct listnode *devices);
+bool is_single_device_type_equal(struct listnode *devices,
+ audio_devices_t type);
+bool compare_devices(struct listnode *d1, struct listnode *d2);
+int update_device_list(struct listnode *head, audio_devices_t type,
+ const char* address, bool add_device);
+int assign_devices(struct listnode *dest, const struct listnode *source);
+int assign_output_devices(struct listnode *dest, const struct listnode *source);
+int reassign_device_list(struct listnode *device_list,
+ audio_devices_t type, char *address);
+int append_devices(struct listnode *dest, const struct listnode *source);
+
+#endif
diff --git a/hal/audio_extn/dolby.c b/hal/audio_extn/dolby.c
index 335cfbd..f4a1a97 100644
--- a/hal/audio_extn/dolby.c
+++ b/hal/audio_extn/dolby.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, 2020, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2010 The Android Open Source Project
@@ -246,7 +246,7 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.out && (usecase->type == PCM_PLAYBACK) &&
- (usecase->devices & ddp_dev) &&
+ (compare_device_type(&usecase->device_list, ddp_dev)) &&
(usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
((usecase->stream.out->format == AUDIO_FORMAT_AC3) ||
(usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
@@ -264,7 +264,7 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.out && (usecase->type == PCM_PLAYBACK) &&
- (usecase->devices & AUDIO_DEVICE_OUT_ALL) &&
+ is_audio_out_device_type(&usecase->device_list) &&
(usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
((usecase->stream.out->format == AUDIO_FORMAT_AC3) ||
(usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
@@ -273,11 +273,14 @@
* Use wfd /hdmi sink channel cap for dolby params if device is wfd
* or hdmi. Otherwise use stereo configuration
*/
- int channel_cap = usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ?
+ int channel_cap = compare_device_type(&usecase->device_list,
+ AUDIO_DEVICE_OUT_AUX_DIGITAL) ?
adev->cur_hdmi_channels :
- usecase->devices & AUDIO_DEVICE_OUT_PROXY ?
+ compare_device_type(&usecase->device_list,
+ AUDIO_DEVICE_OUT_PROXY) ?
adev->cur_wfd_channels : 2;
- send_ddp_endp_params_stream(usecase->stream.out, usecase->devices,
+ send_ddp_endp_params_stream(usecase->stream.out,
+ get_device_types(&usecase->device_list),
channel_cap, false /* set cache */);
}
}
@@ -302,7 +305,7 @@
sizeof(value));
if (ret >= 0) {
ddp_dev = atoi(value);
- if (!(AUDIO_DEVICE_OUT_ALL & ddp_dev))
+ if (!audio_is_output_device(ddp_dev))
return;
} else
return;
@@ -376,7 +379,7 @@
usecase = node_to_item(node, struct audio_usecase, list);
if ((usecase->type == PCM_PLAYBACK) &&
(usecase->id != USECASE_AUDIO_PLAYBACK_LOW_LATENCY)) {
- endpoint |= usecase->devices & AUDIO_DEVICE_OUT_ALL;
+ endpoint |= is_audio_out_device_type(&usecase->device_list);
send = true;
}
}
@@ -528,7 +531,7 @@
usecase = node_to_item(node, struct audio_usecase, list);
if ((usecase->type == PCM_PLAYBACK) &&
(usecase->id != USECASE_AUDIO_PLAYBACK_LOW_LATENCY)) {
- endpoint |= usecase->devices & AUDIO_DEVICE_OUT_ALL;
+ endpoint |= is_audio_out_device_type(&usecase->device_list);
send = true;
}
}
diff --git a/hal/audio_extn/ffv.c b/hal/audio_extn/ffv.c
index b97eedc..fe6ffa6 100644
--- a/hal/audio_extn/ffv.c
+++ b/hal/audio_extn/ffv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -365,13 +365,13 @@
bool audio_extn_ffv_check_usecase(struct stream_in *in) {
int ret = false;
int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
- audio_devices_t devices = in->device;
audio_source_t source = in->source;
if ((audio_extn_ffv_get_enabled()) &&
(channel_count == 1) &&
(AUDIO_SOURCE_MIC == source) &&
- ((AUDIO_DEVICE_IN_BUILTIN_MIC == devices) || (AUDIO_DEVICE_IN_BACK_MIC == devices)) &&
+ (is_single_device_type_equal(&in->device_list, AUDIO_DEVICE_IN_BUILTIN_MIC) ||
+ is_single_device_type_equal(&in->device_list, AUDIO_DEVICE_IN_BACK_MIC)) &&
(in->format == AUDIO_FORMAT_PCM_16_BIT) &&
(in->sample_rate == FFV_SAMPLING_RATE_16000)) {
in->config.channels = channel_count;
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index 435c377..a0c2410 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -182,7 +182,7 @@
fm_out->format = AUDIO_FORMAT_PCM_16_BIT;
fm_out->usecase = USECASE_AUDIO_PLAYBACK_FM;
fm_out->config = pcm_config_fm;
- fm_out->devices = outputDevices;
+ reassign_device_list(&fm_out->device_list, outputDevices, "");
fmmod.is_fm_running = true;
uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
@@ -195,7 +195,7 @@
uc_info->id = USECASE_AUDIO_PLAYBACK_FM;
uc_info->type = PCM_PLAYBACK;
uc_info->stream.out = fm_out;
- uc_info->devices = outputDevices;
+ reassign_device_list(&uc_info->device_list, outputDevices, "");
uc_info->in_snd_device = SND_DEVICE_NONE;
uc_info->out_snd_device = SND_DEVICE_NONE;
@@ -240,7 +240,7 @@
pcm_start(fmmod.fm_pcm_rx);
pcm_start(fmmod.fm_pcm_tx);
- fmmod.fm_device = fm_out->devices;
+ fmmod.fm_device = get_device_types(&fm_out->device_list);
ALOGD("%s: exit: status(%d)", __func__, ret);
return 0;
@@ -388,7 +388,8 @@
ALOGV("%s: exit", __func__);
}
-void audio_extn_fm_route_on_selected_device(struct audio_device *adev, audio_devices_t device)
+void audio_extn_fm_route_on_selected_device(struct audio_device *adev,
+ struct listnode *devices)
{
struct listnode *node;
struct audio_usecase *usecase;
@@ -397,10 +398,10 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->id == USECASE_AUDIO_PLAYBACK_FM) {
- if (fmmod.fm_device != device) {
+ if (fmmod.fm_device != get_device_types(devices)) {
ALOGV("%s selected routing device %x current device %x"
"are different, reroute on selected device", __func__,
- fmmod.fm_device, device);
+ fmmod.fm_device, get_device_types(devices));
select_devices(adev, usecase->id);
}
}
diff --git a/hal/audio_extn/gef.c b/hal/audio_extn/gef.c
index 83e9d45..69b1e41 100644
--- a/hal/audio_extn/gef.c
+++ b/hal/audio_extn/gef.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -427,15 +427,15 @@
#endif
//this will be called from HAL to notify GEF of new device configuration
-void audio_extn_gef_notify_device_config(audio_devices_t audio_device,
+void audio_extn_gef_notify_device_config(struct listnode *audio_devices,
audio_channel_mask_t channel_mask, int sample_rate, int acdb_id, int app_type)
{
ALOGV("%s: Enter", __func__);
//call into GEF to share channel mask and device info
if (gef_hal_handle.handle && gef_hal_handle.device_config_cb) {
- gef_hal_handle.device_config_cb(gef_hal_handle.gef_ptr, audio_device, channel_mask,
- sample_rate, acdb_id, app_type);
+ gef_hal_handle.device_config_cb(gef_hal_handle.gef_ptr, get_device_types(audio_devices),
+ channel_mask, sample_rate, acdb_id, app_type);
}
ALOGV("%s: Exit", __func__);
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index e646bc1..2b63277 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -309,7 +309,7 @@
uc_info->id = hfpmod.ucid;
uc_info->type = PCM_HFP_CALL;
uc_info->stream.out = adev->primary_output;
- uc_info->devices = adev->primary_output->devices;
+ assign_devices(&uc_info->device_list, &adev->primary_output->device_list);
uc_info->in_snd_device = SND_DEVICE_NONE;
uc_info->out_snd_device = SND_DEVICE_NONE;
@@ -440,6 +440,8 @@
{
int32_t ret = 0;
struct audio_usecase *uc_info;
+ struct listnode *node;
+ struct audio_device_info *item = NULL;
ALOGD("%s: enter", __func__);
hfpmod.is_hfp_running = false;
@@ -484,7 +486,7 @@
}
/* 2. Disable echo reference while stopping hfp */
- fp_platform_set_echo_reference(adev, false, uc_info->devices);
+ fp_platform_set_echo_reference(adev, false, &uc_info->device_list);
/* 3. Get and set stream specific mixer controls */
fp_disable_audio_route(adev, uc_info);
diff --git a/hal/audio_extn/hw_loopback.c b/hal/audio_extn/hw_loopback.c
index afc029b..0b81fde 100644
--- a/hal/audio_extn/hw_loopback.c
+++ b/hal/audio_extn/hw_loopback.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -496,7 +496,8 @@
uc_info_rx->id = USECASE_AUDIO_TRANSCODE_LOOPBACK_RX;
uc_info_rx->type = audio_loopback_mod->uc_type_rx;
uc_info_rx->stream.inout = &active_loopback_patch->patch_stream;
- uc_info_rx->devices = active_loopback_patch->patch_stream.out_config.devices;
+ assign_devices(&uc_info_rx->device_list,
+ &active_loopback_patch->patch_stream.out_config.device_list);
uc_info_rx->in_snd_device = SND_DEVICE_NONE;
uc_info_rx->out_snd_device = SND_DEVICE_NONE;
@@ -504,7 +505,8 @@
uc_info_tx->id = USECASE_AUDIO_TRANSCODE_LOOPBACK_TX;
uc_info_tx->type = audio_loopback_mod->uc_type_tx;
uc_info_tx->stream.inout = &active_loopback_patch->patch_stream;
- uc_info_tx->devices = active_loopback_patch->patch_stream.in_config.devices;
+ assign_devices(&uc_info_tx->device_list,
+ &active_loopback_patch->patch_stream.in_config.device_list);
uc_info_tx->in_snd_device = SND_DEVICE_NONE;
uc_info_tx->out_snd_device = SND_DEVICE_NONE;
@@ -678,7 +680,7 @@
stream_cfg->sample_rate = port_cfg->sample_rate;
stream_cfg->channel_mask = port_cfg->channel_mask;
stream_cfg->format = port_cfg->format;
- stream_cfg->devices = port_cfg->ext.device.type;
+ reassign_device_list(&stream_cfg->device_list, port_cfg->ext.device.type, "");
stream_cfg->bit_width = format_to_bitwidth(port_cfg->format);
}
/* API to create audio patch */
diff --git a/hal/audio_extn/keep_alive.c b/hal/audio_extn/keep_alive.c
index 79f2bb0..15725b2 100644
--- a/hal/audio_extn/keep_alive.c
+++ b/hal/audio_extn/keep_alive.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2018, 2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -72,7 +72,7 @@
ka_mode_t prev_mode;
bool done;
void * userdata;
- audio_devices_t active_devices;
+ struct listnode active_devices;
} keep_alive_t;
struct keep_alive_cmd {
@@ -128,7 +128,7 @@
}
ka.done = false;
ka.prev_mode = KEEP_ALIVE_OUT_NONE;
- ka.active_devices = AUDIO_DEVICE_NONE;
+ list_init(&ka.active_devices);
pthread_mutex_init(&ka.lock, (const pthread_mutexattr_t *) NULL);
pthread_cond_init(&ka.cond, (const pthread_condattr_t *) NULL);
@@ -164,38 +164,38 @@
ALOGV("%s deinit done", __func__);
}
-audio_devices_t get_device_id_from_mode(ka_mode_t ka_mode)
+void get_device_id_from_mode(ka_mode_t ka_mode,
+ struct listnode *out_devices)
{
struct audio_device * adev = (struct audio_device *)ka.userdata;
- audio_devices_t out_device = AUDIO_DEVICE_NONE;
+
switch (ka_mode)
{
case KEEP_ALIVE_OUT_PRIMARY:
if (adev->primary_output) {
- if (adev->primary_output->devices & AUDIO_DEVICE_OUT_ALL)
- out_device = adev->primary_output->devices & AUDIO_DEVICE_OUT_ALL;
+ if (is_audio_out_device_type(&adev->primary_output->device_list))
+ assign_output_devices(out_devices, &adev->primary_output->device_list);
else
- out_device = AUDIO_DEVICE_OUT_SPEAKER;
+ reassign_device_list(out_devices, AUDIO_DEVICE_OUT_SPEAKER, "");
}
else {
- out_device = AUDIO_DEVICE_OUT_SPEAKER;
+ reassign_device_list(out_devices, AUDIO_DEVICE_OUT_SPEAKER, "");
}
break;
case KEEP_ALIVE_OUT_HDMI:
- out_device = AUDIO_DEVICE_OUT_AUX_DIGITAL;
+ reassign_device_list(out_devices, AUDIO_DEVICE_OUT_AUX_DIGITAL, "");
break;
-
+ case KEEP_ALIVE_OUT_NONE:
default:
- out_device = AUDIO_DEVICE_NONE;
+ break;
}
- return out_device;
}
void keep_alive_start(ka_mode_t ka_mode)
{
struct audio_device * adev = (struct audio_device *)ka.userdata;
- audio_devices_t out_devices = AUDIO_DEVICE_NONE;
+ struct listnode out_devices;
pthread_mutex_lock(&ka.lock);
ALOGV("%s: mode %x", __func__, ka_mode);
@@ -204,27 +204,32 @@
goto exit;
}
- out_devices = get_device_id_from_mode(ka_mode);
- if ((out_devices == ka.active_devices) && (ka.state == STATE_ACTIVE)) {
- ALOGV(" %s : Already feeding silence to device %x",__func__, out_devices);
+ list_init(&out_devices);
+ get_device_id_from_mode(ka_mode, &out_devices);
+ if (compare_devices(&out_devices, &ka.active_devices) &&
+ (ka.state == STATE_ACTIVE)) {
+ ALOGV(" %s : Already feeding silence to device %x",__func__,
+ get_device_types(&out_devices));
ka.prev_mode |= ka_mode;
goto exit;
}
- ALOGV(" %s : active devices %x, new device %x",__func__, ka.active_devices, out_devices);
+ ALOGV(" %s : active devices %x, new device %x",__func__,
+ get_device_types(&ka.active_devices), get_device_types(&out_devices));
- if (out_devices == AUDIO_DEVICE_NONE)
+ if (list_empty(&out_devices))
goto exit;
if (audio_extn_passthru_is_active()) {
- ka.active_devices &= ~AUDIO_DEVICE_OUT_AUX_DIGITAL;
- if(ka.active_devices == AUDIO_DEVICE_NONE)
+ update_device_list(&ka.active_devices, AUDIO_DEVICE_OUT_AUX_DIGITAL,
+ "", false);
+ if (list_empty(&ka.active_devices))
goto exit;
}
- ka.active_devices |= out_devices;
+ append_devices(&ka.active_devices, &out_devices);
ka.prev_mode |= ka_mode;
if (ka.state == STATE_ACTIVE) {
- ka.out->devices = ka.active_devices;
+ assign_devices(&ka.out->device_list, &ka.active_devices);
select_devices(adev, USECASE_AUDIO_PLAYBACK_SILENCE);
} else if (ka.state == STATE_IDLE) {
keep_alive_start_l();
@@ -263,7 +268,7 @@
}
ka.out->flags = 0;
- ka.out->devices = ka.active_devices;
+ assign_devices(&ka.out->device_list, &ka.active_devices);
ka.out->dev = adev;
ka.out->format = AUDIO_FORMAT_PCM_16_BIT;
ka.out->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
@@ -274,6 +279,7 @@
usecase->stream.out = ka.out;
usecase->type = PCM_PLAYBACK;
usecase->id = USECASE_AUDIO_PLAYBACK_SILENCE;
+ list_init(&usecase->device_list);
usecase->out_snd_device = SND_DEVICE_NONE;
usecase->in_snd_device = SND_DEVICE_NONE;
@@ -304,7 +310,7 @@
void keep_alive_stop(ka_mode_t ka_mode)
{
struct audio_device * adev = (struct audio_device *)ka.userdata;
- audio_devices_t out_devices;
+ struct listnode out_devices;
if (ka.state == STATE_DISABLED)
return;
@@ -312,21 +318,23 @@
ALOGV("%s: mode %x", __func__, ka_mode);
if (ka_mode && (ka.state != STATE_ACTIVE)) {
+ get_device_id_from_mode(ka_mode, &out_devices);
ALOGV(" %s : Can't stop, keep_alive",__func__);
- ALOGV(" %s : keep_alive is not running on device %x",__func__, get_device_id_from_mode(ka_mode));
+ ALOGV(" %s : keep_alive is not running on device %x",__func__,
+ get_device_types(&out_devices));
ka.prev_mode |= ka_mode;
goto exit;
}
- out_devices = get_device_id_from_mode(ka_mode);
+ get_device_id_from_mode(ka_mode, &out_devices);
if (ka.prev_mode & ka_mode) {
ka.prev_mode &= ~ka_mode;
- ka.active_devices = get_device_id_from_mode(ka.prev_mode);
+ get_device_id_from_mode(ka.prev_mode, &ka.active_devices);
}
- if (ka.active_devices == AUDIO_DEVICE_NONE) {
+ if (list_empty(&ka.active_devices)) {
keep_alive_cleanup();
- } else if (ka.out->devices != ka.active_devices){
- ka.out->devices = ka.active_devices;
+ } else if (!compare_devices(&ka.out->device_list, &ka.active_devices)) {
+ assign_devices(&ka.out->device_list, &ka.active_devices);
select_devices(adev, USECASE_AUDIO_PLAYBACK_SILENCE);
}
exit:
@@ -362,7 +370,7 @@
}
pcm_close(ka.pcm);
ka.pcm = NULL;
- ka.active_devices = KEEP_ALIVE_OUT_NONE;
+ clear_devices(&ka.active_devices);
return 0;
}
diff --git a/hal/audio_extn/maxxaudio.c b/hal/audio_extn/maxxaudio.c
index a8f09fc..88de2f2 100644
--- a/hal/audio_extn/maxxaudio.c
+++ b/hal/audio_extn/maxxaudio.c
@@ -100,7 +100,7 @@
typedef struct ma_audio_cal_common_settings {
unsigned int app_type;
- unsigned int device;
+ struct listnode devices;
} ma_audio_cal_common_settings_t;
struct ma_audio_cal_settings {
@@ -237,16 +237,16 @@
(usecase->id == USECASE_AUDIO_PLAYBACK_LOW_LATENCY) ||
(usecase->id == USECASE_AUDIO_PLAYBACK_OFFLOAD)) &&
/* support devices */
- ((usecase->devices & AUDIO_DEVICE_OUT_SPEAKER) ||
- (usecase->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
- (audio_is_usb_out_device(usecase->devices) &&
+ (compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_SPEAKER) ||
+ compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
+ (is_usb_out_device_type(&usecase->device_list) &&
ma_supported_usb())))
/* TODO: enable A2DP when it is ready */
return true;
ALOGV("%s: not support type %d usecase %d device %d",
- __func__, usecase->type, usecase->id, usecase->devices);
+ __func__, usecase->type, usecase->id, get_device_types(&usecase->device_list));
return false;
}
@@ -268,7 +268,9 @@
ma_cal->version.major = AUDIO_CAL_SETTINGS_VERSION_MAJOR_DEFAULT;
ma_cal->version.minor = AUDIO_CAL_SETTINGS_VERSION_MINOR_DEFAULT;
ma_cal->common.app_type = APP_TYPE_DEFAULT;
- ma_cal->common.device = DEVICE_DEFAULT;
+ list_init(&ma_cal->common.devices);
+ update_device_list(&ma_cal->common.devices, DEVICE_DEFAULT,
+ "", true);
ma_cal->effect_scope_flag = EFFECTIVE_SCOPE_ALL;
}
@@ -286,10 +288,10 @@
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.out && valid_usecase(usecase)) {
ma_cal.common.app_type = usecase->stream.out->app_type_cfg.app_type;
- ma_cal.common.device = usecase->stream.out->devices;
+ assign_devices(&ma_cal.common.devices, &usecase->stream.out->device_list);
ALOGV("%s: send usecase(%d) app_type(%d) device(%d)",
__func__, usecase->id, ma_cal.common.app_type,
- ma_cal.common.device);
+ get_device_types(&ma_cal.common.devices));
switch (cmd) {
case MA_CMD_VOL:
@@ -304,7 +306,8 @@
case MA_CMD_SWAP_ENABLE:
/* lr swap only enable for speaker path */
- if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (compare_device_type(&ma_cal.common.devices,
+ 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.");
@@ -322,7 +325,8 @@
break;
case MA_CMD_ROTATE_ENABLE:
- if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (compare_device_type(&ma_cal.common.devices,
+ 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.",
@@ -692,16 +696,17 @@
/* update audio_cal and send it */
ma_cal.common.app_type = usecase->stream.out->app_type_cfg.app_type;
- ma_cal.common.device = usecase->stream.out->devices;
+ assign_devices(&ma_cal.common.devices, &usecase->stream.out->device_list);
ALOGV("%s: send usecase(%d) app_type(%d) device(%d)",
__func__, usecase->id, ma_cal.common.app_type,
- ma_cal.common.device);
+ get_device_types(&ma_cal.common.devices));
pthread_mutex_lock(&my_data->lock);
if (is_active()) {
- if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (compare_device_type(&ma_cal.common.devices,
+ AUDIO_DEVICE_OUT_SPEAKER)) {
if (my_data->orientation_used)
ma_set_rotation_l(usecase->stream.out->dev,
my_data->dispaly_orientation);
diff --git a/hal/audio_extn/passthru.c b/hal/audio_extn/passthru.c
index e900932..293ffac 100644
--- a/hal/audio_extn/passthru.c
+++ b/hal/audio_extn/passthru.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -244,14 +244,21 @@
*/
bool passthru_should_drop_data(struct stream_out * out)
{
+ uint32_t compr_passthr = 0;
/*Drop data only
*stream is routed to HDMI and
*stream has PCM format or
*if a compress offload (DSP decode) session
*/
- if ((out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
+#ifdef AUDIO_QGKI_ENABLED
+ /* out->compr_config.codec->reserved[0] is for compr_passthr */
+ compr_passthr = out->compr_config.codec->reserved[0];
+#else
+ compr_passthr = out->compr_config.codec->compr_passthr;
+#endif
+ if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
(((out->format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) ||
- ((out->compr_config.codec != NULL) && (out->compr_config.codec->compr_passthr == LEGACY_PCM)))) {
+ ((out->compr_config.codec != NULL) && (compr_passthr == LEGACY_PCM)))) {
if (android_atomic_acquire_load(&compress_passthru_active) > 0) {
ALOGI("drop data as pass thru is active");
return true;
@@ -285,7 +292,7 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.out && usecase->type == PCM_PLAYBACK &&
- usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
o = usecase->stream.out;
temp = o->config.period_size * 1000000LL / o->sample_rate;
if (temp > max_period_us)
@@ -314,7 +321,7 @@
android_atomic_dec(&compress_passthru_active);
}
- if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
ALOGD("%s: passthru on aux digital, start keep alive", __func__);
fp_audio_extn_keep_alive_start(KEEP_ALIVE_OUT_HDMI);
}
@@ -461,21 +468,30 @@
struct audio_device *adev, struct stream_out *out,
const void *buffer __unused, size_t bytes __unused)
{
+ uint32_t compr_passthr = 0;
+
if(out->compr_config.codec != NULL) {
if (passthru_is_passt_supported(adev, out)) {
ALOGV("%s:PASSTHROUGH", __func__);
- out->compr_config.codec->compr_passthr = PASSTHROUGH;
+ compr_passthr = PASSTHROUGH;
} else if (passthru_is_convert_supported(adev, out)) {
ALOGV("%s:PASSTHROUGH CONVERT", __func__);
- out->compr_config.codec->compr_passthr = PASSTHROUGH_CONVERT;
+ compr_passthr = PASSTHROUGH_CONVERT;
} else if (out->format == AUDIO_FORMAT_IEC61937) {
ALOGV("%s:PASSTHROUGH IEC61937", __func__);
- out->compr_config.codec->compr_passthr = PASSTHROUGH_IEC61937;
+ compr_passthr = PASSTHROUGH_IEC61937;
} else {
ALOGV("%s:NO PASSTHROUGH", __func__);
- out->compr_config.codec->compr_passthr = LEGACY_PCM;
+ compr_passthr = LEGACY_PCM;
}
}
+
+#ifdef AUDIO_QGKI_ENABLED
+ /* out->compr_config.codec->reserved[0] is for compr_passthr */
+ out->compr_config.codec->reserved[0] = compr_passthr;
+#else
+ out->compr_config.codec->compr_passthr = compr_passthr;
+#endif
}
bool passthru_is_passthrough_stream(struct stream_out *out)
@@ -486,7 +502,7 @@
}
//check supported device, currently only on HDMI.
- if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
//passthrough flag
if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)
return true;
diff --git a/hal/audio_extn/qaf.c b/hal/audio_extn/qaf.c
index 4ec524e..46e625d 100644
--- a/hal/audio_extn/qaf.c
+++ b/hal/audio_extn/qaf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -464,7 +464,9 @@
}
if ((p_qaf->qaf_mod[i].stream_out[QAF_OUT_OFFLOAD])
- && (p_qaf->qaf_mod[i].stream_out[QAF_OUT_OFFLOAD]->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ && compare_device_type(
+ &p_qaf->qaf_mod[i].stream_out[QAF_OUT_OFFLOAD]->device_list,
+ AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
adev_close_output_stream((struct audio_hw_device *)p_qaf->adev,
(struct audio_stream_out *)(p_qaf->qaf_mod[i].stream_out[QAF_OUT_OFFLOAD]));
p_qaf->qaf_mod[i].stream_out[QAF_OUT_OFFLOAD] = NULL;
@@ -525,7 +527,7 @@
config.offload_info.channel_mask = config.channel_mask = out->channel_mask;
//Device is copied from the QAF passthrough input stream.
- devices = out->devices;
+ devices = get_device_types(&out->device_list);
flags = out->flags;
ret = adev_open_output_stream((struct audio_hw_device *)p_qaf->adev,
@@ -711,7 +713,7 @@
ALOGD("%s: enter: stream(%p)usecase(%d: %s) devices(%#x)",
__func__, &out->stream, out->usecase, use_case_table[out->usecase],
- out->devices);
+ get_device_types(&out->device_list));
if (CARD_STATUS_OFFLINE == out->card_status ||
CARD_STATUS_OFFLINE == adev->card_status) {
@@ -781,7 +783,8 @@
}
}
- if ((adev->is_channel_status_set == false) && (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ if ((adev->is_channel_status_set == false) &&
+ compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
audio_utils_set_hdmi_channel_status(out, (char *)buffer, bytes);
adev->is_channel_status_set = true;
}
@@ -1637,9 +1640,9 @@
audio_devices_t devices;
if (qaf_mod->stream_in[QAF_IN_MAIN])
- devices = qaf_mod->stream_in[QAF_IN_MAIN]->devices;
+ devices = get_device_types(&qaf_mod->stream_in[QAF_IN_MAIN]->device_list);
else
- devices = qaf_mod->stream_in[QAF_IN_PCM]->devices;
+ devices = get_device_types(&qaf_mod->stream_in[QAF_IN_PCM]->device_list);
//If multi channel pcm or passthrough is already enabled then remove the hdmi flag from device.
if (p_qaf->mch_pcm_hdmi_enabled || p_qaf->passthrough_enabled) {
@@ -2348,7 +2351,7 @@
/* Setting new device information to the mm module input streams.
* This is needed if QAF module output streams are not created yet.
*/
- out->devices = val;
+ reassign_device_list(&out->device_list, val, "");
#ifndef A2DP_OFFLOAD_ENABLED
if (val == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) {
diff --git a/hal/audio_extn/qap.c b/hal/audio_extn/qap.c
index 0625737..30ebe6d 100644
--- a/hal/audio_extn/qap.c
+++ b/hal/audio_extn/qap.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -431,7 +431,9 @@
}
if ((p_qap->qap_mod[i].stream_out[QAP_OUT_OFFLOAD])
- && (p_qap->qap_mod[i].stream_out[QAP_OUT_OFFLOAD]->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ && compare_device_type(
+ &p_qap->qap_mod[i].stream_out[QAP_OUT_OFFLOAD]->device_list,
+ AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
adev_close_output_stream((struct audio_hw_device *)p_qap->adev,
(struct audio_stream_out *)(p_qap->qap_mod[i].stream_out[QAP_OUT_OFFLOAD]));
p_qap->qap_mod[i].stream_out[QAP_OUT_OFFLOAD] = NULL;
@@ -492,7 +494,7 @@
config.offload_info.channel_mask = config.channel_mask = out->channel_mask;
//Device is copied from the QAP passthrough input stream.
- devices = out->devices;
+ devices = get_device_types(&out->device_list);
flags = out->flags;
ret = adev_open_output_stream((struct audio_hw_device *)p_qap->adev,
@@ -870,7 +872,7 @@
ALOGD("%s: enter: stream(%p)usecase(%d: %s) devices(%#x)",
__func__, &out->stream, out->usecase, use_case_table[out->usecase],
- out->devices);
+ get_device_types(&out->device_list));
if (CARD_STATUS_OFFLINE == out->card_status ||
CARD_STATUS_OFFLINE == adev->card_status) {
@@ -959,7 +961,8 @@
}
}
- if ((adev->is_channel_status_set == false) && (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+ if ((adev->is_channel_status_set == false) &&
+ compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
audio_utils_set_hdmi_channel_status(out, (char *)buffer, bytes);
adev->is_channel_status_set = true;
}
@@ -1759,9 +1762,9 @@
audio_devices_t devices;
if (qap_mod->stream_in[QAP_IN_MAIN])
- devices = qap_mod->stream_in[QAP_IN_MAIN]->devices;
+ devices = get_device_types(&qap_mod->stream_in[QAP_IN_MAIN]->device_list);
else
- devices = qap_mod->stream_in[QAP_IN_PCM]->devices;
+ devices = get_device_types(&qap_mod->stream_in[QAP_IN_PCM]->device_list);
//If multi channel pcm or passthrough is already enabled then remove the hdmi flag from device.
if (p_qap->mch_pcm_hdmi_enabled || p_qap->passthrough_enabled) {
@@ -2595,6 +2598,7 @@
int ret = 0;
int err = 0;
struct qap_module *qap_mod = NULL;
+ char *address = "";
DEBUG_MSG("usecase(%d: %s) kvpairs: %s", out->usecase, use_case_table[out->usecase], kvpairs);
@@ -2612,7 +2616,7 @@
/* Setting new device information to the mm module input streams.
* This is needed if QAP module output streams are not created yet.
*/
- out->devices = val;
+ reassign_device_list(&out->device_list, val, address);
#ifndef SPLIT_A2DP_ENABLED
if (val == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) {
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index a175b83..4ef3581 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, 2016-2019 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 2016-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -53,9 +53,8 @@
#define MINOR_VERSION(ver) ((ver) & 0x00ff)
/* Proprietary interface version used for compatibility with STHAL */
-#define STHAL_PROP_API_VERSION_1_0 MAKE_HAL_VERSION(1, 0)
-#define STHAL_PROP_API_VERSION_1_1 MAKE_HAL_VERSION(1, 1)
-#define STHAL_PROP_API_CURRENT_VERSION STHAL_PROP_API_VERSION_1_1
+#define STHAL_PROP_API_VERSION_2_0 MAKE_HAL_VERSION(2, 0)
+#define STHAL_PROP_API_CURRENT_VERSION STHAL_PROP_API_VERSION_2_0
#define ST_EVENT_CONFIG_MAX_STR_VALUE 32
#define ST_DEVICE_HANDSET_MIC 1
@@ -129,7 +128,7 @@
typedef struct sound_trigger_event_info sound_trigger_event_info_t;
struct sound_trigger_device_info {
- int device;
+ struct listnode devices;
};
struct sound_trigger_get_param_data {
@@ -571,7 +570,7 @@
struct audio_event_info ev_info;
audio_event_type_t ev;
/*Initialize to invalid device*/
- ev_info.device_info.device = -1;
+ list_init(&ev_info.device_info.devices);
if (!st_dev)
return;
@@ -581,14 +580,10 @@
return;
}
- if ((st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0) &&
- (uc_info->type != PCM_PLAYBACK))
- return;
-
if ((uc_info->in_snd_device >= SND_DEVICE_IN_BEGIN &&
uc_info->in_snd_device < SND_DEVICE_IN_END)) {
if (is_same_as_st_device(uc_info->in_snd_device))
- ev_info.device_info.device = ST_DEVICE_HANDSET_MIC;
+ update_device_list(&ev_info.device_info.devices, ST_DEVICE_HANDSET_MIC, "", true);
} else {
ALOGE("%s: invalid input device 0x%x, for event %d",
__func__, uc_info->in_snd_device, event);
@@ -599,9 +594,10 @@
if (raise_event) {
if (uc_info->type == PCM_PLAYBACK) {
if (uc_info->stream.out)
- ev_info.device_info.device = uc_info->stream.out->devices;
+ assign_devices(&ev_info.device_info.devices, &uc_info->stream.out->device_list);
else
- ev_info.device_info.device = AUDIO_DEVICE_OUT_SPEAKER;
+ reassign_device_list(&ev_info.device_info.devices,
+ AUDIO_DEVICE_OUT_SPEAKER, "");
switch(event) {
case ST_EVENT_STREAM_FREE:
st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE, &ev_info);
@@ -629,9 +625,9 @@
void audio_extn_sound_trigger_update_battery_status(bool charging)
{
- struct audio_event_info ev_info;
+ struct audio_event_info ev_info = {{0}, {0}};
- if (!st_dev || st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0)
+ if (!st_dev)
return;
ev_info.u.value = charging;
diff --git a/hal/audio_extn/source_track.c b/hal/audio_extn/source_track.c
index 064fad8..9705d55 100644
--- a/hal/audio_extn/source_track.c
+++ b/hal/audio_extn/source_track.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -230,7 +230,7 @@
if (usecase && (usecase->id != USECASE_AUDIO_SPKR_CALIB_TX)) {
if (is_stt_supported_snd_device(usecase->in_snd_device)) {
- in_device = get_input_audio_device(usecase->devices);
+ in_device = get_input_audio_device(get_device_types(&usecase->device_list));
ret = add_audio_intf_name_to_mixer_ctl(in_device, mixer_ctl_name,
audio_device_to_interface_table, audio_device_to_interface_table_len);
} else {
diff --git a/hal/audio_extn/ssr.c b/hal/audio_extn/ssr.c
index d83b508..8cb7b4e 100644
--- a/hal/audio_extn/ssr.c
+++ b/hal/audio_extn/ssr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, 2020, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -339,7 +339,7 @@
bool ssr_check_usecase(struct stream_in *in) {
int ret = false;
int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
- audio_devices_t devices = in->device;
+ audio_devices_t devices = get_device_types(&in->device_list);
audio_source_t source = in->source;
if ((ssr_get_enabled()) &&
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index a2d559d..531c4b2 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016-2020, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -1472,7 +1472,7 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->type == PCM_PLAYBACK &&
- audio_is_usb_out_device(usecase->devices & AUDIO_DEVICE_OUT_ALL_USB )) {
+ is_usb_out_device_type(&usecase->device_list)) {
switch (usecase->id) {
case USECASE_AUDIO_PLAYBACK_MMAP:
case USECASE_AUDIO_PLAYBACK_ULL:
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 92887f0..e56fee3 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -672,7 +672,7 @@
void audio_extn_utils_update_stream_input_app_type_cfg(void *platform,
struct listnode *streams_input_cfg_list,
- audio_devices_t devices __unused,
+ struct listnode *devices __unused,
audio_input_flags_t flags,
audio_format_t format,
uint32_t sample_rate,
@@ -710,7 +710,7 @@
void audio_extn_utils_update_stream_output_app_type_cfg(void *platform,
struct listnode *streams_output_cfg_list,
- audio_devices_t devices,
+ struct listnode *devices,
audio_output_flags_t flags,
audio_format_t format,
uint32_t sample_rate,
@@ -724,7 +724,7 @@
struct stream_format *sf_info;
char value[PROPERTY_VALUE_MAX] = {0};
- if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (compare_device_type(devices, AUDIO_DEVICE_OUT_SPEAKER)) {
int bw = platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
if ((-ENOSYS != bw) && (bit_width > (uint32_t)bw))
bit_width = (uint32_t)bw;
@@ -866,7 +866,7 @@
case PCM_PLAYBACK:
audio_extn_utils_update_stream_output_app_type_cfg(adev->platform,
&adev->streams_output_cfg_list,
- usecase->stream.out->devices,
+ &usecase->stream.out->device_list,
usecase->stream.out->flags,
usecase->stream.out->hal_op_format,
usecase->stream.out->sample_rate,
@@ -882,7 +882,7 @@
else
audio_extn_utils_update_stream_input_app_type_cfg(adev->platform,
&adev->streams_input_cfg_list,
- usecase->stream.in->device,
+ &usecase->stream.in->device_list,
usecase->stream.in->flags,
usecase->stream.in->format,
usecase->stream.in->sample_rate,
@@ -894,7 +894,7 @@
case TRANSCODE_LOOPBACK_RX :
audio_extn_utils_update_stream_output_app_type_cfg(adev->platform,
&adev->streams_output_cfg_list,
- usecase->stream.inout->out_config.devices,
+ &usecase->stream.inout->out_config.device_list,
0,
usecase->stream.inout->out_config.format,
usecase->stream.inout->out_config.sample_rate,
@@ -1012,7 +1012,7 @@
goto exit_send_app_type_cfg;
}
- if (usecase->devices & AUDIO_DEVICE_OUT_BUS)
+ if (compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_BUS))
is_bus_dev_usecase = true;
snd_device = usecase->out_snd_device;
@@ -1118,7 +1118,8 @@
if (usecase->id == USECASE_AUDIO_PLAYBACK_VOIP) {
usecase->stream.out->app_type_cfg.sample_rate = usecase->stream.out->sample_rate;
- } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
+ } else if (compare_device_type(&usecase->stream.out->device_list,
+ AUDIO_DEVICE_OUT_SPEAKER)) {
usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
} else if ((snd_device == SND_DEVICE_OUT_HDMI ||
snd_device == SND_DEVICE_OUT_USB_HEADSET ||
@@ -1138,7 +1139,7 @@
(usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
/* Reset to default if no native stream is active*/
usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
- } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ } else if (is_a2dp_out_device_type(&usecase->stream.out->device_list)) {
/*
* For a2dp playback get encoder sampling rate and set copp sampling rate,
* for bit width use the stream param only.
@@ -2101,7 +2102,7 @@
backend = platform_get_snd_device_backend_interface(usecase->out_snd_device);
if (!backend) {
ALOGE("%s: Unsupported device %d", __func__,
- usecase->stream.out->devices);
+ get_device_types(&usecase->stream.out->device_list));
ret = -EINVAL;
goto done;
}
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index f70883d..58bbfb5 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -660,7 +660,7 @@
uint32_t *dsp_frames) {
// Adjustment accounts for A2dp encoder latency with offload usecases
// Note: Encoder latency is returned in ms.
- if (AUDIO_DEVICE_OUT_ALL_A2DP & out->devices) {
+ if (is_a2dp_out_device_type(&out->device_list)) {
unsigned long offset =
(audio_extn_a2dp_get_encoder_latency() * out->sample_rate / 1000);
*dsp_frames = (*dsp_frames > offset) ? (*dsp_frames - offset) : 0;
@@ -682,23 +682,20 @@
}
}
-static inline void patch_map_remove(struct audio_device *adev,
+static inline void patch_map_remove_l(struct audio_device *adev,
audio_patch_handle_t patch_handle)
{
if (patch_handle == AUDIO_PATCH_HANDLE_NONE)
return;
- pthread_mutex_lock(&adev->lock);
struct audio_patch_info *p_info =
hashmapGet(adev->patch_map, (void *) (intptr_t) patch_handle);
if (p_info) {
ALOGV("%s: Remove patch %d", __func__, patch_handle);
hashmapRemove(adev->patch_map, (void *) (intptr_t) patch_handle);
free(p_info->patch);
- pthread_mutex_destroy(&p_info->lock);
free(p_info);
}
- pthread_mutex_unlock(&adev->lock);
}
static inline int io_streams_map_insert(struct audio_device *adev,
@@ -715,14 +712,13 @@
}
s_info->stream = stream;
s_info->patch_handle = patch_handle;
- pthread_mutex_init(&s_info->lock, (const pthread_mutexattr_t *) NULL);
pthread_mutex_lock(&adev->lock);
struct audio_stream_info *stream_info =
hashmapPut(adev->io_streams_map, (void *) (intptr_t) handle, (void *) s_info);
- pthread_mutex_unlock(&adev->lock);
if (stream_info != NULL)
free(stream_info);
+ pthread_mutex_unlock(&adev->lock);
ALOGD("%s: Added stream in io_streams_map with handle %d", __func__, handle);
return 0;
}
@@ -733,24 +729,22 @@
pthread_mutex_lock(&adev->lock);
struct audio_stream_info *s_info =
hashmapRemove(adev->io_streams_map, (void *) (intptr_t) handle);
- pthread_mutex_unlock(&adev->lock);
if (s_info == NULL)
- return;
+ goto done;
ALOGD("%s: Removed stream with handle %d", __func__, handle);
- patch_map_remove(adev, s_info->patch_handle);
- pthread_mutex_destroy(&s_info->lock);
+ patch_map_remove_l(adev, s_info->patch_handle);
free(s_info);
+done:
+ pthread_mutex_unlock(&adev->lock);
return;
}
-static struct audio_patch_info* fetch_patch_info(struct audio_device *adev,
+static struct audio_patch_info* fetch_patch_info_l(struct audio_device *adev,
audio_patch_handle_t handle)
{
struct audio_patch_info *p_info = NULL;
- pthread_mutex_lock(&adev->lock);
p_info = (struct audio_patch_info *)
hashmapGet(adev->patch_map, (void *) (intptr_t) handle);
- pthread_mutex_unlock(&adev->lock);
return p_info;
}
@@ -1182,6 +1176,7 @@
char mixer_path[MIXER_PATH_MAX_LENGTH];
struct stream_out *out = NULL;
struct stream_in *in = NULL;
+ struct listnode out_devices;
int ret = 0;
if (usecase == NULL)
@@ -1196,25 +1191,30 @@
if (in) {
if (in->enable_aec || in->enable_ec_port) {
- audio_devices_t out_device = AUDIO_DEVICE_OUT_SPEAKER;
+ list_init(&out_devices);
+ update_device_list(&out_devices, AUDIO_DEVICE_OUT_SPEAKER, "", true);
struct listnode *node;
struct audio_usecase *voip_usecase = get_usecase_from_list(adev,
USECASE_AUDIO_PLAYBACK_VOIP);
if (voip_usecase) {
- out_device = voip_usecase->stream.out->devices;
+ assign_devices(&out_devices,
+ &voip_usecase->stream.out->device_list);
} else if (adev->primary_output &&
!adev->primary_output->standby) {
- out_device = adev->primary_output->devices;
+ assign_devices(&out_devices,
+ &adev->primary_output->device_list);
} else {
list_for_each(node, &adev->usecase_list) {
uinfo = node_to_item(node, struct audio_usecase, list);
if (uinfo->type != PCM_CAPTURE) {
- out_device = uinfo->stream.out->devices;
+ assign_devices(&out_devices,
+ &uinfo->stream.out->device_list);
break;
}
}
}
- platform_set_echo_reference(adev, true, out_device);
+
+ platform_set_echo_reference(adev, true, &out_devices);
in->ec_opened = true;
}
}
@@ -1245,7 +1245,7 @@
if (usecase->type == PCM_CAPTURE) {
in = usecase->stream.in;
- if (in && is_loopback_input_device(in->device)) {
+ if (in && is_loopback_input_device(get_device_types(&in->device_list))) {
ALOGD("%s: set custom mtmx params v1", __func__);
audio_extn_set_custom_mtmx_params_v1(adev, usecase, true);
}
@@ -1296,7 +1296,9 @@
if (usecase->type == PCM_CAPTURE) {
struct stream_in *in = usecase->stream.in;
if (in && in->ec_opened) {
- platform_set_echo_reference(in->dev, false, AUDIO_DEVICE_NONE);
+ struct listnode out_devices;
+ list_init(&out_devices);
+ platform_set_echo_reference(in->dev, false, &out_devices);
in->ec_opened = false;
}
}
@@ -1305,7 +1307,7 @@
if (usecase->type == PCM_CAPTURE) {
in = usecase->stream.in;
- if (in && is_loopback_input_device(in->device)) {
+ if (in && is_loopback_input_device(get_device_types(&in->device_list))) {
ALOGD("%s: reset custom mtmx params v1", __func__);
audio_extn_set_custom_mtmx_params_v1(adev, usecase, false);
}
@@ -1598,35 +1600,39 @@
struct audio_usecase *new_uc,
snd_device_t new_snd_device)
{
- audio_devices_t a1, a2;
+ struct listnode a1, a2;
snd_device_t d1 = uc->out_snd_device;
snd_device_t d2 = new_snd_device;
+ list_init(&a1);
+ list_init(&a2);
+
switch (uc->type) {
case TRANSCODE_LOOPBACK_RX :
- a1 = uc->stream.inout->out_config.devices;
- a2 = new_uc->stream.inout->out_config.devices;
+ assign_devices(&a1, &uc->stream.inout->out_config.device_list);
+ assign_devices(&a2, &new_uc->stream.inout->out_config.device_list);
break;
default :
- a1 = uc->stream.out->devices;
- a2 = new_uc->stream.out->devices;
+ assign_devices(&a1, &uc->stream.out->device_list);
+ assign_devices(&a2, &new_uc->stream.out->device_list);
break;
}
// Treat as a special case when a1 and a2 are not disjoint
- if ((a1 != a2) && (a1 & a2)) {
+ if (!compare_devices(&a1, &a2) &&
+ compare_devices_for_any_match(&a1 ,&a2)) {
snd_device_t d3[2];
int num_devices = 0;
int ret = platform_split_snd_device(platform,
- popcount(a1) > 1 ? d1 : d2,
+ list_length(&a1) > 1 ? d1 : d2,
&num_devices,
d3);
if (ret < 0) {
if (ret != -ENOSYS) {
ALOGW("%s failed to split snd_device %d",
__func__,
- popcount(a1) > 1 ? d1 : d2);
+ list_length(&a1) > 1 ? d1 : d2);
}
goto end;
}
@@ -1634,7 +1640,7 @@
if (platform_check_backends_match(d3[0], d3[1])) {
return d2; // case 5
} else {
- if (popcount(a1) > 1)
+ if (list_length(&a1) > 1)
return d1; //case 7
// check if d1 is related to any of d3's
if (d1 == d3[0] || d1 == d3[1])
@@ -1716,12 +1722,12 @@
uc_derive_snd_device = derive_playback_snd_device(adev->platform,
usecase, uc_info, snd_device);
if (((uc_derive_snd_device != usecase->out_snd_device) || force_routing) &&
- ((usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
- (usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
- (usecase->devices & AUDIO_DEVICE_OUT_USB_DEVICE) ||
- (usecase->devices & AUDIO_DEVICE_OUT_USB_HEADSET) ||
- (usecase->devices & AUDIO_DEVICE_OUT_ALL_A2DP) ||
- (usecase->devices & AUDIO_DEVICE_OUT_ALL_SCO)) &&
+ (is_codec_backend_out_device_type(&usecase->device_list) ||
+ compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
+ compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_USB_DEVICE) ||
+ compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_USB_HEADSET) ||
+ is_a2dp_out_device_type(&usecase->device_list) ||
+ is_sco_out_device_type(&usecase->device_list)) &&
((force_restart_session) ||
(platform_check_backends_match(snd_device, usecase->out_snd_device)))) {
ALOGD("%s:becf: check_usecases (%s) is active on (%s) - disabling ..",
@@ -1803,7 +1809,7 @@
usecase->out_snd_device,
platform_get_input_snd_device(
adev->platform, NULL,
- uc_info->devices));
+ &uc_info->device_list));
enable_audio_route(adev, usecase);
if (usecase->stream.out && usecase->id == USECASE_AUDIO_PLAYBACK_VOIP) {
out_set_voip_volume(&usecase->stream.out->stream,
@@ -1824,7 +1830,7 @@
struct audio_usecase *usecase;
bool switch_device[AUDIO_USECASE_MAX];
int i, num_uc_to_switch = 0;
- int backend_check_cond = AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND;
+ int backend_check_cond = is_codec_backend_out_device_type(&uc_info->device_list);
int status = 0;
bool force_routing = platform_check_and_set_capture_codec_backend_cfg(adev, uc_info,
@@ -1837,7 +1843,7 @@
* codec backend or vice versa causes issues.
*/
if (uc_info->type == PCM_CAPTURE)
- backend_check_cond = AUDIO_DEVICE_IN_ALL_CODEC_BACKEND;
+ backend_check_cond = is_codec_backend_in_device_type(&uc_info->device_list);
/*
* This function is to make sure that all the active capture usecases
* are always routed to the same input sound device.
@@ -1859,13 +1865,14 @@
if (usecase->type != PCM_PLAYBACK &&
usecase != uc_info &&
(usecase->in_snd_device != snd_device || force_routing) &&
- ((uc_info->devices & backend_check_cond) &&
- (((usecase->devices & ~AUDIO_DEVICE_BIT_IN) & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND) ||
+ ((backend_check_cond &&
+ (is_codec_backend_in_device_type(&usecase->device_list) ||
(usecase->type == VOIP_CALL))) &&
((uc_info->type == VOICE_CALL &&
- usecase->devices == AUDIO_DEVICE_IN_VOICE_CALL) ||
+ is_single_device_type_equal(&usecase->device_list,
+ AUDIO_DEVICE_IN_VOICE_CALL)) ||
platform_check_backends_match(snd_device,\
- usecase->in_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],
@@ -2334,8 +2341,8 @@
if (is_offload_usecase(usecase->id) &&
(usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) &&
- (usecase->stream.out->devices == AUDIO_DEVICE_OUT_WIRED_HEADSET ||
- usecase->stream.out->devices == AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) {
+ (compare_device_type(&usecase->stream.out->device_list, AUDIO_DEVICE_OUT_WIRED_HEADSET) ||
+ compare_device_type(&usecase->stream.out->device_list, AUDIO_DEVICE_OUT_WIRED_HEADPHONE))) {
is_it_true_mode = (NATIVE_AUDIO_MODE_TRUE_44_1 == platform_get_native_support()? true : false);
if ((is_it_true_mode && !adev->native_playback_enabled) ||
(!is_it_true_mode && adev->native_playback_enabled)){
@@ -2347,7 +2354,7 @@
// Force all a2dp output devices to reconfigure for proper AFE encode format
//Also handle a case where in earlier a2dp start failed as A2DP stream was
//in suspended state, hence try to trigger a retry when we again get a routing request.
- if((usecase->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) &&
+ if(is_a2dp_out_device_type(&usecase->stream.out->device_list) &&
audio_extn_a2dp_is_force_device_switch()) {
ALOGD("Force a2dp device switch to update new encoder config");
ret = true;
@@ -2571,7 +2578,7 @@
ALOGE("%s: stream.out is NULL", __func__);
return -EINVAL;
}
- if (usecase->devices & AUDIO_DEVICE_OUT_BUS) {
+ if (compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_BUS)) {
out_snd_device = audio_extn_auto_hal_get_output_snd_device(adev,
uc_id);
in_snd_device = audio_extn_auto_hal_get_input_snd_device(adev,
@@ -2581,28 +2588,30 @@
usecase->stream.out);
in_snd_device = platform_get_input_snd_device(adev->platform,
NULL,
- usecase->stream.out->devices);
+ &usecase->stream.out->device_list);
}
- usecase->devices = usecase->stream.out->devices;
+ assign_devices(&usecase->device_list, &usecase->stream.out->device_list);
} else if (usecase->type == TRANSCODE_LOOPBACK_RX) {
if (usecase->stream.inout == NULL) {
ALOGE("%s: stream.inout is NULL", __func__);
return -EINVAL;
}
- stream_out.devices = usecase->stream.inout->out_config.devices;
+ assign_devices(&stream_out.device_list, &usecase->stream.inout->out_config.device_list);
stream_out.sample_rate = usecase->stream.inout->out_config.sample_rate;
stream_out.format = usecase->stream.inout->out_config.format;
stream_out.channel_mask = usecase->stream.inout->out_config.channel_mask;
out_snd_device = platform_get_output_snd_device(adev->platform,
&stream_out);
- usecase->devices = out_snd_device;
+ assign_devices(&usecase->device_list,
+ &usecase->stream.inout->out_config.device_list);
} else if (usecase->type == TRANSCODE_LOOPBACK_TX ) {
if (usecase->stream.inout == NULL) {
ALOGE("%s: stream.inout is NULL", __func__);
return -EINVAL;
}
- in_snd_device = platform_get_input_snd_device(adev->platform, NULL, AUDIO_DEVICE_NONE);
- usecase->devices = in_snd_device;
+ in_snd_device = platform_get_input_snd_device(adev->platform, NULL, NULL);
+ assign_devices(&usecase->device_list,
+ &usecase->stream.inout->in_config.device_list);
} else {
/*
* If the voice call is active, use the sound devices of voice call usecase
@@ -2616,12 +2625,14 @@
if (voice_is_in_call(adev) && adev->mode != AUDIO_MODE_NORMAL) {
vc_usecase = get_usecase_from_list(adev,
get_usecase_id_from_usecase_type(adev, VOICE_CALL));
- if ((vc_usecase) && (((vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
- (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND)) ||
- ((vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
- (usecase->devices & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND)) ||
- (vc_usecase->devices == AUDIO_DEVICE_OUT_HEARING_AID) ||
- (usecase->devices == AUDIO_DEVICE_IN_VOICE_CALL))) {
+ if ((vc_usecase) && ((is_codec_backend_out_device_type(&vc_usecase->device_list) &&
+ is_codec_backend_out_device_type(&usecase->device_list)) ||
+ (is_codec_backend_out_device_type(&vc_usecase->device_list) &&
+ is_codec_backend_in_device_type(&usecase->device_list)) ||
+ is_single_device_type_equal(&vc_usecase->device_list,
+ AUDIO_DEVICE_OUT_HEARING_AID) ||
+ is_single_device_type_equal(&usecase->device_list,
+ AUDIO_DEVICE_IN_VOICE_CALL))) {
in_snd_device = vc_usecase->in_snd_device;
out_snd_device = vc_usecase->out_snd_device;
}
@@ -2637,9 +2648,9 @@
adev->platform,
usecase->stream.out));
}
- if ((voip_usecase) && ((voip_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
- ((usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
- ((usecase->devices & ~AUDIO_DEVICE_BIT_IN) & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND)) &&
+ if ((voip_usecase) && (is_codec_backend_out_device_type(&voip_usecase->device_list) &&
+ (is_codec_backend_out_device_type(&usecase->device_list) ||
+ is_codec_backend_in_device_type(&usecase->device_list)) &&
out_snd_device_backend_match &&
(voip_usecase->stream.out != adev->primary_output))) {
in_snd_device = voip_usecase->in_snd_device;
@@ -2648,7 +2659,7 @@
} else if (audio_extn_hfp_is_active(adev)) {
hfp_ucid = audio_extn_hfp_get_usecase();
hfp_usecase = get_usecase_from_list(adev, hfp_ucid);
- if ((hfp_usecase) && (hfp_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND)) {
+ if ((hfp_usecase) && is_codec_backend_out_device_type(&hfp_usecase->device_list)) {
in_snd_device = hfp_usecase->in_snd_device;
out_snd_device = hfp_usecase->out_snd_device;
}
@@ -2658,12 +2669,12 @@
ALOGE("%s: stream.out is NULL", __func__);
return -EINVAL;
}
- usecase->devices = usecase->stream.out->devices;
+ assign_devices(&usecase->device_list, &usecase->stream.out->device_list);
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);
- if (usecase->devices & AUDIO_DEVICE_OUT_BUS)
+ if (compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_BUS))
out_snd_device = audio_extn_auto_hal_get_output_snd_device(adev, uc_id);
else
out_snd_device = platform_get_output_snd_device(adev->platform,
@@ -2681,13 +2692,14 @@
ALOGE("%s: stream.in is NULL", __func__);
return -EINVAL;
}
- usecase->devices = usecase->stream.in->device;
+ assign_devices(&usecase->device_list, &usecase->stream.in->device_list);
out_snd_device = SND_DEVICE_NONE;
if (in_snd_device == SND_DEVICE_NONE) {
- audio_devices_t out_device = AUDIO_DEVICE_NONE;
+ struct listnode out_devices;
struct stream_in *voip_in = get_voice_communication_input(adev);
struct stream_in *priority_in = NULL;
+ list_init(&out_devices);
if (voip_in != NULL) {
struct audio_usecase *voip_usecase = get_usecase_from_list(adev,
USECASE_AUDIO_PLAYBACK_VOIP);
@@ -2695,16 +2707,16 @@
usecase->stream.in->enable_ec_port = false;
if (usecase->id == USECASE_AUDIO_RECORD_AFE_PROXY) {
- out_device = AUDIO_DEVICE_OUT_TELEPHONY_TX;
+ reassign_device_list(&out_devices, AUDIO_DEVICE_OUT_TELEPHONY_TX, "");
} else if (voip_usecase) {
- out_device = voip_usecase->stream.out->devices;
+ assign_devices(&out_devices, &voip_usecase->stream.out->device_list);
} else if (adev->primary_output &&
!adev->primary_output->standby) {
- out_device = adev->primary_output->devices;
+ assign_devices(&out_devices, &adev->primary_output->device_list);
} else {
/* forcing speaker o/p device to get matching i/p pair
in case o/p is not routed from same primary HAL */
- out_device = AUDIO_DEVICE_OUT_SPEAKER;
+ reassign_device_list(&out_devices, AUDIO_DEVICE_OUT_SPEAKER, "");
}
priority_in = voip_in;
} else {
@@ -2717,7 +2729,7 @@
in_snd_device = platform_get_input_snd_device(adev->platform,
priority_in,
- out_device);
+ &out_devices);
}
}
}
@@ -2729,9 +2741,9 @@
return 0;
}
- if (!(usecase->devices & AUDIO_DEVICE_OUT_BUS) &&
+ if (!compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_BUS) &&
((is_btsco_device(out_snd_device,in_snd_device) && !adev->bt_sco_on) ||
- (is_a2dp_device(out_snd_device) && !audio_extn_a2dp_source_is_ready()))) {
+ (is_a2dp_device(out_snd_device) && !audio_extn_a2dp_source_is_ready()))) {
ALOGD("SCO/A2DP is selected but they are not connected/ready hence dont route");
return 0;
}
@@ -2852,7 +2864,7 @@
usecase);
if (usecase->type == PCM_PLAYBACK) {
if ((24 == usecase->stream.out->bit_width) &&
- (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
+ compare_device_type(&usecase->stream.out->device_list, AUDIO_DEVICE_OUT_SPEAKER)) {
usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
} else if ((out_snd_device == SND_DEVICE_OUT_HDMI ||
out_snd_device == SND_DEVICE_OUT_USB_HEADSET ||
@@ -2982,7 +2994,7 @@
/* 2. Disable the tx device */
disable_snd_device(adev, uc_info->in_snd_device);
- if (is_loopback_input_device(in->device))
+ if (is_loopback_input_device(get_device_types(&in->device_list)))
audio_extn_keep_alive_stop(KEEP_ALIVE_OUT_PRIMARY);
list_remove(&uc_info->list);
@@ -3026,7 +3038,7 @@
goto error_config;
}
- if (audio_is_bluetooth_sco_device(in->device)) {
+ if (is_sco_in_device_type(&in->device_list)) {
if (!adev->bt_sco_on) {
ALOGE("%s: SCO profile is not ready, return error", __func__);
ret = -EIO;
@@ -3065,7 +3077,8 @@
uc_info->id = in->usecase;
uc_info->type = PCM_CAPTURE;
uc_info->stream.in = in;
- uc_info->devices = in->device;
+ list_init(&uc_info->device_list);
+ assign_devices(&uc_info->device_list, &in->device_list);
uc_info->in_snd_device = SND_DEVICE_NONE;
uc_info->out_snd_device = SND_DEVICE_NONE;
@@ -3175,7 +3188,7 @@
audio_extn_audiozoom_set_microphone_direction(in, in->zoom);
audio_extn_audiozoom_set_microphone_field_dimension(in, in->direction);
- if (is_loopback_input_device(in->device))
+ if (is_loopback_input_device(get_device_types(&in->device_list)))
audio_extn_keep_alive_start(KEEP_ALIVE_OUT_PRIMARY);
done_open:
@@ -3556,7 +3569,7 @@
adev->dsp_bit_width_enforce_mode,
false);
}
- if (audio_is_usb_out_device(out->devices & AUDIO_DEVICE_OUT_ALL_USB)) {
+ if (is_usb_out_device_type(&out->device_list)) {
ret = audio_extn_usb_check_and_set_svc_int(uc_info,
false);
@@ -3573,13 +3586,18 @@
(audio_extn_passthru_is_passthrough_stream(out))) {
ALOGV("Disable passthrough , reset mixer to pcm");
/* NO_PASSTHROUGH */
+#ifdef AUDIO_GKI_ENABLED
+ /* out->compr_config.codec->reserved[0] is for compr_passthr */
+ out->compr_config.codec->reserved[0] = 0;
+#else
out->compr_config.codec->compr_passthr = 0;
+#endif
audio_extn_passthru_on_stop(out);
audio_extn_dolby_set_dap_bypass(adev, DAP_STATE_ON);
}
/* Must be called after removing the usecase from list */
- if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
+ if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL))
audio_extn_keep_alive_start(KEEP_ALIVE_OUT_HDMI);
if (out->ip_hdlr_handle) {
@@ -3593,7 +3611,7 @@
2) trigger voip input to reroute when voip output changes to
hearing aid. */
if (has_voip_usecase ||
- out->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
+ compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
struct listnode *node;
struct audio_usecase *usecase;
list_for_each(node, &adev->usecase_list) {
@@ -3670,7 +3688,12 @@
ALOGD("%s: enter: stream(%p)usecase(%d: %s) devices(%#x) is_haptic_usecase(%d)",
__func__, &out->stream, out->usecase, use_case_table[out->usecase],
- out->devices, is_haptic_usecase);
+ get_device_types(&out->device_list), is_haptic_usecase);
+
+ bool is_speaker_active = compare_device_type(&out->device_list,
+ AUDIO_DEVICE_OUT_SPEAKER);
+ bool is_speaker_safe_active = compare_device_type(&out->device_list,
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE);
if (CARD_STATUS_OFFLINE == out->card_status ||
CARD_STATUS_OFFLINE == adev->card_status) {
@@ -3689,10 +3712,9 @@
}
}
- if (out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ if (is_a2dp_out_device_type(&out->device_list)) {
if (!audio_extn_a2dp_source_is_ready()) {
- if (out->devices &
- (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+ if (is_speaker_active || is_speaker_safe_active) {
a2dp_combo = true;
} else {
if (!(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
@@ -3703,12 +3725,12 @@
}
}
}
- if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
+ if (is_sco_out_device_type(&out->device_list)) {
if (!adev->bt_sco_on) {
- if (out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (is_speaker_active) {
//combo usecase just by pass a2dp
ALOGW("%s: SCO is not connected, route it to speaker", __func__);
- out->devices = AUDIO_DEVICE_OUT_SPEAKER;
+ reassign_device_list(&out->device_list, AUDIO_DEVICE_OUT_SPEAKER, "");
} else {
ALOGE("%s: SCO profile is not ready, return error", __func__);
ret = -EAGAIN;
@@ -3745,12 +3767,13 @@
uc_info->id = out->usecase;
uc_info->type = PCM_PLAYBACK;
uc_info->stream.out = out;
- uc_info->devices = out->devices;
+ list_init(&uc_info->device_list);
+ assign_devices(&uc_info->device_list, &out->device_list);
uc_info->in_snd_device = SND_DEVICE_NONE;
uc_info->out_snd_device = SND_DEVICE_NONE;
/* This must be called before adding this usecase to the list */
- if (audio_is_usb_out_device(out->devices & AUDIO_DEVICE_OUT_ALL_USB)) {
+ if (is_usb_out_device_type(&out->device_list)) {
audio_extn_usb_check_and_set_svc_int(uc_info, true);
/* USB backend is not reopened immediately.
This is eventually done as part of select_devices */
@@ -3763,7 +3786,7 @@
adev->perf_lock_opts,
adev->perf_lock_opts_size);
- if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
audio_extn_keep_alive_stop(KEEP_ALIVE_OUT_HDMI);
if (audio_extn_passthru_is_enabled() &&
audio_extn_passthru_is_passthrough_stream(out)) {
@@ -3771,18 +3794,22 @@
}
}
- if ((out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) &&
+ if (is_a2dp_out_device_type(&out->device_list) &&
(!audio_extn_a2dp_source_is_ready())) {
if (!a2dp_combo) {
check_a2dp_restore_l(adev, out, false);
} else {
- audio_devices_t dev = out->devices;
- if (dev & AUDIO_DEVICE_OUT_SPEAKER_SAFE)
- out->devices = AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+ struct listnode dev;
+ list_init(&dev);
+ assign_devices(&dev, &out->device_list);
+ if (compare_device_type(&dev, AUDIO_DEVICE_OUT_SPEAKER_SAFE))
+ reassign_device_list(&out->device_list,
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE, "");
else
- out->devices = AUDIO_DEVICE_OUT_SPEAKER;
+ reassign_device_list(&out->device_list,
+ AUDIO_DEVICE_OUT_SPEAKER, "");
select_devices(adev, out->usecase);
- out->devices = dev;
+ assign_devices(&out->device_list, &dev);
}
} else {
select_devices(adev, out->usecase);
@@ -3946,7 +3973,7 @@
audio_extn_check_and_set_dts_hpx_state(adev);
}
- if (out->devices & AUDIO_DEVICE_OUT_BUS) {
+ if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_BUS)) {
/* Update cached volume from media to offload/direct stream */
struct listnode *node = NULL;
list_for_each(node, &adev->active_outputs_list) {
@@ -4386,7 +4413,7 @@
stop_output_stream(out);
}
// if fm is active route on selected device in UI
- audio_extn_fm_route_on_selected_device(adev, out->devices);
+ audio_extn_fm_route_on_selected_device(adev, &out->device_list);
pthread_mutex_unlock(&adev->lock);
}
pthread_mutex_unlock(&out->lock);
@@ -4597,22 +4624,20 @@
}
int route_output_stream(struct stream_out *out,
- audio_devices_t devices,
- char *address)
+ struct listnode *devices)
{
struct audio_device *adev = out->dev;
- struct str_parms *addr;
int ret = 0;
- audio_devices_t new_devices = devices;
+ struct listnode new_devices;
bool bypass_a2dp = false;
bool reconfig = false;
unsigned long service_interval = 0;
ALOGD("%s: enter: usecase(%d: %s) devices %x",
- __func__, out->usecase, use_case_table[out->usecase], devices);
- addr = str_parms_create_str(address);
- if (!addr)
- goto error;
+ __func__, out->usecase, use_case_table[out->usecase], get_device_types(devices));
+
+ list_init(&new_devices);
+ assign_devices(&new_devices, devices);
lock_output_stream(out);
pthread_mutex_lock(&adev->lock);
@@ -4624,11 +4649,11 @@
* turned off, the write gets blocked.
* Avoid this by routing audio to speaker until standby.
*/
- if ((out->devices == AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
- (new_devices == AUDIO_DEVICE_NONE) &&
+ if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
+ list_empty(&new_devices) &&
!audio_extn_passthru_is_passthrough_stream(out) &&
(platform_get_edid_info(adev->platform) != 0) /* HDMI disconnected */) {
- new_devices = AUDIO_DEVICE_OUT_SPEAKER;
+ reassign_device_list(&new_devices, AUDIO_DEVICE_OUT_SPEAKER, "");
}
/*
* When A2DP is disconnected the
@@ -4637,11 +4662,11 @@
* (3sec). As BT is turned off, the write gets blocked.
* Avoid this by routing audio to speaker until standby.
*/
- if ((out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) &&
- (new_devices == AUDIO_DEVICE_NONE) &&
+ if (is_a2dp_out_device_type(&out->device_list) &&
+ list_empty(&new_devices) &&
!audio_extn_a2dp_source_is_ready() &&
!adev->bt_sco_on) {
- new_devices = AUDIO_DEVICE_OUT_SPEAKER;
+ reassign_device_list(&new_devices, AUDIO_DEVICE_OUT_SPEAKER, "");
}
/*
* When USB headset is disconnected the music platback paused
@@ -4650,18 +4675,18 @@
* when USB is connected back. So routing to speker will guarantee
* AFE reconfiguration and AFE will be opend once USB is connected again
*/
- if ((out->devices & AUDIO_DEVICE_OUT_ALL_USB) &&
- (new_devices == AUDIO_DEVICE_NONE) &&
- !audio_extn_usb_connected(addr))
- new_devices = AUDIO_DEVICE_OUT_SPEAKER;
-
+ if (is_usb_out_device_type(&out->device_list) &&
+ list_empty(&new_devices) &&
+ !audio_extn_usb_connected(NULL)) {
+ reassign_device_list(&new_devices, AUDIO_DEVICE_OUT_SPEAKER, "");
+ }
/* To avoid a2dp to sco overlapping / BT device improper state
* check with BT lib about a2dp streaming support before routing
*/
- if (new_devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ if (is_a2dp_out_device_type(&new_devices)) {
if (!audio_extn_a2dp_source_is_ready()) {
- if (new_devices &
- (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+ if (compare_device_type(&new_devices, AUDIO_DEVICE_OUT_SPEAKER) ||
+ compare_device_type(&new_devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
//combo usecase just by pass a2dp
ALOGW("%s: A2DP profile is not ready,routing to speaker only", __func__);
bypass_a2dp = true;
@@ -4671,7 +4696,7 @@
* However it is still possible a2dp routing called because
* of current active device disconnection (like wired headset)
*/
- out->devices = new_devices;
+ assign_devices(&out->device_list, &new_devices);
pthread_mutex_unlock(&adev->lock);
pthread_mutex_unlock(&out->lock);
goto error;
@@ -4679,17 +4704,23 @@
}
}
-
// Workaround: If routing to an non existing usb device, fail gracefully
// The routing request will otherwise block during 10 second
int card;
- if (audio_is_usb_out_device(new_devices) &&
- (card = get_alive_usb_card(addr)) >= 0) {
- ALOGW("out_set_parameters() ignoring rerouting to non existing USB card %d", card);
- pthread_mutex_unlock(&adev->lock);
- pthread_mutex_unlock(&out->lock);
- ret = -ENOSYS;
- goto error;
+ if (is_usb_out_device_type(&new_devices)) {
+ struct str_parms *parms =
+ str_parms_create_str(get_usb_device_address(&new_devices));
+ if (!parms)
+ goto error;
+ if ((card = get_alive_usb_card(parms)) >= 0) {
+ ALOGW("%s: ignoring rerouting to non existing USB card %d", __func__, card);
+ pthread_mutex_unlock(&adev->lock);
+ pthread_mutex_unlock(&out->lock);
+ str_parms_destroy(parms);
+ ret = -ENOSYS;
+ goto error;
+ }
+ str_parms_destroy(parms);
}
/*
@@ -4710,15 +4741,15 @@
* Because select_devices() must be called to switch back the music
* playback to headset.
*/
- if (new_devices != AUDIO_DEVICE_NONE) {
- bool same_dev = out->devices == new_devices;
- out->devices = new_devices;
+ if (!list_empty(&new_devices)) {
+ bool same_dev = compare_devices(&out->device_list, &new_devices);
+ assign_devices(&out->device_list, &new_devices);
if (output_drives_call(adev, out)) {
if (!voice_is_call_state_active(adev)) {
if (adev->mode == AUDIO_MODE_IN_CALL) {
adev->current_call_output = out;
- if (audio_is_usb_out_device(out->devices & AUDIO_DEVICE_OUT_ALL_USB)) {
+ if (is_usb_out_device_type(&out->device_list)) {
service_interval =
audio_extn_usb_find_service_interval(true, true /*playback*/);
audio_extn_usb_set_service_interval(true /*playback*/,
@@ -4747,12 +4778,12 @@
if (!bypass_a2dp) {
select_devices(adev, out->usecase);
} else {
- if (new_devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE)
- out->devices = AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+ if (compare_device_type(&new_devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE))
+ reassign_device_list(&out->device_list, AUDIO_DEVICE_OUT_SPEAKER_SAFE, "");
else
- out->devices = AUDIO_DEVICE_OUT_SPEAKER;
+ reassign_device_list(&out->device_list, AUDIO_DEVICE_OUT_SPEAKER, "");
select_devices(adev, out->usecase);
- out->devices = new_devices;
+ assign_devices(&out->device_list, &new_devices);
}
if (!same_dev) {
@@ -4763,7 +4794,7 @@
}
if ((out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
out->a2dp_compress_mute &&
- (!(out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) || audio_extn_a2dp_source_is_ready())) {
+ (!is_a2dp_out_device_type(&out->device_list) || audio_extn_a2dp_source_is_ready())) {
pthread_mutex_lock(&out->compr_mute_lock);
out->a2dp_compress_mute = false;
out_set_compr_volume(&out->stream, out->volume_l, out->volume_r);
@@ -4781,8 +4812,6 @@
audio_extn_extspk_update(adev->extspk);
error:
- if (addr)
- str_parms_destroy(addr);
ALOGV("%s: exit: code(%d)", __func__, ret);
return ret;
}
@@ -4844,7 +4873,8 @@
lock_output_stream(out);
audio_extn_utils_update_stream_output_app_type_cfg(adev->platform,
&adev->streams_output_cfg_list,
- out->devices, out->flags, out->hal_op_format,
+ &out->device_list, out->flags,
+ out->hal_op_format,
out->sample_rate, out->bit_width,
out->channel_mask, out->profile,
&out->app_type_cfg);
@@ -5173,7 +5203,7 @@
(out->config.rate);
}
- if (AUDIO_DEVICE_OUT_ALL_A2DP & out->devices)
+ if (is_a2dp_out_device_type(&out->device_list))
latency += audio_extn_a2dp_get_encoder_latency();
ALOGV("%s: Latency %d", __func__, latency);
@@ -5347,7 +5377,7 @@
volume[1] = (long)(AmpToDb(right));
mixer_ctl_set_array(ctl, volume, sizeof(volume)/sizeof(volume[0]));
return 0;
- } else if ((out->devices & AUDIO_DEVICE_OUT_BUS) &&
+ } else if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_BUS) &&
(out->car_audio_stream == CAR_AUDIO_STREAM_MEDIA)) {
ALOGD("%s: Overriding offload set volume for media bus stream", __func__);
struct listnode *node = NULL;
@@ -5541,6 +5571,7 @@
const size_t frame_size = audio_stream_out_frame_size(stream);
const size_t frames = (frame_size != 0) ? bytes / frame_size : bytes;
struct audio_usecase *usecase = NULL;
+ uint32_t compr_passthr = 0;
ATRACE_BEGIN("out_write");
lock_output_stream(out);
@@ -5571,7 +5602,7 @@
goto exit;
}
- if ((out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
+ if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
!out->is_iec61937_info_available) {
if (!audio_extn_passthru_is_passthrough_stream(out)) {
@@ -5608,8 +5639,15 @@
}
}
+#ifdef AUDIO_GKI_ENABLED
+ /* out->compr_config.codec->reserved[0] is for compr_passthr */
+ compr_passthr = out->compr_config.codec->reserved[0];
+#else
+ compr_passthr = out->compr_config.codec->compr_passthr;
+#endif
+
if ((channels < (int)audio_channel_count_from_out_mask(out->channel_mask)) &&
- (out->compr_config.codec->compr_passthr == PASSTHROUGH) &&
+ (compr_passthr == PASSTHROUGH) &&
(out->is_iec61937_info_available == true)) {
ALOGE("%s: ERROR: Unsupported channel config in passthrough mode", __func__);
ret = -EINVAL;
@@ -5618,10 +5656,10 @@
}
}
- if ((out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) &&
+ if (is_a2dp_out_device_type(&out->device_list) &&
(audio_extn_a2dp_source_is_suspended())) {
- if (!(out->devices &
- (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE))) {
+ if (!(compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_SPEAKER) ||
+ compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_SPEAKER_SAFE))) {
if (!(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
ret = -EIO;
goto exit;
@@ -5659,7 +5697,9 @@
audio_extn_send_dual_mono_mixing_coefficients(out);
}
- if (adev->is_channel_status_set == false && (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)){
+ if (adev->is_channel_status_set == false &&
+ compare_device_type(&out->device_list,
+ AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
audio_utils_set_hdmi_channel_status(out, (void *)buffer, bytes);
adev->is_channel_status_set = true;
}
@@ -6016,7 +6056,7 @@
&out->sample_rate);
// Adjustment accounts for A2dp encoder latency with offload usecases
// Note: Encoder latency is returned in ms.
- if (AUDIO_DEVICE_OUT_ALL_A2DP & out->devices) {
+ if (is_a2dp_out_device_type(&out->device_list)) {
unsigned long offset =
(audio_extn_a2dp_get_encoder_latency() * out->sample_rate / 1000);
dsp_frames = (dsp_frames > offset) ? (dsp_frames - offset) : 0;
@@ -6055,7 +6095,7 @@
// Adjustment accounts for A2dp encoder latency with non offload usecases
// Note: Encoder latency is returned in ms, while platform_render_latency in us.
- if (AUDIO_DEVICE_OUT_ALL_A2DP & out->devices) {
+ if (is_a2dp_out_device_type(&out->device_list)) {
frames_temp = audio_extn_a2dp_get_encoder_latency() * out->sample_rate / 1000;
if (signed_frames >= frames_temp)
signed_frames -= frames_temp;
@@ -6583,8 +6623,7 @@
}
int route_input_stream(struct stream_in *in,
- audio_devices_t devices,
- char *address,
+ struct listnode *devices,
audio_source_t source)
{
struct audio_device *adev = in->dev;
@@ -6610,22 +6649,20 @@
}
}
- if ((in->device != devices) && (devices != AUDIO_DEVICE_NONE) &&
- audio_is_input_device(devices)) {
+ if (!compare_devices(&in->device_list, devices) && !list_empty(devices) &&
+ is_audio_in_device_type(devices)) {
// Workaround: If routing to an non existing usb device, fail gracefully
// The routing request will otherwise block during 10 second
int card;
- struct str_parms *addr = str_parms_create_str(address);
-
- if (!addr)
- return ret;
- if (audio_is_usb_in_device(devices) &&
- (card = get_alive_usb_card(addr)) >= 0) {
+ struct str_parms *usb_addr =
+ str_parms_create_str(get_usb_device_address(devices));
+ if (is_usb_in_device_type(devices) && usb_addr &&
+ (card = get_alive_usb_card(usb_addr)) >= 0) {
ALOGW("%s: ignoring rerouting to non existing USB card %d", __func__, card);
ret = -ENOSYS;
} else {
- in->device = devices;
/* If recording is in progress, change the tx device to new device */
+ assign_devices(&in->device_list, devices);
if (!in->standby && !in->is_st_session) {
ALOGV("update input routing change");
// inform adm before actual routing to prevent glitches.
@@ -6638,7 +6675,8 @@
}
}
}
- str_parms_destroy(addr);
+ if (usb_addr)
+ str_parms_destroy(usb_addr);
}
pthread_mutex_unlock(&adev->lock);
pthread_mutex_unlock(&in->lock);
@@ -6669,7 +6707,7 @@
ALOGV("updating stream profile with value '%s'", in->profile);
audio_extn_utils_update_stream_input_app_type_cfg(adev->platform,
&adev->streams_input_cfg_list,
- in->device, in->flags, in->format,
+ &in->device_list, in->flags, in->format,
in->sample_rate, in->bit_width,
in->profile, &in->app_type_cfg);
}
@@ -7345,22 +7383,24 @@
int error = 0;
struct stream_in *in = (struct stream_in *)stream;
struct audio_device *adev = in->dev;
- audio_devices_t device = AUDIO_DEVICE_NONE;
+ struct listnode devices;
+
+ list_init(&devices);
if (sink_metadata->track_count != 0)
- device = sink_metadata->tracks->dest_device;
+ reassign_device_list(&devices, sink_metadata->tracks->dest_device, "");
lock_input_stream(in);
pthread_mutex_lock(&adev->lock);
- ALOGV("%s: in->usecase: %d, device: %x", __func__, in->usecase, device);
+ ALOGV("%s: in->usecase: %d, device: %x", __func__, in->usecase, get_device_types(&devices));
if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY
- && device != AUDIO_DEVICE_NONE
+ && !list_empty(&devices)
&& adev->voice_tx_output != NULL) {
/* Use the rx device from afe-proxy record to route voice call because
there is no routing if tx device is on primary hal and rx device
is on other hal during voice call. */
- adev->voice_tx_output->devices = device;
+ assign_devices(&adev->voice_tx_output->device_list, &devices);
if (!voice_is_call_state_active(adev)) {
if (adev->mode == AUDIO_MODE_IN_CALL) {
@@ -7443,7 +7483,8 @@
devices = AUDIO_DEVICE_OUT_SPEAKER;
out->flags = flags;
- out->devices = devices;
+ list_init(&out->device_list);
+ update_device_list(&out->device_list, devices, address, true /* add devices */);
out->dev = adev;
out->hal_op_format = out->hal_ip_format = format = out->format = config->format;
out->sample_rate = config->sample_rate;
@@ -7551,7 +7592,7 @@
}
/* validate bus device address */
- if (out->devices & AUDIO_DEVICE_OUT_BUS) {
+ if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_BUS)) {
/* extract car audio stream index */
out->car_audio_stream =
audio_extn_auto_hal_get_car_audio_stream_from_address(address);
@@ -7687,11 +7728,16 @@
if (out->flags & AUDIO_OUTPUT_FLAG_FAST) {
ALOGD("%s: Setting latency mode to true", __func__);
+#ifdef AUDIO_GKI_ENABLED
+ /* out->compr_config.codec->reserved[1] is for flags */
+ out->compr_config.codec->reserved[1] |= audio_extn_utils_get_perf_mode_flag();
+#else
out->compr_config.codec->flags |= audio_extn_utils_get_perf_mode_flag();
+#endif
}
if (out->usecase == USECASE_INVALID) {
- if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL &&
+ if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
config->format == 0 && config->sample_rate == 0 &&
config->channel_mask == 0) {
ALOGI("%s dummy open to query sink capability",__func__);
@@ -7739,8 +7785,14 @@
out->bit_width = AUDIO_OUTPUT_BIT_WIDTH;
if (out->flags & AUDIO_OUTPUT_FLAG_TIMESTAMP)
+#ifdef AUDIO_GKI_ENABLED
+ /* out->compr_config.codec->reserved[1] is for flags */
+ out->compr_config.codec->reserved[1] |= COMPRESSED_TIMESTAMP_FLAG;
+ ALOGVV("%s : out->compr_config.codec->flags -> (%#x) ", __func__, out->compr_config.codec->reserved[1]);
+#else
out->compr_config.codec->flags |= COMPRESSED_TIMESTAMP_FLAG;
ALOGVV("%s : out->compr_config.codec->flags -> (%#x) ", __func__, out->compr_config.codec->flags);
+#endif
/*TODO: Do we need to change it for passthrough */
out->compr_config.codec->format = SND_AUDIOSTREAMFORMAT_RAW;
@@ -7879,7 +7931,12 @@
}
if (config->format == AUDIO_FORMAT_DSD) {
out->flags |= AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH;
+#ifdef AUDIO_GKI_ENABLED
+ /* out->compr_config.codec->reserved[0] is for compr_passthr */
+ out->compr_config.codec->reserved[0] = PASSTHROUGH_DSD;
+#else
out->compr_config.codec->compr_passthr = PASSTHROUGH_DSD;
+#endif
}
create_offload_callback_thread(out);
@@ -7933,7 +7990,8 @@
__func__, ret);
goto error_open;
}
- } else if (out->devices == AUDIO_DEVICE_OUT_TELEPHONY_TX) {
+ } else if (is_single_device_type_equal(&out->device_list,
+ AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
switch (config->sample_rate) {
case 0:
out->sample_rate = AFE_PROXY_SAMPLING_RATE;
@@ -8063,7 +8121,7 @@
adev->haptics_config.channels = 1;
} else
adev->haptics_config.channels = audio_channel_count_from_out_mask(out->channel_mask & AUDIO_CHANNEL_HAPTIC_ALL);
- } else if (out->devices & AUDIO_DEVICE_OUT_BUS) {
+ } else if (compare_device_type(&out->device_list, AUDIO_DEVICE_OUT_BUS)) {
ret = audio_extn_auto_hal_open_output_stream(out);
if (ret) {
ALOGE("%s: Failed to open output stream for bus device", __func__);
@@ -8105,7 +8163,8 @@
out->bit_width = 16;
audio_extn_utils_update_stream_output_app_type_cfg(adev->platform,
&adev->streams_output_cfg_list,
- devices, out->flags, out->hal_op_format, out->sample_rate,
+ &out->device_list, out->flags,
+ out->hal_op_format, out->sample_rate,
out->bit_width, out->channel_mask, out->profile,
&out->app_type_cfg);
if ((out->usecase == (audio_usecase_t)(GET_USECASE_AUDIO_PLAYBACK_PRIMARY(use_db_as_primary))) ||
@@ -8392,10 +8451,10 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.in && (usecase->type == PCM_CAPTURE) &&
- ((usecase->stream.in->device & ~AUDIO_DEVICE_BIT_IN) &
- AUDIO_DEVICE_IN_ALL_SCO)) {
+ is_sco_in_device_type(&usecase->stream.in->device_list)) {
ALOGD("a2dp resumed, switch bt sco mic to handset mic");
- usecase->stream.in->device = AUDIO_DEVICE_IN_BUILTIN_MIC;
+ reassign_device_list(&usecase->stream.in->device_list,
+ AUDIO_DEVICE_IN_BUILTIN_MIC, "");
select_devices(adev, usecase->id);
}
}
@@ -8542,7 +8601,7 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.out && (usecase->type == PCM_PLAYBACK) &&
- (usecase->devices & AUDIO_DEVICE_OUT_ALL_A2DP)){
+ is_a2dp_out_device_type(&usecase->device_list)) {
ALOGD("reconfigure a2dp... forcing device switch");
pthread_mutex_unlock(&adev->lock);
lock_output_stream(usecase->stream.out);
@@ -8563,7 +8622,8 @@
pthread_mutex_unlock(&adev->lock);
lock_output_stream(usecase->stream.out);
pthread_mutex_lock(&adev->lock);
- usecase->stream.out->devices = AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
+ reassign_device_list(&usecase->stream.out->device_list,
+ AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, "");
check_a2dp_restore_l(adev, usecase->stream.out, true);
pthread_mutex_unlock(&usecase->stream.out->lock);
break;
@@ -8898,7 +8958,7 @@
struct audio_config *config,
struct audio_stream_in **stream_in,
audio_input_flags_t flags,
- const char *address __unused,
+ const char *address,
audio_source_t source)
{
struct audio_device *adev = (struct audio_device *)dev;
@@ -8984,7 +9044,8 @@
in->stream.set_microphone_field_dimension = in_set_microphone_field_dimension;
in->stream.update_sink_metadata = in_update_sink_metadata;
- in->device = devices;
+ list_init(&in->device_list);
+ update_device_list(&in->device_list, devices, address, true);
in->source = source;
in->dev = adev;
in->standby = 1;
@@ -9144,8 +9205,10 @@
default:
in->bit_width = 16;
}
- } else if ((in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) ||
- (in->device == AUDIO_DEVICE_IN_PROXY)) {
+ } else if (is_single_device_type_equal(&in->device_list,
+ AUDIO_DEVICE_IN_TELEPHONY_RX) ||
+ is_single_device_type_equal(&in->device_list,
+ AUDIO_DEVICE_IN_PROXY)) {
if (config->sample_rate == 0)
config->sample_rate = AFE_PROXY_SAMPLING_RATE;
if (config->sample_rate != 48000 && config->sample_rate != 16000 &&
@@ -9270,7 +9333,7 @@
audio_extn_utils_update_stream_input_app_type_cfg(adev->platform,
&adev->streams_input_cfg_list,
- devices, flags, in->format,
+ &in->device_list, flags, in->format,
in->sample_rate, in->bit_width,
in->profile, &in->app_type_cfg);
register_format(in->format, in->supported_formats);
@@ -9337,6 +9400,10 @@
ALOGD("%s: enter:stream_handle(%p)",__func__, in);
+ if (in == NULL) {
+ ALOGE("%s: audio_stream_in ptr is NULL", __func__);
+ return;
+ }
io_streams_map_remove(adev, in->capture_handle);
/* must deregister from sndmonitor first to prevent races
@@ -9349,15 +9416,13 @@
*/
if (adev_get_active_input(adev) == NULL &&
!audio_extn_hfp_is_active(adev) &&
- !audio_extn_sound_trigger_check_ec_ref_enable())
- platform_set_echo_reference(adev, false, AUDIO_DEVICE_NONE);
- else
+ !audio_extn_sound_trigger_check_ec_ref_enable()) {
+ struct listnode out_devices;
+ list_init(&out_devices);
+ platform_set_echo_reference(adev, false, &out_devices);
+ } else
audio_extn_sound_trigger_update_ec_ref_status(false);
- if (in == NULL) {
- ALOGE("%s: audio_stream_in ptr is NULL", __func__);
- return;
- }
error_log_destroy(in->error_log);
in->error_log = NULL;
@@ -9496,14 +9561,14 @@
uc_info.type = usecase_type;
if (dir) {
memset(&in, 0, sizeof(in));
- in.device = audio_device;
+ update_device_list(&in.device_list, audio_device, "", true);
in.source = AUDIO_SOURCE_VOICE_COMMUNICATION;
uc_info.stream.in = ∈
}
memset(&out, 0, sizeof(out));
- out.devices = audio_device; /* only field needed in select_devices */
+ update_device_list(&out.device_list, audio_device, "", true);
uc_info.stream.out = &out;
- uc_info.devices = audio_device;
+ update_device_list(&uc_info.device_list, audio_device, "", true);
uc_info.in_snd_device = SND_DEVICE_NONE;
uc_info.out_snd_device = SND_DEVICE_NONE;
list_add_tail(&adev->usecase_list, &uc_info.list);
@@ -9595,6 +9660,7 @@
audio_source_t input_source = AUDIO_SOURCE_DEFAULT;
struct audio_stream_info *s_info = NULL;
struct audio_stream *stream = NULL;
+ struct listnode devices;
audio_devices_t device_type = AUDIO_DEVICE_NONE;
bool new_patch = false;
char addr[AUDIO_DEVICE_MAX_ADDRESS_LEN];
@@ -9623,17 +9689,19 @@
ALOGV("%s: source role %d, source type %d", __func__,
sources[0].type, sources[0].role);
+ list_init(&devices);
// Populate source/sink information and fetch stream info
switch (sources[0].type) {
case AUDIO_PORT_TYPE_DEVICE: // Patch for audio capture or loopback
device_type = sources[0].ext.device.type;
strlcpy(&addr[0], &sources[0].ext.device.address[0], AUDIO_DEVICE_MAX_ADDRESS_LEN);
+ update_device_list(&devices, device_type, &addr[0], true);
if (sinks[0].type == AUDIO_PORT_TYPE_MIX) {
patch_type = PATCH_CAPTURE;
io_handle = sinks[0].ext.mix.handle;
input_source = sinks[0].ext.mix.usecase.source;
- ALOGV("%s: Capture patch from device %x to mix %d",
+ ALOGD("%s: Capture patch from device %x to mix %d",
__func__, device_type, io_handle);
} else {
// Device to device patch is not implemented.
@@ -9645,103 +9713,91 @@
case AUDIO_PORT_TYPE_MIX: // Patch for audio playback
io_handle = sources[0].ext.mix.handle;
for (int i = 0; i < num_sinks; i++) {
- if (sinks[i].type == AUDIO_PORT_TYPE_MIX) {
- ALOGE("%s: mix to mix patches are not supported", __func__);
- ret = -EINVAL;
- goto done;
- }
- device_type |= sinks[i].ext.device.type;
+ device_type = sinks[i].ext.device.type;
strlcpy(&addr[0], &sinks[i].ext.device.address[0], AUDIO_DEVICE_MAX_ADDRESS_LEN);
+ update_device_list(&devices, device_type, &addr[0], true);
}
patch_type = PATCH_PLAYBACK;
- ALOGV("%s: Playback patch from mix handle %d to device %x",
- __func__, io_handle, device_type);
+ ALOGD("%s: Playback patch from mix handle %d to device %x",
+ __func__, io_handle, get_device_types(&devices));
break;
case AUDIO_PORT_TYPE_SESSION:
case AUDIO_PORT_TYPE_NONE:
- break;
+ ALOGE("%s: Unsupported source type %d", __func__, sources[0].type);
+ ret = -EINVAL;
+ goto done;
}
pthread_mutex_lock(&adev->lock);
- s_info = hashmapGet(adev->io_streams_map, (void *) (intptr_t) io_handle);
- pthread_mutex_unlock(&adev->lock);
- if (s_info == NULL) {
- ALOGE("%s: Failed to obtain stream info", __func__);
- ret = -EINVAL;
- goto done;
- }
- ALOGV("%s: Fetched stream info with io_handle %d", __func__, io_handle);
- pthread_mutex_lock(&s_info->lock);
// Generate patch info and update patch
if (*handle == AUDIO_PATCH_HANDLE_NONE) {
- if (s_info->patch_handle != AUDIO_PATCH_HANDLE_NONE) {
- // Use patch handle cached in s_info to update patch
- *handle = s_info->patch_handle;
- p_info = fetch_patch_info(adev, *handle);
- if (p_info == NULL) {
- ALOGE("%s: Unable to fetch patch for stream patch handle %d",
- __func__, *handle);
- pthread_mutex_unlock(&s_info->lock);
- ret = -EINVAL;
- goto done;
- }
- } else {
- *handle = generate_patch_handle();
- p_info = (struct audio_patch_info *) calloc(1, sizeof(struct audio_patch_info));
- if (p_info == NULL) {
- ALOGE("%s: Failed to allocate memory", __func__);
- pthread_mutex_unlock(&s_info->lock);
- ret = -ENOMEM;
- goto done;
- }
- new_patch = true;
- pthread_mutex_init(&p_info->lock, (const pthread_mutexattr_t *) NULL);
- s_info->patch_handle = *handle;
+ *handle = generate_patch_handle();
+ p_info = (struct audio_patch_info *)
+ calloc(1, sizeof(struct audio_patch_info));
+ if (p_info == NULL) {
+ ALOGE("%s: Failed to allocate memory", __func__);
+ pthread_mutex_unlock(&adev->lock);
+ ret = -ENOMEM;
+ goto done;
}
+ new_patch = true;
} else {
- p_info = fetch_patch_info(adev, *handle);
+ p_info = fetch_patch_info_l(adev, *handle);
if (p_info == NULL) {
ALOGE("%s: Unable to fetch patch for received patch handle %d",
__func__, *handle);
- pthread_mutex_unlock(&s_info->lock);
+ pthread_mutex_unlock(&adev->lock);
ret = -EINVAL;
goto done;
}
- s_info->patch_handle = *handle;
}
- pthread_mutex_lock(&p_info->lock);
update_patch(num_sources, sources, num_sinks, sinks,
- *handle, p_info, patch_type, new_patch);
- stream = s_info->stream;
+ *handle, p_info, patch_type, new_patch);
+
+ // Fetch stream info of associated mix for playback or capture patches
+ if (p_info->patch_type == PATCH_PLAYBACK ||
+ p_info->patch_type == PATCH_CAPTURE) {
+ s_info = hashmapGet(adev->io_streams_map, (void *) (intptr_t) io_handle);
+ if (s_info == NULL) {
+ ALOGE("%s: Failed to obtain stream info", __func__);
+ if (new_patch)
+ free(p_info);
+ pthread_mutex_unlock(&adev->lock);
+ ret = -EINVAL;
+ goto done;
+ }
+ ALOGV("%s: Fetched stream info with io_handle %d", __func__, io_handle);
+ s_info->patch_handle = *handle;
+ stream = s_info->stream;
+ }
+ pthread_mutex_unlock(&adev->lock);
// Update routing for stream
if (stream != NULL) {
if (p_info->patch_type == PATCH_PLAYBACK)
- ret = route_output_stream((struct stream_out *) stream, device_type, &addr[0]);
+ ret = route_output_stream((struct stream_out *) stream, &devices);
else if (p_info->patch_type == PATCH_CAPTURE)
- ret = route_input_stream((struct stream_in *) stream,
- device_type, &addr[0], input_source);
- }
-
- if (ret < 0) {
- s_info->patch_handle = AUDIO_PATCH_HANDLE_NONE;
- ALOGE("%s: Stream routing failed for io_handle %d", __func__, io_handle);
- pthread_mutex_unlock(&p_info->lock);
- pthread_mutex_unlock(&s_info->lock);
- goto done;
+ ret = route_input_stream((struct stream_in *) stream, &devices, input_source);
+ if (ret < 0) {
+ pthread_mutex_lock(&adev->lock);
+ s_info->patch_handle = AUDIO_PATCH_HANDLE_NONE;
+ if (new_patch)
+ free(p_info);
+ pthread_mutex_unlock(&adev->lock);
+ ALOGE("%s: Stream routing failed for io_handle %d", __func__, io_handle);
+ goto done;
+ }
}
// Add new patch to patch map
if (!ret && new_patch) {
pthread_mutex_lock(&adev->lock);
hashmapPut(adev->patch_map, (void *) (intptr_t) *handle, (void *) p_info);
- pthread_mutex_unlock(&adev->lock);
ALOGD("%s: Added a new patch with handle %d", __func__, *handle);
+ pthread_mutex_unlock(&adev->lock);
}
- pthread_mutex_unlock(&p_info->lock);
- pthread_mutex_unlock(&s_info->lock);
done:
audio_extn_hw_loopback_create_audio_patch(dev,
num_sources,
@@ -9763,8 +9819,8 @@
{
struct audio_device *adev = (struct audio_device *) dev;
int ret = 0;
- char *addr = "";
audio_source_t input_source = AUDIO_SOURCE_DEFAULT;
+ struct audio_stream *stream = NULL;
if (handle == AUDIO_PATCH_HANDLE_NONE) {
ALOGE("%s: Invalid patch handle %d", __func__, handle);
@@ -9773,64 +9829,65 @@
}
ALOGD("%s: Remove patch with handle %d", __func__, handle);
- struct audio_patch_info *p_info = fetch_patch_info(adev, handle);
+ pthread_mutex_lock(&adev->lock);
+ struct audio_patch_info *p_info = fetch_patch_info_l(adev, handle);
if (p_info == NULL) {
ALOGE("%s: Patch info not found with handle %d", __func__, handle);
+ pthread_mutex_unlock(&adev->lock);
ret = -EINVAL;
goto done;
}
- pthread_mutex_lock(&p_info->lock);
struct audio_patch *patch = p_info->patch;
if (patch == NULL) {
ALOGE("%s: Patch not found for handle %d", __func__, handle);
+ pthread_mutex_unlock(&adev->lock);
ret = -EINVAL;
- pthread_mutex_unlock(&p_info->lock);
goto done;
}
- pthread_mutex_unlock(&p_info->lock);
audio_io_handle_t io_handle = AUDIO_IO_HANDLE_NONE;
switch (patch->sources[0].type) {
case AUDIO_PORT_TYPE_MIX:
io_handle = patch->sources[0].ext.mix.handle;
break;
case AUDIO_PORT_TYPE_DEVICE:
- io_handle = patch->sinks[0].ext.mix.handle;
+ if (p_info->patch_type == PATCH_CAPTURE)
+ io_handle = patch->sinks[0].ext.mix.handle;
break;
case AUDIO_PORT_TYPE_SESSION:
case AUDIO_PORT_TYPE_NONE:
- break;
+ pthread_mutex_unlock(&adev->lock);
+ ret = -EINVAL;
+ goto done;
}
// Remove patch and reset patch handle in stream info
- pthread_mutex_lock(&adev->lock);
- struct audio_stream_info *s_info =
- hashmapGet(adev->io_streams_map, (void *) (intptr_t) io_handle);
- pthread_mutex_unlock(&adev->lock);
- if (s_info == NULL) {
- ALOGE("%s: stream for io_handle %d is not available", __func__, io_handle);
- goto done;
+ patch_map_remove_l(adev, handle);
+ if (p_info->patch_type == PATCH_PLAYBACK ||
+ p_info->patch_type == PATCH_CAPTURE) {
+ struct audio_stream_info *s_info =
+ hashmapGet(adev->io_streams_map, (void *) (intptr_t) io_handle);
+ if (s_info == NULL) {
+ ALOGE("%s: stream for io_handle %d is not available", __func__, io_handle);
+ pthread_mutex_unlock(&adev->lock);
+ goto done;
+ }
+ s_info->patch_handle = AUDIO_PATCH_HANDLE_NONE;
+ stream = s_info->stream;
}
- pthread_mutex_lock(&s_info->lock);
- s_info->patch_handle = AUDIO_PATCH_HANDLE_NONE;
- struct audio_stream *stream = s_info->stream;
+ pthread_mutex_unlock(&adev->lock);
- pthread_mutex_lock(&p_info->lock);
if (stream != NULL) {
+ struct listnode devices;
+ list_init(&devices);
if (p_info->patch_type == PATCH_PLAYBACK)
- ret = route_output_stream((struct stream_out *)stream, AUDIO_DEVICE_NONE, addr);
+ ret = route_output_stream((struct stream_out *) stream, &devices);
else if (p_info->patch_type == PATCH_CAPTURE)
- ret = route_input_stream((struct stream_in *)stream,
- AUDIO_DEVICE_NONE, addr, input_source);
+ ret = route_input_stream((struct stream_in *) stream, &devices, input_source);
}
if (ret < 0)
ALOGW("%s: Stream routing failed for io_handle %d", __func__, io_handle);
- pthread_mutex_unlock(&p_info->lock);
- pthread_mutex_unlock(&s_info->lock);
-
- // Remove patch entry from map
- patch_map_remove(adev, handle);
done:
audio_extn_hw_loopback_release_audio_patch(dev, handle);
audio_extn_auto_hal_release_audio_patch(dev, handle);
@@ -9982,7 +10039,7 @@
struct audio_usecase *uc_info;
float left_p;
float right_p;
- audio_devices_t devices;
+ struct listnode devices;
uc_info = get_usecase_from_list(adev, out->usecase);
if (uc_info == NULL) {
@@ -9996,7 +10053,7 @@
if (restore) {
// restore A2DP device for active usecases and unmute if required
- if (out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ if (is_a2dp_out_device_type(&out->device_list)) {
ALOGD("%s: restoring A2dp and unmuting stream", __func__);
if (uc_info->out_snd_device != SND_DEVICE_OUT_BT_A2DP)
select_devices(adev, uc_info->id);
@@ -10014,8 +10071,8 @@
pthread_mutex_lock(&out->compr_mute_lock);
if (!out->a2dp_compress_mute && !out->standby) {
ALOGD("%s: selecting speaker and muting stream", __func__);
- devices = out->devices;
- out->devices = AUDIO_DEVICE_OUT_SPEAKER;
+ assign_devices(&devices, &out->device_list);
+ reassign_device_list(&out->device_list, AUDIO_DEVICE_OUT_SPEAKER, "");
left_p = out->volume_l;
right_p = out->volume_r;
if (out->offload_state == OFFLOAD_STATE_PLAYING)
@@ -10025,7 +10082,7 @@
select_devices(adev, out->usecase);
if (out->offload_state == OFFLOAD_STATE_PLAYING)
compress_resume(out->compr);
- out->devices = devices;
+ assign_devices(&out->device_list, &devices);
out->volume_l = left_p;
out->volume_r = right_p;
}
@@ -10403,8 +10460,7 @@
adev_open_err:
free_map(adev->patch_map);
free_map(adev->io_streams_map);
- if (adev->snd_dev_ref_cnt)
- free(adev->snd_dev_ref_cnt);
+ free(adev->snd_dev_ref_cnt);
pthread_mutex_destroy(&adev->lock);
free(adev);
adev = NULL;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 5604977..a4cb2e8 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -51,6 +51,7 @@
#include "audio_defs.h"
#include "voice.h"
#include "audio_hw_extn_api.h"
+#include "device_utils.h"
#if LINUX_ENABLED
#if defined(__LP64__)
@@ -334,7 +335,7 @@
unsigned int sample_rate;
audio_channel_mask_t channel_mask;
audio_format_t format;
- audio_devices_t devices;
+ struct listnode device_list;
unsigned int bit_width;
};
@@ -368,7 +369,7 @@
unsigned int sample_rate;
audio_channel_mask_t channel_mask;
audio_format_t format;
- audio_devices_t devices;
+ struct listnode device_list;
audio_output_flags_t flags;
char profile[MAX_STREAM_PROFILE_STR_LEN];
audio_usecase_t usecase;
@@ -465,7 +466,7 @@
int standby;
int source;
int pcm_device_id;
- audio_devices_t device;
+ struct listnode device_list;
audio_channel_mask_t channel_mask;
audio_usecase_t usecase;
bool enable_aec;
@@ -531,13 +532,11 @@
struct audio_patch_info {
struct audio_patch *patch;
patch_type_t patch_type;
- pthread_mutex_t lock;
};
struct audio_stream_info {
struct audio_stream *stream;
audio_patch_handle_t patch_handle;
- pthread_mutex_t lock;
};
union stream_ptr {
@@ -550,7 +549,7 @@
struct listnode list;
audio_usecase_t id;
usecase_type_t type;
- audio_devices_t devices;
+ struct listnode device_list;
snd_device_t out_snd_device;
snd_device_t in_snd_device;
struct stream_app_type_cfg out_app_type_cfg;
@@ -798,12 +797,10 @@
}
int route_output_stream(struct stream_out *stream,
- audio_devices_t devices,
- char *address);
+ struct listnode *devices);
int route_input_stream(struct stream_in *stream,
- audio_devices_t devices,
- char *address,
- audio_source_t source);
+ struct listnode *devices,
+ audio_source_t source);
/*
* NOTE: when multiple mutexes have to be acquired, always take the
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 4a70358..3222516 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -210,7 +210,6 @@
"audio/x-ape" /*ape */,
};
-
enum {
VOICE_FEATURE_SET_DEFAULT,
VOICE_FEATURE_SET_VOLUME_BOOST
@@ -1862,7 +1861,7 @@
}
void platform_set_echo_reference(struct audio_device *adev, bool enable,
- audio_devices_t out_device)
+ struct listnode *out_devices)
{
struct platform_data *my_data = (struct platform_data *)adev->platform;
char ec_ref_mixer_path[MIXER_PATH_MAX_LENGTH] = "echo-reference";
@@ -1898,16 +1897,16 @@
else if (adev->snd_dev_ref_cnt[SND_DEVICE_OUT_DISPLAY_PORT1] > 0)
strlcat(ec_ref_mixer_path, " display-port1",
MIXER_PATH_MAX_LENGTH);
- else if (out_device & AUDIO_DEVICE_OUT_EARPIECE)
+ else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_EARPIECE))
strlcat(ec_ref_mixer_path, " handset",
MIXER_PATH_MAX_LENGTH);
- else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE)
+ else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE))
strlcat(ec_ref_mixer_path, " headphones",
MIXER_PATH_MAX_LENGTH);
- else if (out_device & AUDIO_DEVICE_OUT_USB_HEADSET)
+ else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_USB_HEADSET))
strlcat(ec_ref_mixer_path, " usb-headphones",
MIXER_PATH_MAX_LENGTH);
- else if (out_device & AUDIO_DEVICE_OUT_BUS)
+ else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_BUS))
strlcpy(ec_ref_mixer_path, "multi-mic-echo-reference",
MIXER_PATH_MAX_LENGTH);
@@ -2972,14 +2971,6 @@
list_init(&operator_info_list);
list_init(&app_type_entry_list);
- if(audio_extn_is_concurrent_capture_enabled())
- AUDIO_DEVICE_IN_ALL_CODEC_BACKEND = (AUDIO_DEVICE_IN_BUILTIN_MIC | \
- AUDIO_DEVICE_IN_BACK_MIC | AUDIO_DEVICE_IN_VOICE_CALL) & ~AUDIO_DEVICE_BIT_IN;
- else
- AUDIO_DEVICE_IN_ALL_CODEC_BACKEND = (AUDIO_DEVICE_IN_BUILTIN_MIC | \
- AUDIO_DEVICE_IN_BACK_MIC | AUDIO_DEVICE_IN_WIRED_HEADSET | \
- AUDIO_DEVICE_IN_VOICE_CALL) & ~AUDIO_DEVICE_BIT_IN;
-
adev->snd_card = audio_extn_utils_open_snd_mixer(&adev->mixer);
if (adev->snd_card < 0) {
ALOGE("%s: Unable to find correct sound card", __func__);
@@ -4954,14 +4945,16 @@
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.out && is_offload_usecase(usecase->id) &&
- (usecase->stream.out->devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- usecase->stream.out->devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) &&
- OUTPUT_SAMPLING_RATE_44100 == usecase->stream.out->sample_rate) {
+ (compare_device_type(&usecase->stream.out->device_list,
+ AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
+ compare_device_type(&usecase->stream.out->device_list,
+ AUDIO_DEVICE_OUT_WIRED_HEADSET)) &&
+ OUTPUT_SAMPLING_RATE_44100 == usecase->stream.out->sample_rate) {
ALOGD("%s:napb: triggering dynamic device switch for usecase %d, %s"
" stream %p, device (%u)", __func__, usecase->id,
use_case_table[usecase->id],
(void*) usecase->stream.out,
- usecase->stream.out->devices);
+ get_device_types(&usecase->stream.out->device_list));
select_devices(platform->adev, usecase->id);
}
}
@@ -4987,14 +4980,14 @@
return ret;
}
-int codec_device_supports_native_playback(audio_devices_t out_device)
+int codec_device_supports_native_playback(struct listnode *out_devices)
{
int ret = false;
- if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
- out_device & AUDIO_DEVICE_OUT_LINE ||
- out_device & AUDIO_DEVICE_OUT_USB_HEADSET)
+ if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADSET) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_LINE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_USB_HEADSET))
ret = true;
return ret;
@@ -5072,7 +5065,7 @@
if (voice_is_in_call(my_data->adev))
is_incall_rec_usecase = voice_is_in_call_rec_stream(usecase->stream.in);
- if (usecase->devices & AUDIO_DEVICE_OUT_BUS)
+ if (compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_BUS))
is_bus_dev_usecase = true;
if (usecase->type == PCM_PLAYBACK)
@@ -5155,7 +5148,7 @@
/* Notify device change info to effect clients registered */
if (usecase->type == PCM_PLAYBACK) {
audio_extn_gef_notify_device_config(
- usecase->stream.out->devices,
+ &usecase->stream.out->device_list,
usecase->stream.out->channel_mask,
sample_rate,
acdb_dev_id,
@@ -5937,7 +5930,7 @@
struct audio_device *adev = my_data->adev;
audio_mode_t mode = adev->mode;
snd_device_t snd_device = SND_DEVICE_NONE;
- audio_devices_t devices = out->devices;
+ struct listnode devices;
unsigned int sample_rate = out->sample_rate;
int na_mode = platform_get_native_support();
struct stream_in *in = adev_get_active_input(adev);
@@ -5948,14 +5941,17 @@
int controller = -1;
int stream = -1;
- ALOGV("%s: enter: output devices(%#x)", __func__, devices);
- if (devices == AUDIO_DEVICE_NONE ||
- devices & AUDIO_DEVICE_BIT_IN) {
- ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
+ list_init(&devices);
+ assign_devices(&devices, &out->device_list);
+
+ ALOGV("%s: enter: output devices(%#x)", __func__, get_device_types(&devices));
+ if (list_empty(&devices) ||
+ compare_device_type(&devices, AUDIO_DEVICE_BIT_IN)) {
+ ALOGV("%s: Invalid output devices (%#x)", __func__, get_device_types(&devices));
goto exit;
}
- if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ if (compare_device_type(&devices, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
controller = out->extconn.cs.controller;
stream = out->extconn.cs.stream;
@@ -5967,7 +5963,7 @@
}
}
- if (popcount(devices) == 2) {
+ if (list_length(&devices) == 2) {
bool is_active_voice_call = false;
/*
@@ -5980,8 +5976,8 @@
voice_extn_compress_voip_is_active(adev))
is_active_voice_call = true;
- if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_SPEAKER)) {
+ if (compare_device_type(&devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER)) {
if (my_data->external_spk_1)
snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1;
else if (my_data->external_spk_2)
@@ -5993,11 +5989,11 @@
snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_HIFI_FILTER;
else
snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
- } else if (devices == (AUDIO_DEVICE_OUT_LINE |
- AUDIO_DEVICE_OUT_SPEAKER)) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_LINE) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
- } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_SPEAKER)) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_WIRED_HEADSET) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER)) {
if (audio_extn_get_anc_enabled()) {
if (audio_extn_should_use_fb_anc()) {
if (is_active_voice_call)
@@ -6023,19 +6019,19 @@
else
snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
}
- } else if (devices == (AUDIO_DEVICE_OUT_LINE |
- AUDIO_DEVICE_OUT_SPEAKER)) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_LINE) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
- } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
- devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+ } else if ((compare_device_type(&devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE)) ||
+ (compare_device_type(&devices, AUDIO_DEVICE_OUT_WIRED_HEADSET) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE))) {
snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES;
- } else if (devices == (AUDIO_DEVICE_OUT_LINE |
- AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_LINE) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE;
- } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
- AUDIO_DEVICE_OUT_SPEAKER)) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER)) {
switch(my_data->ext_disp[controller][stream].type) {
case EXT_DISPLAY_TYPE_HDMI:
snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
@@ -6049,22 +6045,22 @@
my_data->ext_disp[controller][stream].type);
goto exit;
}
- } else if (devices == (AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_SPEAKER)) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
- } else if ((devices == (AUDIO_DEVICE_OUT_USB_DEVICE |
- AUDIO_DEVICE_OUT_SPEAKER)) ||
- (devices == (AUDIO_DEVICE_OUT_USB_HEADSET |
- AUDIO_DEVICE_OUT_SPEAKER))) {
+ } else if ((compare_device_type(&devices, AUDIO_DEVICE_OUT_USB_DEVICE) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER)) ||
+ (compare_device_type(&devices, AUDIO_DEVICE_OUT_USB_HEADSET) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER))) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
- } else if ((devices & AUDIO_DEVICE_OUT_SPEAKER) &&
- (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER) &&
+ is_a2dp_out_device_type(&devices)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP;
- } else if ((devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) &&
- (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE) &&
+ is_a2dp_out_device_type(&devices)) {
snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP;
- } else if ((devices & AUDIO_DEVICE_OUT_ALL_SCO) &&
- ((devices & ~AUDIO_DEVICE_OUT_ALL_SCO) == AUDIO_DEVICE_OUT_SPEAKER)) {
+ } else if (is_sco_out_device_type(&devices) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER)) {
if (my_data->is_wsa_speaker) {
if (adev->swb_speech_mode != SPEECH_MODE_INVALID)
snd_device = SND_DEVICE_OUT_SPEAKER_WSA_AND_BT_SCO_SWB;
@@ -6080,21 +6076,21 @@
SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB :
SND_DEVICE_OUT_SPEAKER_AND_BT_SCO;
}
- } else if ((devices & AUDIO_DEVICE_OUT_ALL_SCO) &&
- ((devices & ~AUDIO_DEVICE_OUT_ALL_SCO) == AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+ } else if (is_sco_out_device_type(&devices) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
if (adev->swb_speech_mode != SPEECH_MODE_INVALID)
snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_SWB;
else
snd_device = adev->bt_wb_speech_enabled ?
SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB :
SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO;
- } else if ((devices == (AUDIO_DEVICE_OUT_USB_DEVICE |
- AUDIO_DEVICE_OUT_SPEAKER_SAFE)) ||
- (devices == (AUDIO_DEVICE_OUT_USB_HEADSET |
- AUDIO_DEVICE_OUT_SPEAKER_SAFE))) {
+ } else if ((compare_device_type(&devices, AUDIO_DEVICE_OUT_USB_DEVICE) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE)) ||
+ (compare_device_type(&devices, AUDIO_DEVICE_OUT_USB_HEADSET) &&
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE))) {
snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET;
} else {
- ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
+ ALOGE("%s: Invalid combo device(%#x)", __func__, get_device_types(&devices));
goto exit;
}
if (snd_device != SND_DEVICE_NONE) {
@@ -6102,8 +6098,8 @@
}
}
- if (popcount(devices) != 1) {
- ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
+ if (list_length(&devices) != 1) {
+ ALOGE("%s: Invalid output devices(%#x)", __func__, get_device_types(&devices));
goto exit;
}
@@ -6112,15 +6108,15 @@
voice_extn_compress_voip_is_active(adev) ||
adev->enable_voicerx ||
audio_extn_hfp_is_active(adev)) {
- if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
- devices & AUDIO_DEVICE_OUT_LINE) {
+ if (compare_device_type(&devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_WIRED_HEADSET) ||
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_LINE)) {
if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
!voice_extn_compress_voip_is_active(adev)) {
switch (adev->voice.tty_mode) {
case TTY_MODE_FULL:
if (audio_extn_is_concurrent_capture_enabled() &&
- (devices & AUDIO_DEVICE_OUT_WIRED_HEADSET)) {
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_WIRED_HEADSET)) {
//Separate backend is added for headset-mic as part of concurrent capture
snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADSET;
} else {
@@ -6129,7 +6125,7 @@
break;
case TTY_MODE_VCO:
if (audio_extn_is_concurrent_capture_enabled() &&
- (devices & AUDIO_DEVICE_OUT_WIRED_HEADSET)) {
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_WIRED_HEADSET)) {
//Separate backend is added for headset-mic as part of concurrent capture
snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADSET;
} else {
@@ -6143,7 +6139,7 @@
ALOGE("%s: Invalid TTY mode (%#x)",
__func__, adev->voice.tty_mode);
}
- } else if (devices & AUDIO_DEVICE_OUT_LINE) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_LINE)) {
snd_device = SND_DEVICE_OUT_VOICE_LINE;
} else if (audio_extn_get_anc_enabled()) {
if (audio_extn_should_use_fb_anc())
@@ -6151,15 +6147,14 @@
else
snd_device = SND_DEVICE_OUT_VOICE_ANC_HEADSET;
} else if (audio_extn_is_concurrent_capture_enabled() &&
- (devices & AUDIO_DEVICE_OUT_WIRED_HEADSET)) {
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_WIRED_HEADSET)) {
//Separate backend is added for headset-mic as part of concurrent capture
snd_device = SND_DEVICE_OUT_VOICE_HEADSET;
} else {
snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
}
- } else if (devices &
- (AUDIO_DEVICE_OUT_USB_DEVICE |
- AUDIO_DEVICE_OUT_USB_HEADSET)) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_USB_DEVICE) ||
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_USB_HEADSET)) {
if (voice_is_in_call(adev)) {
switch (adev->voice.tty_mode) {
case TTY_MODE_FULL:
@@ -6184,14 +6179,15 @@
SND_DEVICE_OUT_VOICE_USB_HEADSET :
SND_DEVICE_OUT_VOICE_USB_HEADPHONES;
}
- } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
+ } else if (is_sco_out_device_type(&devices)) {
if (adev->swb_speech_mode != SPEECH_MODE_INVALID)
snd_device = SND_DEVICE_OUT_BT_SCO_SWB;
else if (adev->bt_wb_speech_enabled)
snd_device = SND_DEVICE_OUT_BT_SCO_WB;
else
snd_device = SND_DEVICE_OUT_BT_SCO;
- } else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER) ||
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
if (my_data->is_vbat_speaker || my_data->is_bcl_speaker) {
if (hw_info_is_stereo_spkr(my_data->hw_info)) {
if (my_data->mono_speaker == SPKR_1)
@@ -6222,12 +6218,12 @@
else
snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
}
- } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ } else if (is_a2dp_out_device_type(&devices)) {
snd_device = SND_DEVICE_OUT_BT_A2DP;
- } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
- devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET) ||
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) {
snd_device = SND_DEVICE_OUT_USB_HEADSET;
- } else if ((devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
adev->dp_allowed_for_voice) {
switch(my_data->ext_disp[controller][stream].type) {
case EXT_DISPLAY_TYPE_DP:
@@ -6239,9 +6235,9 @@
my_data->ext_disp[controller][stream].type);
goto exit;
}
- } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_FM_TX)) {
snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
- } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_EARPIECE)) {
if(adev->voice.hac)
snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
else if (is_operator_tmus())
@@ -6250,9 +6246,9 @@
snd_device = SND_DEVICE_OUT_ANC_HANDSET;
else
snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
- } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
snd_device = SND_DEVICE_OUT_VOICE_TX;
- } else if (devices & AUDIO_DEVICE_OUT_HEARING_AID) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_HEARING_AID)) {
snd_device = SND_DEVICE_OUT_VOICE_HEARING_AID;
}
@@ -6261,16 +6257,16 @@
}
}
- if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
- devices & AUDIO_DEVICE_OUT_LINE) {
+ if (compare_device_type(&devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_WIRED_HEADSET) ||
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_LINE)) {
if (OUTPUT_SAMPLING_RATE_44100 == sample_rate &&
NATIVE_AUDIO_MODE_SRC == na_mode &&
!audio_extn_get_anc_enabled()) {
snd_device = SND_DEVICE_OUT_HEADPHONES_44_1;
- } else if (devices & AUDIO_DEVICE_OUT_WIRED_HEADSET
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_WIRED_HEADSET)
&& audio_extn_get_anc_enabled()) {
if (audio_extn_should_use_fb_anc())
snd_device = SND_DEVICE_OUT_ANC_FB_HEADSET;
@@ -6288,15 +6284,15 @@
} else if (audio_extn_is_hifi_filter_enabled(adev, out, snd_device,
my_data->codec_variant, channel_count, 1)) {
snd_device = SND_DEVICE_OUT_HEADPHONES_HIFI_FILTER;
- } else if (devices & AUDIO_DEVICE_OUT_LINE) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_LINE)) {
snd_device = SND_DEVICE_OUT_LINE;
} else
snd_device = SND_DEVICE_OUT_HEADPHONES;
- } else if (devices & AUDIO_DEVICE_OUT_LINE) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_LINE)) {
snd_device = SND_DEVICE_OUT_LINE;
- } else if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
snd_device = SND_DEVICE_OUT_SPEAKER_SAFE;
- } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_SPEAKER)) {
if (my_data->external_spk_1)
snd_device = SND_DEVICE_OUT_SPEAKER_EXTERNAL_1;
else if (my_data->external_spk_2)
@@ -6319,16 +6315,16 @@
snd_device = SND_DEVICE_OUT_SPEAKER_WSA;
else
snd_device = SND_DEVICE_OUT_SPEAKER;
- } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
+ } else if (is_sco_out_device_type(&devices)) {
if (adev->swb_speech_mode != SPEECH_MODE_INVALID)
snd_device = SND_DEVICE_OUT_BT_SCO_SWB;
else if (adev->bt_wb_speech_enabled)
snd_device = SND_DEVICE_OUT_BT_SCO_WB;
else
snd_device = SND_DEVICE_OUT_BT_SCO;
- } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ } else if (is_a2dp_out_device_type(&devices)) {
snd_device = SND_DEVICE_OUT_BT_A2DP;
- } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
switch(my_data->ext_disp[controller][stream].type) {
case EXT_DISPLAY_TYPE_HDMI:
snd_device = SND_DEVICE_OUT_HDMI;
@@ -6342,37 +6338,36 @@
my_data->ext_disp[controller][stream].type);
goto exit;
}
- } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
- devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET) ||
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) {
ALOGD("%s: setting USB hadset channel capability(2) for Proxy", __func__);
snd_device = SND_DEVICE_OUT_USB_HEADSET;
audio_extn_set_afe_proxy_channel_mixer(adev, 2, snd_device);
- } else if (devices &
- (AUDIO_DEVICE_OUT_USB_DEVICE |
- AUDIO_DEVICE_OUT_USB_HEADSET)) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_USB_DEVICE) ||
+ compare_device_type(&devices, AUDIO_DEVICE_OUT_USB_HEADSET)) {
if (audio_extn_qdsp_supported_usb())
snd_device = SND_DEVICE_OUT_USB_HEADSET_SPEC;
else if (audio_extn_usb_is_capture_supported())
snd_device = SND_DEVICE_OUT_USB_HEADSET;
else
snd_device = SND_DEVICE_OUT_USB_HEADPHONES;
- } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_FM_TX)) {
snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
- } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_EARPIECE)) {
/*HAC support for voice-ish audio (eg visual voicemail)*/
if(adev->voice.hac)
snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
else
snd_device = SND_DEVICE_OUT_HANDSET;
- } else if (devices & AUDIO_DEVICE_OUT_PROXY) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_PROXY)) {
channel_count = audio_extn_get_afe_proxy_channel_count();
ALOGD("%s: setting sink capability(%d) for Proxy", __func__, channel_count);
snd_device = SND_DEVICE_OUT_AFE_PROXY;
audio_extn_set_afe_proxy_channel_mixer(adev, channel_count, snd_device);
- } else if (devices & AUDIO_DEVICE_OUT_BUS) {
+ } else if (compare_device_type(&devices, AUDIO_DEVICE_OUT_BUS)) {
snd_device = audio_extn_auto_hal_get_output_snd_device(adev, out->usecase);
} else {
- ALOGE("%s: Unknown device(s) %#x", __func__, devices);
+ ALOGE("%s: Unknown device(s) %#x", __func__, get_device_types(&devices));
}
exit:
ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
@@ -6381,13 +6376,13 @@
static snd_device_t get_snd_device_for_voice_comm_ecns_enabled(struct platform_data *my_data,
struct stream_in *in,
- audio_devices_t out_device __unused,
- audio_devices_t in_device)
+ struct listnode *out_devices __unused,
+ struct listnode *in_devices)
{
struct audio_device *adev = my_data->adev;
snd_device_t snd_device = SND_DEVICE_NONE;
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (compare_device_type(in_devices, AUDIO_DEVICE_IN_BACK_MIC)) {
if (my_data->fluence_in_spkr_mode) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
@@ -6409,7 +6404,7 @@
snd_device = my_data->fluence_sb_enabled ?
SND_DEVICE_IN_SPEAKER_MIC_SB
: SND_DEVICE_IN_SPEAKER_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ } else if (compare_device_type(in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC)) {
if ((my_data->fluence_type & FLUENCE_TRI_MIC) &&
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_TMIC_AEC_NS;
@@ -6424,7 +6419,7 @@
snd_device = my_data->fluence_sb_enabled ?
SND_DEVICE_IN_HANDSET_MIC_SB
: SND_DEVICE_IN_HANDSET_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ } else if (compare_device_type(in_devices, AUDIO_DEVICE_IN_WIRED_HEADSET)) {
snd_device = SND_DEVICE_IN_HEADSET_MIC;
}
in->enable_ec_port = true;
@@ -6434,14 +6429,14 @@
static snd_device_t get_snd_device_for_voice_comm_ecns_disabled(struct platform_data *my_data,
struct stream_in *in,
- audio_devices_t out_device,
- audio_devices_t in_device)
+ struct listnode *out_devices,
+ struct listnode *in_devices)
{
struct audio_device *adev = my_data->adev;
snd_device_t snd_device = SND_DEVICE_NONE;
if (in != NULL && in->enable_aec && in->enable_ns) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (compare_device_type(in_devices, AUDIO_DEVICE_IN_BACK_MIC)) {
if (my_data->fluence_in_spkr_mode) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
@@ -6464,7 +6459,7 @@
snd_device = my_data->fluence_sb_enabled ?
SND_DEVICE_IN_SPEAKER_MIC_AEC_NS_SB
: SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ } else if (compare_device_type(in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC)) {
if ((my_data->fluence_type & FLUENCE_TRI_MIC) &&
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_TMIC_AEC_NS;
@@ -6480,13 +6475,14 @@
snd_device = my_data->fluence_sb_enabled ?
SND_DEVICE_IN_HANDSET_MIC_AEC_NS_SB
: SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ } else if (compare_device_type(in_devices, AUDIO_DEVICE_IN_WIRED_HEADSET)) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- } else if (audio_extn_usb_connected(NULL) && audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
+ } else if (audio_extn_usb_connected(NULL) &&
+ is_usb_in_device_type(in_devices)) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
} else if (in != NULL && in->enable_aec) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (compare_device_type(in_devices, AUDIO_DEVICE_IN_BACK_MIC)) {
if (my_data->fluence_in_spkr_mode) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
@@ -6509,7 +6505,7 @@
snd_device = my_data->fluence_sb_enabled ?
SND_DEVICE_IN_SPEAKER_MIC_AEC_SB
: SND_DEVICE_IN_SPEAKER_MIC_AEC;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ } else if (compare_device_type(in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC)) {
if ((my_data->fluence_type & FLUENCE_TRI_MIC) &&
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_TMIC_AEC;
@@ -6523,13 +6519,13 @@
adev->acdb_settings |= DMIC_FLAG;
} else
snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ } else if (compare_device_type(in_devices, AUDIO_DEVICE_IN_WIRED_HEADSET)) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- } else if (audio_extn_usb_connected(NULL) && audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
+ } else if (audio_extn_usb_connected(NULL) && is_usb_in_device_type(in_devices)) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
}
} else if (in != NULL && in->enable_ns) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (compare_device_type(in_devices, AUDIO_DEVICE_IN_BACK_MIC)) {
if (my_data->fluence_in_spkr_mode) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
@@ -6552,7 +6548,7 @@
snd_device = my_data->fluence_sb_enabled ?
SND_DEVICE_IN_SPEAKER_MIC_NS_SB
: SND_DEVICE_IN_SPEAKER_MIC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ } else if (compare_device_type(in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC)) {
if ((my_data->fluence_type & FLUENCE_TRI_MIC) &&
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_TMIC_NS;
@@ -6566,42 +6562,45 @@
adev->acdb_settings |= DMIC_FLAG;
} else
snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ } else if (compare_device_type(in_devices, AUDIO_DEVICE_IN_WIRED_HEADSET)) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
}
- platform_set_echo_reference(adev, false, out_device);
+ platform_set_echo_reference(adev, false, out_devices);
} else
- platform_set_echo_reference(adev, false, out_device);
+ platform_set_echo_reference(adev, false, out_devices);
return snd_device;
}
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 listnode *out_devices,
+ struct listnode *in_devices)
{
if(voice_extn_is_dynamic_ecns_enabled())
- return get_snd_device_for_voice_comm_ecns_enabled(my_data, in, out_device, in_device);
+ return get_snd_device_for_voice_comm_ecns_enabled(my_data, in, out_devices, in_devices);
else
- return get_snd_device_for_voice_comm_ecns_disabled(my_data, in, out_device, in_device);
+ return get_snd_device_for_voice_comm_ecns_disabled(my_data, in, out_devices, in_devices);
}
snd_device_t platform_get_input_snd_device(void *platform,
struct stream_in *in,
- audio_devices_t out_device)
+ struct listnode *out_devices)
{
struct platform_data *my_data = (struct platform_data *)platform;
struct audio_device *adev = my_data->adev;
audio_mode_t mode = adev->mode;
snd_device_t snd_device = SND_DEVICE_NONE;
+ struct listnode in_devices;
+ char *address = "";
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;
+ list_init(&in_devices);
+ if (in != NULL)
+ assign_devices(&in_devices, &in->device_list);
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);
int str_bitwidth = (in == NULL) ? CODEC_BACKEND_DEFAULT_BIT_WIDTH : in->bit_width;
@@ -6610,18 +6609,19 @@
audio_usecase_t uc_id = (in == NULL) ? USECASE_AUDIO_RECORD : in->usecase;
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);
+ __func__, get_device_types(out_devices), get_device_types(&in_devices),
+ channel_count, channel_mask);
if (my_data->external_mic) {
- if ((out_device != AUDIO_DEVICE_NONE) && ((mode == AUDIO_MODE_IN_CALL) ||
+ if (!list_empty(out_devices) && ((mode == AUDIO_MODE_IN_CALL) ||
voice_check_voicecall_usecases_active(adev) ||
voice_extn_compress_voip_is_active(adev) ||
audio_extn_hfp_is_active(adev))) {
- if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- out_device & AUDIO_DEVICE_OUT_EARPIECE ||
- out_device & AUDIO_DEVICE_OUT_SPEAKER )
+ if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_EARPIECE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_SPEAKER))
snd_device = SND_DEVICE_IN_HANDSET_MIC_EXTERNAL;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
- in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC) ||
+ compare_device_type(&in_devices, AUDIO_DEVICE_IN_BACK_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_MIC_EXTERNAL;
}
}
@@ -6629,15 +6629,15 @@
if (snd_device != AUDIO_DEVICE_NONE)
goto exit;
- if ((out_device != AUDIO_DEVICE_NONE) && ((mode == AUDIO_MODE_IN_CALL) ||
+ if (!list_empty(out_devices) && ((mode == AUDIO_MODE_IN_CALL) ||
voice_check_voicecall_usecases_active(adev) ||
voice_extn_compress_voip_is_active(adev) ||
audio_extn_hfp_is_active(adev))) {
if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
!voice_extn_compress_voip_is_active(adev)) {
- if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
- out_device & AUDIO_DEVICE_OUT_LINE) {
+ if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADSET) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_LINE)) {
switch (adev->voice.tty_mode) {
case TTY_MODE_FULL:
snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
@@ -6652,9 +6652,8 @@
ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
}
goto exit;
- } else if (out_device &
- (AUDIO_DEVICE_OUT_USB_DEVICE |
- AUDIO_DEVICE_OUT_USB_HEADSET)) {
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_USB_DEVICE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_USB_HEADSET)) {
switch (adev->voice.tty_mode) {
case TTY_MODE_FULL:
snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC;
@@ -6672,10 +6671,10 @@
goto exit;
}
}
- if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
- out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- out_device & AUDIO_DEVICE_OUT_LINE) {
- if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
+ if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_EARPIECE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_LINE)) {
+ if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_EARPIECE) &&
audio_extn_should_use_handset_anc(channel_count)) {
if ((my_data->fluence_type != FLUENCE_NONE) &&
(my_data->source_mic_type & SOURCE_DUAL_MIC)) {
@@ -6688,7 +6687,7 @@
} else if (my_data->fluence_type == FLUENCE_NONE ||
(my_data->fluence_in_voice_call == false &&
my_data->fluence_in_hfp_call == false)) {
- if (out_device & AUDIO_DEVICE_OUT_LINE &&
+ if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_LINE) &&
audio_extn_hfp_is_active(adev)) {
snd_device = my_data->fluence_sb_enabled ?
SND_DEVICE_IN_VOICE_SPEAKER_MIC_SB
@@ -6699,7 +6698,7 @@
: SND_DEVICE_IN_HANDSET_MIC;
}
if (audio_extn_hfp_is_active(adev))
- platform_set_echo_reference(adev, true, out_device);
+ platform_set_echo_reference(adev, true, out_devices);
} else {
if ((my_data->fluence_type & FLUENCE_TRI_MIC) &&
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
@@ -6714,11 +6713,11 @@
adev->acdb_settings |= DMIC_FLAG;
}
}
- } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADSET)) {
snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
if (audio_extn_hfp_is_active(adev))
- platform_set_echo_reference(adev, true, out_device);
- } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
+ platform_set_echo_reference(adev, true, out_devices);
+ } else if (is_sco_out_device_type(out_devices)) {
if (adev->swb_speech_mode != SPEECH_MODE_INVALID) {
if (adev->bluetooth_nrec)
snd_device = SND_DEVICE_IN_BT_SCO_MIC_SWB_NREC;
@@ -6735,7 +6734,7 @@
else
snd_device = SND_DEVICE_IN_BT_SCO_MIC;
}
- } else if ((out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
adev->dp_allowed_for_voice) {
if (audio_extn_usb_is_capture_supported())
snd_device = SND_DEVICE_IN_VOICE_USB_HEADSET_MIC;
@@ -6745,11 +6744,11 @@
: SND_DEVICE_IN_HANDSET_MIC;
if (voice_is_in_call(adev))
- platform_set_echo_reference(adev, true, out_device);
- } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
- out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
- out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- out_device & AUDIO_DEVICE_OUT_LINE) {
+ platform_set_echo_reference(adev, true, out_devices);
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_SPEAKER) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_LINE)) {
if (my_data->fluence_type != FLUENCE_NONE &&
(my_data->fluence_in_voice_call ||
my_data->fluence_in_hfp_call) &&
@@ -6772,24 +6771,23 @@
: SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
}
if (audio_extn_hfp_is_active(adev))
- platform_set_echo_reference(adev, true, out_device);
+ platform_set_echo_reference(adev, true, out_devices);
} else {
if (adev->enable_hfp) {
snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP;
- platform_set_echo_reference(adev, true, out_device);
+ platform_set_echo_reference(adev, true, out_devices);
} else {
snd_device = my_data->fluence_sb_enabled ?
SND_DEVICE_IN_VOICE_SPEAKER_MIC_SB
: SND_DEVICE_IN_VOICE_SPEAKER_MIC;
if (audio_extn_hfp_is_active(adev))
- platform_set_echo_reference(adev, true, out_device);
+ platform_set_echo_reference(adev, true, out_devices);
}
}
- } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX) {
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
snd_device = SND_DEVICE_IN_VOICE_RX;
- } else if (out_device &
- (AUDIO_DEVICE_OUT_USB_DEVICE |
- AUDIO_DEVICE_OUT_USB_HEADSET)) {
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_USB_DEVICE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_USB_HEADSET)) {
if (audio_extn_usb_is_capture_supported()) {
snd_device = SND_DEVICE_IN_VOICE_USB_HEADSET_MIC;
} else if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode) {
@@ -6801,25 +6799,25 @@
} else {
snd_device = SND_DEVICE_IN_HANDSET_MIC;
}
- } else if (out_device & AUDIO_DEVICE_OUT_HEARING_AID) {
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_HEARING_AID)) {
snd_device = SND_DEVICE_IN_VOICE_HEARING_AID;
}
} else if (my_data->use_generic_handset == true && // system prop is enabled
(my_data->source_mic_type & SOURCE_QUAD_MIC) && // AND 4mic is available
- ((in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) || // AND device is buit-in mic or back mic
- (in_device & AUDIO_DEVICE_IN_BACK_MIC)) &&
+ (compare_device_type(&in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC) || // AND device is buit-in mic or back mic
+ compare_device_type(&in_devices, AUDIO_DEVICE_IN_BACK_MIC)) &&
(my_data->fluence_in_audio_rec == true && // AND fluencepro is enabled
my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(source == AUDIO_SOURCE_CAMCORDER || // AND source is cam/mic/unprocessed
source == AUDIO_SOURCE_UNPROCESSED ||
source == AUDIO_SOURCE_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_GENERIC_QMIC;
- platform_set_echo_reference(adev, true, out_device);
+ platform_set_echo_reference(adev, true, out_devices);
} else if (my_data->use_generic_handset == true && // System prop is enabled
(my_data->ambisonic_capture == true) && // Enable Ambisonic capture
(my_data->source_mic_type & SOURCE_QUAD_MIC) && // AND 4mic is available
- ((in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) || // AND device is Built-in
- (in_device & AUDIO_DEVICE_IN_BACK_MIC)) && // OR Back-mic
+ (compare_device_type(&in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC) || // AND device is Built-in
+ compare_device_type(&in_devices, AUDIO_DEVICE_IN_BACK_MIC)) && // OR Back-mic
(source == AUDIO_SOURCE_MIC || // AND source is MIC for 16bit
source == AUDIO_SOURCE_UNPROCESSED || // OR unprocessed for 24bit
source == AUDIO_SOURCE_CAMCORDER) && // OR camera usecase
@@ -6847,8 +6845,8 @@
}
}
} else if (source == AUDIO_SOURCE_CAMCORDER) {
- if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
- in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC) ||
+ compare_device_type(&in_devices, AUDIO_DEVICE_IN_BACK_MIC)) {
switch (adev->camera_orientation) {
case CAMERA_BACK_LANDSCAPE:
snd_device = SND_DEVICE_IN_CAMCORDER_LANDSCAPE;
@@ -6902,7 +6900,7 @@
}
}
} else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
- if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC)) {
if (my_data->fluence_in_voice_rec && channel_count == 1) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
@@ -6947,15 +6945,15 @@
else
snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
}
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_WIRED_HEADSET)) {
snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
- } else if (audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
+ } else if (is_usb_in_device_type(&in_devices)) {
snd_device = fixup_usb_headset_mic_snd_device(platform,
SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC,
SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MULTI_CHANNEL_MIC);
}
} else if (source == AUDIO_SOURCE_UNPROCESSED) {
- if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC)) {
if (((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) ||
(channel_mask == AUDIO_CHANNEL_IN_STEREO)) &&
(my_data->source_mic_type & SOURCE_DUAL_MIC)) {
@@ -6969,40 +6967,43 @@
} else {
snd_device = SND_DEVICE_IN_UNPROCESSED_MIC;
}
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_WIRED_HEADSET)) {
snd_device = SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC;
- } else if (audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
+ } else if (is_usb_in_device_type(&in_devices)) {
snd_device = fixup_usb_headset_mic_snd_device(platform,
SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC,
SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MULTI_CHANNEL_MIC);
}
} else if ((source == AUDIO_SOURCE_VOICE_COMMUNICATION) ||
(mode == AUDIO_MODE_IN_COMMUNICATION)) {
- if (out_device & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
- out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- (out_device & (AUDIO_DEVICE_OUT_USB_DEVICE | AUDIO_DEVICE_OUT_USB_HEADSET) &&
+ if ((compare_device_type(out_devices, AUDIO_DEVICE_OUT_SPEAKER) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE)) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
+ ((compare_device_type(out_devices, AUDIO_DEVICE_OUT_USB_DEVICE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_USB_HEADSET)) &&
!audio_extn_usb_is_capture_supported()))
- in_device = AUDIO_DEVICE_IN_BACK_MIC;
- else if (out_device & AUDIO_DEVICE_OUT_EARPIECE)
- in_device = AUDIO_DEVICE_IN_BUILTIN_MIC;
- else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET)
- in_device = AUDIO_DEVICE_IN_WIRED_HEADSET;
- else if (out_device & AUDIO_DEVICE_OUT_USB_DEVICE)
- in_device = AUDIO_DEVICE_IN_USB_DEVICE;
+ reassign_device_list(&in_devices, AUDIO_DEVICE_IN_BACK_MIC, address);
+ else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_EARPIECE))
+ reassign_device_list(&in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC, address);
+ else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADSET))
+ reassign_device_list(&in_devices, AUDIO_DEVICE_IN_WIRED_HEADSET, address);
+ else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_USB_DEVICE))
+ reassign_device_list(&in_devices, AUDIO_DEVICE_IN_USB_DEVICE, address);
- in_device = ((out_device == AUDIO_DEVICE_NONE) ?
- AUDIO_DEVICE_IN_BUILTIN_MIC : in_device) & ~AUDIO_DEVICE_BIT_IN;
+ if (list_empty(out_devices))
+ reassign_device_list(&in_devices, (AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN),
+ address);
if (in)
- snd_device = get_snd_device_for_voice_comm(my_data, in, out_device, in_device);
+ snd_device = get_snd_device_for_voice_comm(my_data, in, out_devices, &in_devices);
} else if (source == AUDIO_SOURCE_MIC) {
- if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
+ if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC) &&
channel_count == 1 ) {
if(my_data->fluence_in_audio_rec) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_QMIC;
- platform_set_echo_reference(adev, true, out_device);
+ platform_set_echo_reference(adev, true, out_devices);
} else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_TMIC_FLUENCE_PRO;
@@ -7012,11 +7013,11 @@
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_DUAL_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_DMIC;
- platform_set_echo_reference(adev, true, out_device);
+ platform_set_echo_reference(adev, true, out_devices);
}
}
- } else if (in_device & AUDIO_DEVICE_IN_LOOPBACK) {
- if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_LOOPBACK)) {
+ if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC)) {
usecase = get_usecase_from_list(adev, uc_id);
if (usecase == NULL) {
ALOGE("%s: Could not find the record usecase", __func__);
@@ -7043,10 +7044,10 @@
goto exit;
}
- if (in_device != AUDIO_DEVICE_NONE &&
- !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
- !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
- if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if (!list_empty(&in_devices) &&
+ !(compare_device_type(&in_devices, AUDIO_DEVICE_IN_VOICE_CALL)) &&
+ !(compare_device_type(&in_devices, AUDIO_DEVICE_IN_COMMUNICATION))) {
+ if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_BUILTIN_MIC)) {
if ((in && (audio_extn_ssr_get_stream() == in)) ||
((my_data->source_mic_type & SOURCE_QUAD_MIC) &&
channel_mask == AUDIO_CHANNEL_INDEX_MASK_4))
@@ -7060,7 +7061,7 @@
else
snd_device = my_data->fluence_sb_enabled ? SND_DEVICE_IN_HANDSET_MIC_SB
: SND_DEVICE_IN_HANDSET_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_BACK_MIC)) {
if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
channel_count == 2)
snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
@@ -7068,11 +7069,11 @@
snd_device = my_data->fluence_sb_enabled ?
SND_DEVICE_IN_SPEAKER_MIC_SB
: SND_DEVICE_IN_SPEAKER_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_LINE) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_LINE)) {
snd_device = SND_DEVICE_IN_LINE;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_WIRED_HEADSET)) {
snd_device = SND_DEVICE_IN_HEADSET_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
if (adev->swb_speech_mode != SPEECH_MODE_INVALID) {
if (adev->bluetooth_nrec)
snd_device = SND_DEVICE_IN_BT_SCO_MIC_SWB_NREC;
@@ -7089,37 +7090,38 @@
else
snd_device = SND_DEVICE_IN_BT_SCO_MIC;
}
- } else if (in_device & AUDIO_DEVICE_IN_SPDIF) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_SPDIF)) {
snd_device = SND_DEVICE_IN_SPDIF;
- } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_BLUETOOTH_A2DP)) {
snd_device = SND_DEVICE_IN_BT_A2DP;
- } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_AUX_DIGITAL)) {
snd_device = SND_DEVICE_IN_HDMI_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_HDMI_ARC) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_HDMI_ARC)) {
snd_device = SND_DEVICE_IN_HDMI_ARC;
- } else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
- in_device & AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET) ||
+ compare_device_type(&in_devices, AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET)) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_FM_TUNER) {
+ } else if (compare_device_type(&in_devices, AUDIO_DEVICE_IN_FM_TUNER)) {
snd_device = SND_DEVICE_IN_CAPTURE_FM;
- } else if (audio_extn_usb_connected(NULL) && audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
+ } else if (audio_extn_usb_connected(NULL) &&
+ is_usb_in_device_type(&in_devices)) {
snd_device = fixup_usb_headset_mic_snd_device(platform,
SND_DEVICE_IN_USB_HEADSET_MIC,
SND_DEVICE_IN_USB_HEADSET_MULTI_CHANNEL_MIC);
} else {
- ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
+ ALOGE("%s: Unknown input device(s) %#x", __func__, get_device_types(&in_devices));
ALOGW("%s: Using default handset-mic", __func__);
snd_device = my_data->fluence_sb_enabled ? SND_DEVICE_IN_HANDSET_MIC_SB
: SND_DEVICE_IN_HANDSET_MIC;
}
} else {
- if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
+ if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_EARPIECE)) {
snd_device = my_data->fluence_sb_enabled ? SND_DEVICE_IN_HANDSET_MIC_SB
: SND_DEVICE_IN_HANDSET_MIC;
- } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADSET)) {
snd_device = SND_DEVICE_IN_HEADSET_MIC;
- } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
- out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_SPEAKER) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
(channel_count == 2)) {
snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
@@ -7136,11 +7138,11 @@
SND_DEVICE_IN_SPEAKER_MIC_SB
: SND_DEVICE_IN_SPEAKER_MIC;
}
- } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- out_device & AUDIO_DEVICE_OUT_LINE) {
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_LINE)) {
snd_device = my_data->fluence_sb_enabled ? SND_DEVICE_IN_HANDSET_MIC_SB
: SND_DEVICE_IN_HANDSET_MIC;
- } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) {
if (adev->swb_speech_mode != SPEECH_MODE_INVALID) {
if (adev->bluetooth_nrec)
snd_device = SND_DEVICE_IN_BT_SCO_MIC_SWB_NREC;
@@ -7157,14 +7159,13 @@
else
snd_device = SND_DEVICE_IN_BT_SCO_MIC;
}
- } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
snd_device = SND_DEVICE_IN_HDMI_MIC;
- } else if (out_device & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
- out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) {
snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
- } else if (out_device &
- (AUDIO_DEVICE_OUT_USB_DEVICE |
- AUDIO_DEVICE_OUT_USB_HEADSET)) {
+ } else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_USB_DEVICE) ||
+ compare_device_type(out_devices, AUDIO_DEVICE_OUT_USB_HEADSET)) {
if (audio_extn_usb_is_capture_supported() && audio_extn_usb_connected(NULL))
snd_device = fixup_usb_headset_mic_snd_device(platform,
SND_DEVICE_IN_USB_HEADSET_MIC,
@@ -7173,7 +7174,7 @@
snd_device = SND_DEVICE_IN_HANDSET_MIC;
} else {
- ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
+ ALOGE("%s: Unknown output device(s) %#x", __func__, get_device_types(out_devices));
ALOGW("%s: Using default handset-mic", __func__);
snd_device = my_data->fluence_sb_enabled ? SND_DEVICE_IN_HANDSET_MIC_SB
: SND_DEVICE_IN_HANDSET_MIC;
@@ -7606,6 +7607,7 @@
uint8_t *dptr = NULL;
int32_t dlen;
int err, ret;
+ char *address = "";
if(value == NULL || platform == NULL || parms == NULL) {
ALOGE("[%s] received null pointer, failed",__func__);
goto done_key_audcal;
@@ -7635,13 +7637,17 @@
goto done_key_audcal;
}
+ list_init(&out.device_list);
if (cal.dev_id) {
if (audio_is_input_device(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);
+ struct listnode cal_devices;
+ list_init(&cal_devices);
+ update_device_list(&cal_devices, cal.dev_id, address, true);
+ cal.snd_dev_id = platform_get_input_snd_device(platform, NULL, &cal_devices);
} else {
- out.devices = cal.dev_id;
+ reassign_device_list(&out.device_list, cal.dev_id, address);
out.sample_rate = cal.sampling_rate;
cal.snd_dev_id = platform_get_output_snd_device(platform, &out);
}
@@ -8198,6 +8204,7 @@
char *rparms=NULL;
int ret=0, err;
uint32_t param_len;
+ char *address = "";
if(query==NULL || platform==NULL || reply==NULL) {
ALOGE("[%s] received null pointer",__func__);
@@ -8219,10 +8226,14 @@
goto done;
}
+ list_init(&out.device_list);
if (cal.dev_id & AUDIO_DEVICE_BIT_IN) {
- cal.snd_dev_id = platform_get_input_snd_device(platform, NULL, cal.dev_id);
- } else if(cal.dev_id) {
- out.devices = cal.dev_id;
+ struct listnode devices;
+ list_init(&devices);
+ update_device_list(&devices, cal.dev_id, address, true);
+ cal.snd_dev_id = platform_get_input_snd_device(platform, NULL, &devices);
+ } else if (cal.dev_id) {
+ reassign_device_list(&out.device_list, cal.dev_id, address);
out.sample_rate = cal.sampling_rate;
cal.snd_dev_id = platform_get_output_snd_device(platform, &out);
}
@@ -9042,6 +9053,7 @@
bool passthrough_enabled = false;
int controller = -1;
int stream = -1;
+ uint32_t compr_passthr = 0;
if (!usecase) {
ALOGE("%s: becf: HDMI: usecase is NULL", __func__);
@@ -9067,8 +9079,15 @@
", usecase = %d", __func__, bit_width,
sample_rate, channels, usecase->id);
+#ifdef AUDIO_GKI_ENABLED
+ /* out->compr_config.codec->reserved[0] is for compr_passthr */
+ compr_passthr = usecase->stream.out->compr_config.codec->reserved[0];
+#else
+ compr_passthr = usecase->stream.out->compr_config.codec->compr_passthr;
+#endif
+
if (audio_extn_passthru_is_enabled() && audio_extn_passthru_is_active()
- && (usecase->stream.out->compr_config.codec->compr_passthr != 0)) {
+ && (compr_passthr != 0)) {
passthrough_enabled = true;
ALOGI("passthrough is enabled for this stream");
}
@@ -9109,7 +9128,7 @@
if (((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
(usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC) ||
(usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD))
- && (usecase->stream.out->compr_config.codec->compr_passthr == PASSTHROUGH)) {
+ && (compr_passthr == PASSTHROUGH)) {
sample_rate = sample_rate * 4;
if (sample_rate > HDMI_PASSTHROUGH_MAX_SAMPLE_RATE)
sample_rate = HDMI_PASSTHROUGH_MAX_SAMPLE_RATE;
@@ -9241,7 +9260,7 @@
}
/* Native playback is preferred for Headphone/HS device over 192Khz */
- if (!voice_call_active && codec_device_supports_native_playback(usecase->devices)) {
+ if (!voice_call_active && codec_device_supports_native_playback(&usecase->device_list)) {
if (audio_is_true_native_stream_active(adev)) {
if (check_hdset_combo_device(snd_device)) {
/*
@@ -9370,7 +9389,7 @@
* Handset and speaker may have diffrent backend. Check if the device is speaker or handset,
* and these devices are restricited to 48kHz.
*/
- if (!codec_device_supports_native_playback(usecase->devices) &&
+ if (!codec_device_supports_native_playback(&usecase->device_list) &&
(platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, snd_device) ||
platform_check_backends_match(SND_DEVICE_OUT_HANDSET, snd_device))) {
int bw = platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
@@ -9706,7 +9725,8 @@
backend_cfg.bit_width= usecase->stream.in->bit_width;
backend_cfg.format= usecase->stream.in->format;
backend_cfg.channels = audio_channel_count_from_in_mask(usecase->stream.in->channel_mask);
- if (is_loopback_input_device(usecase->stream.in->device)) {
+ if (is_loopback_input_device(
+ get_device_types(&usecase->stream.in->device_list))) {
int bw = platform_get_snd_device_bit_width(snd_device);
if ((-ENOSYS != bw) && (backend_cfg.bit_width > (uint32_t)bw)) {
backend_cfg.bit_width = bw;
@@ -11386,7 +11406,8 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->stream.out && usecase->type == PCM_PLAYBACK &&
- usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
+ compare_device_type(&usecase->stream.out->device_list,
+ AUDIO_DEVICE_OUT_SPEAKER)) {
/*
* If acdb tuning is different for SPEAKER_REVERSE, it is must
* to perform device switch to disable the current backend to
@@ -11633,9 +11654,11 @@
}
size_t max_mic_count = my_data->declared_mic_count;
size_t actual_mic_count = 0;
+ struct listnode devices;
+ list_init(&devices);
snd_device_t active_input_snd_device =
- platform_get_input_snd_device(platform, usecase->stream.in, AUDIO_DEVICE_NONE);
+ platform_get_input_snd_device(platform, usecase->stream.in, &devices);
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 f59f514..7bb699c 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -50,28 +50,6 @@
SPKR_2
};
-/*
- * Below are the devices for which is back end is same, SLIMBUS_0_RX.
- * All these devices are handled by the internal HW codec. We can
- * enable any one of these devices at any time. An exception here is
- * 44.1k headphone which uses different backend. This is filtered
- * as different hal internal device in the code but remains same
- * as standard android device AUDIO_DEVICE_OUT_WIRED_HEADPHONE
- * for other layers.
- */
-#define AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND \
- (AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | \
- AUDIO_DEVICE_OUT_SPEAKER_SAFE | \
- AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE | \
- AUDIO_DEVICE_OUT_LINE)
-
-/*
- * Below are the input devices for which back end is same, SLIMBUS_0_TX.
- * All these devices are handled by the internal HW codec. We can
- * enable any one of these devices at any time
- */
-int AUDIO_DEVICE_IN_ALL_CODEC_BACKEND;
-
/* Sound devices specific to the platform
* The DEVICE_OUT_* and DEVICE_IN_* should be mapped to these sound
* devices to enable corresponding mixer paths
diff --git a/hal/platform_api.h b/hal/platform_api.h
index cd5f888..fbf159a 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -207,7 +207,7 @@
snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *out);
snd_device_t platform_get_input_snd_device(void *platform,
struct stream_in *in,
- audio_devices_t out_device);
+ struct listnode *out_devices);
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,
@@ -268,7 +268,8 @@
struct audio_usecase *usecase, snd_device_t snd_device);
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);
-void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device);
+void platform_set_echo_reference(struct audio_device *adev, bool enable,
+ struct listnode *out_devices);
int platform_check_and_set_swap_lr_channels(struct audio_device *adev, bool swap_channels);
int platform_set_swap_channels(struct audio_device *adev, bool swap_channels);
void platform_get_device_to_be_id_map(int **be_id_map, int *length);
diff --git a/hal/voice.c b/hal/voice.c
index 0000d72..818eb94 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -239,11 +239,12 @@
uc_info->id = usecase_id;
uc_info->type = VOICE_CALL;
uc_info->stream.out = adev->current_call_output;
- uc_info->devices = adev->current_call_output->devices;
+ list_init(&uc_info->device_list);
+ assign_devices(&uc_info->device_list, &adev->current_call_output->device_list);
- if (popcount(uc_info->devices) == 2) {
+ if (list_length(&uc_info->device_list) == 2) {
ALOGE("%s: Invalid combo device(%#x) for voice call", __func__,
- uc_info->devices);
+ get_device_types(&uc_info->device_list));
ret = -EIO;
goto error_start_voice;
}
@@ -252,7 +253,7 @@
uc_info->out_snd_device = SND_DEVICE_NONE;
adev->voice.use_device_mute = false;
- if (audio_is_bluetooth_sco_device(uc_info->devices) && !adev->bt_sco_on) {
+ if (is_sco_out_device_type(&uc_info->device_list) && !adev->bt_sco_on) {
ALOGE("start_call: couldn't find BT SCO, SCO is not ready");
adev->voice.in_call = false;
ret = -EIO;
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index fbd6d6f..2d14bf0 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, 2020, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -450,7 +450,7 @@
goto error;
}
- if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
+ if (is_sco_out_device_type(&out->device_list)) {
if (!adev->bt_sco_on) {
ALOGE("%s: SCO profile is not ready, return error", __func__);
ret = -EAGAIN;
@@ -466,7 +466,7 @@
uc_info = get_usecase_from_list(adev, USECASE_COMPRESS_VOIP_CALL);
if (uc_info) {
uc_info->stream.out = out;
- uc_info->devices = out->devices;
+ assign_devices(&uc_info->device_list, &out->device_list);
} else {
ret = -EINVAL;
ALOGE("%s: exit(%d): failed to get use case info", __func__, ret);
@@ -492,7 +492,7 @@
goto error;
}
- if (audio_is_bluetooth_sco_device(in->device) && !adev->bt_sco_on) {
+ if (is_sco_in_device_type(&in->device_list) && !adev->bt_sco_on) {
ret = -EIO;
ALOGE("%s SCO is not ready return error %d", __func__,ret);
goto error;
diff --git a/visualizer/offload_visualizer.c b/visualizer/offload_visualizer.c
index 442ef3e..e1a34a0 100644
--- a/visualizer/offload_visualizer.c
+++ b/visualizer/offload_visualizer.c
@@ -971,17 +971,19 @@
if (context->state == EFFECT_STATE_ACTIVE) {
int32_t latency_ms = visu_ctxt->latency;
- const uint32_t delta_ms = visualizer_get_delta_time_ms_from_updated_time(visu_ctxt);
+ const int32_t delta_ms = visualizer_get_delta_time_ms_from_updated_time(visu_ctxt);
latency_ms -= delta_ms;
if (latency_ms < 0) {
latency_ms = 0;
}
const uint32_t delta_smp = context->config.inputCfg.samplingRate * latency_ms / 1000;
- int32_t capture_point = visu_ctxt->capture_idx - visu_ctxt->capture_size - delta_smp;
- int32_t capture_size = visu_ctxt->capture_size;
+ int64_t capture_point = visu_ctxt->capture_idx;
+ capture_point -= visu_ctxt->capture_size;
+ capture_point -= delta_smp;
+ int64_t capture_size = visu_ctxt->capture_size;
if (capture_point < 0) {
- int32_t size = -capture_point;
+ int64_t size = -capture_point;
if (size > capture_size)
size = capture_size;