Merge "configs: apq8098_latv: propagate msm8998 changes"
diff --git a/configs/apq8098_latv/apq8098_latv.mk b/configs/apq8098_latv/apq8098_latv.mk
index cc17043..4d20981 100755
--- a/configs/apq8098_latv/apq8098_latv.mk
+++ b/configs/apq8098_latv/apq8098_latv.mk
@@ -46,7 +46,7 @@
AUDIO_FEATURE_ENABLED_FLUENCE := true
AUDIO_FEATURE_ENABLED_HDMI_EDID := true
AUDIO_FEATURE_ENABLED_HDMI_PASSTHROUGH := true
-#AUDIO_FEATURE_ENABLED_KEEP_ALIVE := true
+AUDIO_FEATURE_ENABLED_KEEP_ALIVE := true
AUDIO_FEATURE_ENABLED_DISPLAY_PORT := true
AUDIO_FEATURE_ENABLED_DS2_DOLBY_DAP := false
AUDIO_FEATURE_ENABLED_HFP := true
@@ -56,6 +56,7 @@
AUDIO_FEATURE_ENABLED_SPKR_PROTECTION := true
AUDIO_FEATURE_ENABLED_ACDB_LICENSE := true
AUDIO_FEATURE_ENABLED_DEV_ARBI := false
+AUDIO_FEATURE_ENABLED_DYNAMIC_LOG := true
MM_AUDIO_ENABLED_FTM := true
TARGET_USES_QCOM_MM_AUDIO := true
AUDIO_FEATURE_ENABLED_SOURCE_TRACKING := true
diff --git a/configs/apq8098_latv/audio_policy_configuration.xml b/configs/apq8098_latv/audio_policy_configuration.xml
index fafd322..484f96a 100755
--- a/configs/apq8098_latv/audio_policy_configuration.xml
+++ b/configs/apq8098_latv/audio_policy_configuration.xml
@@ -68,6 +68,10 @@
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
+ <mixPort name="mmap_no_irq_out" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
<mixPort name="deep_buffer" role="source"
flags="AUDIO_OUTPUT_FLAG_DEEP_BUFFER">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
@@ -194,6 +198,11 @@
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
</mixPort>
+ <mixPort name="mmap_no_irq_in" role="sink" flags="AUDIO_INPUT_FLAG_MMAP_NOIRQ">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3"/>
+ </mixPort>
</mixPorts>
<devicePorts>
@@ -305,15 +314,15 @@
<!-- route declaration, i.e. list all available sources for a given sink -->
<routes>
<route type="mix" sink="Earpiece"
- sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out"/>
<route type="mix" sink="Speaker"
- sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out"/>
<route type="mix" sink="Wired Headset"
- sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,dsd_compress_passthrough,voip_rx"/>
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,dsd_compress_passthrough,voip_rx,mmap_no_irq_out"/>
<route type="mix" sink="Wired Headphones"
- sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,dsd_compress_passthrough,voip_rx"/>
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,dsd_compress_passthrough,voip_rx,mmap_no_irq_out"/>
<route type="mix" sink="Line"
- sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,dsd_compress_passthrough,voip_rx"/>
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,dsd_compress_passthrough,voip_rx,mmap_no_irq_out"/>
<route type="mix" sink="HDMI"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,compress_passthrough"/>
<route type="mix" sink="Proxy"
@@ -321,9 +330,9 @@
<route type="mix" sink="FM"
sources="primary output"/>
<route type="mix" sink="BT SCO All"
- sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out"/>
<route type="mix" sink="USB Device Out"
- sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out"/>
<route type="mix" sink="Telephony Tx"
sources="voice_tx"/>
<route type="mix" sink="voice_rx"
@@ -334,6 +343,8 @@
sources="Built-In Mic,Built-In Back Mic"/>
<route type="mix" sink="record_24"
sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic"/>
+ <route type="mix" sink="mmap_no_irq_in"
+ sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,USB Device In"/>
<route type="mix" sink="BT A2DP Out"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
<route type="mix" sink="BT A2DP Headphones"
diff --git a/configs/msm8998/audio_policy_configuration.xml b/configs/msm8998/audio_policy_configuration.xml
index e084bba..e2ec755 100644
--- a/configs/msm8998/audio_policy_configuration.xml
+++ b/configs/msm8998/audio_policy_configuration.xml
@@ -77,6 +77,7 @@
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
+ <mixPort name="hifi_playback" role="source" />
<mixPort name="compress_passthrough" role="source"
flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
<profile name="" format="dynamic"
@@ -200,6 +201,7 @@
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3"/>
</mixPort>
+ <mixPort name="hifi_input" role="sink" />
</mixPorts>
<devicePorts>
@@ -329,7 +331,7 @@
<route type="mix" sink="BT SCO All"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out"/>
<route type="mix" sink="USB Device Out"
- sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out"/>
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback"/>
<route type="mix" sink="Telephony Tx"
sources="voice_tx"/>
<route type="mix" sink="voice_rx"
@@ -348,6 +350,7 @@
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
<route type="mix" sink="BT A2DP Speaker"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
+ <route type="mix" sink="hifi_input" sources="USB Device In" />
</routes>
</module>
diff --git a/configs/msm8998/mixer_paths_skuk.xml b/configs/msm8998/mixer_paths_skuk.xml
index e4b3785..f2e9c9a 100644
--- a/configs/msm8998/mixer_paths_skuk.xml
+++ b/configs/msm8998/mixer_paths_skuk.xml
@@ -165,6 +165,7 @@
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia15" value="0" />
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia16" value="0" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia6 Mixer SLIM_0_TX" value="0" />
@@ -204,6 +205,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2594,4 +2596,25 @@
<path name="audio-ull-playback bt-a2dp" />
<path name="audio-ull-playback" />
</path>
+
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/msm8998/mixer_paths_tasha.xml b/configs/msm8998/mixer_paths_tasha.xml
index 93656e6..4ea726b 100644
--- a/configs/msm8998/mixer_paths_tasha.xml
+++ b/configs/msm8998/mixer_paths_tasha.xml
@@ -212,6 +212,7 @@
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia15" value="0" />
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia16" value="0" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia6 Mixer SLIM_0_TX" value="0" />
@@ -389,6 +390,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2935,4 +2937,25 @@
<path name="audio-ull-playback bt-a2dp" />
<path name="audio-ull-playback" />
</path>
+
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/msm8998/mixer_paths_tavil.xml b/configs/msm8998/mixer_paths_tavil.xml
index ba37799..fc5a440 100644
--- a/configs/msm8998/mixer_paths_tavil.xml
+++ b/configs/msm8998/mixer_paths_tavil.xml
@@ -173,6 +173,7 @@
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia15" value="0" />
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia16" value="0" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia6 Mixer SLIM_0_TX" value="0" />
@@ -212,6 +213,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2801,4 +2803,24 @@
<ctl name="MultiMedia16 Mixer USB_AUDIO_TX" value="1" />
</path>
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm660/audio_platform_info.xml b/configs/sdm660/audio_platform_info.xml
index 313c59b..b5aa892 100644
--- a/configs/sdm660/audio_platform_info.xml
+++ b/configs/sdm660/audio_platform_info.xml
@@ -76,6 +76,7 @@
</config_params>
<acdb_ids>
<device name="SND_DEVICE_OUT_SPEAKER" acdb_id="15"/>
+ <device name="SND_DEVICE_OUT_SPEAKER_REVERSE" acdb_id="15"/>
<device name="SND_DEVICE_OUT_SPEAKER_PROTECTED" acdb_id="124"/>
<device name="SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED" acdb_id="101"/>
<device name="SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT" acdb_id="124"/>
diff --git a/configs/sdm660/audio_policy_configuration.xml b/configs/sdm660/audio_policy_configuration.xml
index 9a67a32..418cf42 100644
--- a/configs/sdm660/audio_policy_configuration.xml
+++ b/configs/sdm660/audio_policy_configuration.xml
@@ -73,6 +73,7 @@
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
+ <mixPort name="hifi_playback" role="source" />
<mixPort name="compress_passthrough" role="source"
flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
<profile name="" format="dynamic"
@@ -191,6 +192,7 @@
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
</mixPort>
+ <mixPort name="hifi_input" role="sink" />
</mixPorts>
<devicePorts>
@@ -320,7 +322,7 @@
<route type="mix" sink="BT SCO All"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
<route type="mix" sink="USB Device Out"
- sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,hifi_playback"/>
<route type="mix" sink="Telephony Tx"
sources="voice_tx"/>
<route type="mix" sink="voice_rx"
@@ -337,6 +339,7 @@
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
<route type="mix" sink="BT A2DP Speaker"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
+ <route type="mix" sink="hifi_input" sources="USB Device In" />
</routes>
</module>
diff --git a/configs/sdm660/mixer_paths.xml b/configs/sdm660/mixer_paths.xml
index 459ffa1..8cca459 100644
--- a/configs/sdm660/mixer_paths.xml
+++ b/configs/sdm660/mixer_paths.xml
@@ -147,6 +147,7 @@
<ctl name="USB_AUDIO_RX SampleRate" value="KHZ_48" />
<ctl name="USB_AUDIO_RX Channels" value="Two" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="USB_AUDIO_TX Format" value="S16_LE" />
@@ -175,6 +176,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2312,4 +2314,25 @@
<path name="mmap-record usb-headset-mic">
<ctl name="MultiMedia16 Mixer USB_AUDIO_TX" value="1" />
</path>
+
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm660/mixer_paths_mtp.xml b/configs/sdm660/mixer_paths_mtp.xml
index bba3cb9..4f61224 100644
--- a/configs/sdm660/mixer_paths_mtp.xml
+++ b/configs/sdm660/mixer_paths_mtp.xml
@@ -146,6 +146,7 @@
<ctl name="USB_AUDIO_RX SampleRate" value="KHZ_48" />
<ctl name="USB_AUDIO_RX Channels" value="Two" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="USB_AUDIO_TX Format" value="S16_LE" />
@@ -174,6 +175,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2373,4 +2375,25 @@
<path name="audio-ull-playback bt-a2dp" />
<path name="audio-ull-playback" />
</path>
+
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm660/mixer_paths_skus.xml b/configs/sdm660/mixer_paths_skus.xml
index 8ecc1a3..bdd0d61 100644
--- a/configs/sdm660/mixer_paths_skus.xml
+++ b/configs/sdm660/mixer_paths_skus.xml
@@ -210,6 +210,7 @@
<ctl name="USB_AUDIO_RX SampleRate" value="KHZ_48" />
<ctl name="USB_AUDIO_RX Channels" value="Two" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="USB_AUDIO_TX Format" value="S16_LE" />
@@ -391,6 +392,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2849,4 +2851,25 @@
<path name="audio-ull-playback bt-a2dp" />
<path name="audio-ull-playback" />
</path>
+
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm660/mixer_paths_skush.xml b/configs/sdm660/mixer_paths_skush.xml
index cf0838f..aa81e7b 100644
--- a/configs/sdm660/mixer_paths_skush.xml
+++ b/configs/sdm660/mixer_paths_skush.xml
@@ -141,6 +141,7 @@
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia15" value="0" />
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia16" value="0" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia6 Mixer INT3_MI2S_TX" value="0" />
@@ -166,6 +167,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2423,4 +2425,25 @@
<path name="audio-ull-playback bt-a2dp" />
<path name="audio-ull-playback" />
</path>
+
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm660/mixer_paths_wcd9326.xml b/configs/sdm660/mixer_paths_wcd9326.xml
index 0745180..9e6623d 100644
--- a/configs/sdm660/mixer_paths_wcd9326.xml
+++ b/configs/sdm660/mixer_paths_wcd9326.xml
@@ -209,6 +209,7 @@
<ctl name="USB_AUDIO_RX SampleRate" value="KHZ_48" />
<ctl name="USB_AUDIO_RX Channels" value="Two" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="USB_AUDIO_TX Format" value="S16_LE" />
@@ -390,6 +391,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2794,4 +2796,25 @@
<path name="audio-ull-playback bt-a2dp" />
<path name="audio-ull-playback" />
</path>
+
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm660/mixer_paths_wcd9335.xml b/configs/sdm660/mixer_paths_wcd9335.xml
index 8cc6f65..d4c098f 100644
--- a/configs/sdm660/mixer_paths_wcd9335.xml
+++ b/configs/sdm660/mixer_paths_wcd9335.xml
@@ -209,6 +209,7 @@
<ctl name="USB_AUDIO_RX SampleRate" value="KHZ_48" />
<ctl name="USB_AUDIO_RX Channels" value="Two" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="USB_AUDIO_TX Format" value="S16_LE" />
@@ -390,6 +391,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2871,4 +2873,25 @@
<path name="mmap-record usb-headset-mic">
<ctl name="MultiMedia16 Mixer USB_AUDIO_TX" value="1" />
</path>
+
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm660/mixer_paths_wcd9340.xml b/configs/sdm660/mixer_paths_wcd9340.xml
index 213f5c3..6c6f2cf 100644
--- a/configs/sdm660/mixer_paths_wcd9340.xml
+++ b/configs/sdm660/mixer_paths_wcd9340.xml
@@ -170,6 +170,7 @@
<ctl name="USB_AUDIO_RX SampleRate" value="KHZ_48" />
<ctl name="USB_AUDIO_RX Channels" value="Two" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="USB_AUDIO_TX Format" value="S16_LE" />
@@ -213,6 +214,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2619,4 +2621,24 @@
<ctl name="MultiMedia16 Mixer USB_AUDIO_TX" value="1" />
</path>
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm660/sdm660.mk b/configs/sdm660/sdm660.mk
index 8d57a46..6834479 100644
--- a/configs/sdm660/sdm660.mk
+++ b/configs/sdm660/sdm660.mk
@@ -57,6 +57,7 @@
AUDIO_FEATURE_ENABLED_SPKR_PROTECTION := true
AUDIO_FEATURE_ENABLED_ACDB_LICENSE := true
AUDIO_FEATURE_ENABLED_DEV_ARBI := false
+AUDIO_FEATURE_ENABLED_DYNAMIC_LOG := true
MM_AUDIO_ENABLED_FTM := true
TARGET_USES_QCOM_MM_AUDIO := true
AUDIO_FEATURE_ENABLED_SOURCE_TRACKING := true
diff --git a/configs/sdm670/audio_platform_info.xml b/configs/sdm670/audio_platform_info.xml
index 57cddc2..71a8bf6 100644
--- a/configs/sdm670/audio_platform_info.xml
+++ b/configs/sdm670/audio_platform_info.xml
@@ -41,6 +41,24 @@
<device name="SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2" acdb_id="10"/>
<device name="SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET" acdb_id="45"/>
</acdb_ids>
+ <module_ids>
+ <aec>
+ <device name="SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS" module_id="0x10F17" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+ <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE" module_id="0x10F18" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+ <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+ <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+ <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+ <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+ </aec>
+ <ns>
+ <device name="SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS" module_id="0x10F17" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+ <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE" module_id="0x10F18" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+ <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+ <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+ <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+ <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+ </ns>
+ </module_ids>
<bit_width_configs>
<device name="SND_DEVICE_OUT_SPEAKER" bit_width="24"/>
</bit_width_configs>
diff --git a/configs/sdm670/audio_policy_configuration.xml b/configs/sdm670/audio_policy_configuration.xml
index 09a4bb9..8e51ba5 100644
--- a/configs/sdm670/audio_policy_configuration.xml
+++ b/configs/sdm670/audio_policy_configuration.xml
@@ -73,6 +73,7 @@
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
+ <mixPort name="hifi_playback" role="source" />
<mixPort name="compress_passthrough" role="source"
flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
<profile name="" format="dynamic"
@@ -191,6 +192,7 @@
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
</mixPort>
+ <mixPort name="hifi_input" role="sink" />
</mixPorts>
<devicePorts>
@@ -320,7 +322,7 @@
<route type="mix" sink="BT SCO All"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
<route type="mix" sink="USB Device Out"
- sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,hifi_playback"/>
<route type="mix" sink="Telephony Tx"
sources="voice_tx"/>
<route type="mix" sink="voice_rx"
@@ -337,6 +339,7 @@
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
<route type="mix" sink="BT A2DP Speaker"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
+ <route type="mix" sink="hifi_input" sources="USB Device In" />
</routes>
</module>
diff --git a/configs/sdm670/mixer_paths.xml b/configs/sdm670/mixer_paths.xml
index 1b07f80..5f81e65 100644
--- a/configs/sdm670/mixer_paths.xml
+++ b/configs/sdm670/mixer_paths.xml
@@ -146,6 +146,7 @@
<ctl name="USB_AUDIO_RX SampleRate" value="KHZ_48" />
<ctl name="USB_AUDIO_RX Channels" value="Two" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="USB_AUDIO_TX Format" value="S16_LE" />
@@ -174,6 +175,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2256,4 +2258,25 @@
<path name="audio-ull-playback bt-a2dp" />
<path name="audio-ull-playback" />
</path>
+
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm670/mixer_paths_mtp.xml b/configs/sdm670/mixer_paths_mtp.xml
index b08059c..9b462a4 100644
--- a/configs/sdm670/mixer_paths_mtp.xml
+++ b/configs/sdm670/mixer_paths_mtp.xml
@@ -132,6 +132,7 @@
<ctl name="USB_AUDIO_RX SampleRate" value="KHZ_48" />
<ctl name="USB_AUDIO_RX Channels" value="Two" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="USB_AUDIO_TX Format" value="S16_LE" />
@@ -159,6 +160,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2119,4 +2121,25 @@
<path name="audio-ull-playback bt-a2dp" />
<path name="audio-ull-playback" />
</path>
+
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm670/mixer_paths_tasha.xml b/configs/sdm670/mixer_paths_tasha.xml
index be2f56b..cbb74a5 100644
--- a/configs/sdm670/mixer_paths_tasha.xml
+++ b/configs/sdm670/mixer_paths_tasha.xml
@@ -195,6 +195,7 @@
<ctl name="USB_AUDIO_RX SampleRate" value="KHZ_48" />
<ctl name="USB_AUDIO_RX Channels" value="Two" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="USB_AUDIO_TX Format" value="S16_LE" />
@@ -375,6 +376,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2751,4 +2753,24 @@
<path name="audio-ull-playback" />
</path>
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm670/mixer_paths_tashalite.xml b/configs/sdm670/mixer_paths_tashalite.xml
index 65dec6a..e4ea674 100644
--- a/configs/sdm670/mixer_paths_tashalite.xml
+++ b/configs/sdm670/mixer_paths_tashalite.xml
@@ -195,6 +195,7 @@
<ctl name="USB_AUDIO_RX SampleRate" value="KHZ_48" />
<ctl name="USB_AUDIO_RX Channels" value="Two" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="USB_AUDIO_TX Format" value="S16_LE" />
@@ -375,6 +376,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2728,4 +2730,25 @@
<path name="audio-ull-playback bt-a2dp" />
<path name="audio-ull-playback" />
</path>
+
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm670/mixer_paths_tavil.xml b/configs/sdm670/mixer_paths_tavil.xml
index 8a8783b..f822423 100644
--- a/configs/sdm670/mixer_paths_tavil.xml
+++ b/configs/sdm670/mixer_paths_tavil.xml
@@ -157,6 +157,7 @@
<ctl name="USB_AUDIO_RX SampleRate" value="KHZ_48" />
<ctl name="USB_AUDIO_RX Channels" value="Two" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="USB_AUDIO_TX Format" value="S16_LE" />
@@ -199,6 +200,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2386,4 +2388,25 @@
<path name="audio-ull-playback bt-a2dp" />
<path name="audio-ull-playback" />
</path>
+
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm670/sdm670.mk b/configs/sdm670/sdm670.mk
index 7efcc2f..d220650 100644
--- a/configs/sdm670/sdm670.mk
+++ b/configs/sdm670/sdm670.mk
@@ -7,6 +7,7 @@
USE_CUSTOM_AUDIO_POLICY := 1
AUDIO_FEATURE_ENABLED_COMPRESS_CAPTURE := false
AUDIO_FEATURE_ENABLED_COMPRESS_VOIP := true
+AUDIO_FEATURE_ENABLED_DYNAMIC_ECNS := false
AUDIO_FEATURE_ENABLED_EXTN_FORMATS := true
AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER := true
AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER := true
@@ -23,6 +24,7 @@
AUDIO_FEATURE_ENABLED_PROXY_DEVICE := true
AUDIO_FEATURE_ENABLED_SSR := true
AUDIO_FEATURE_ENABLED_DTS_EAGLE := false
+AUDIO_FEATURE_ENABLED_DYNAMIC_LOG := true
BOARD_USES_SRS_TRUEMEDIA := false
DTS_CODEC_M_ := false
MM_AUDIO_ENABLED_SAFX := true
@@ -98,7 +100,7 @@
hardware/qcom/audio/configs/sdm670/sound_trigger_mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9335.xml \
hardware/qcom/audio/configs/sdm670/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
hardware/qcom/audio/configs/sdm670/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
- hardware/qcom/audio/configs/sdm670/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
+ hardware/qcom/audio/configs/sdm670/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml
#XML Audio configuration files
ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
diff --git a/configs/sdm845/audio_platform_info.xml b/configs/sdm845/audio_platform_info.xml
index d53fce8..19ea80c 100644
--- a/configs/sdm845/audio_platform_info.xml
+++ b/configs/sdm845/audio_platform_info.xml
@@ -27,6 +27,7 @@
<audio_platform_info>
<acdb_ids>
<device name="SND_DEVICE_OUT_SPEAKER" acdb_id="15"/>
+ <device name="SND_DEVICE_OUT_SPEAKER_REVERSE" acdb_id="15"/>
<device name="SND_DEVICE_OUT_SPEAKER_PROTECTED" acdb_id="124"/>
<device name="SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE" acdb_id="131"/>
<device name="SND_DEVICE_IN_VOICE_REC_TMIC" acdb_id="131"/>
@@ -35,8 +36,33 @@
<device name="SND_DEVICE_OUT_VOICE_SPEAKER_2_PROTECTED_VBAT" acdb_id="150"/>
<device name="SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_1" acdb_id="151"/>
<device name="SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_2" acdb_id="152"/>
- <device name="SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC" acdb_id="133"/>
+ <device name="SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC" acdb_id="133"/>
+ <device name="SND_DEVICE_IN_UNPROCESSED_MIC" acdb_id="143"/>
+ <device name="SND_DEVICE_IN_UNPROCESSED_STEREO_MIC" acdb_id="144"/>
+ <device name="SND_DEVICE_IN_UNPROCESSED_THREE_MIC" acdb_id="145"/>
+ <device name="SND_DEVICE_IN_UNPROCESSED_QUAD_MIC" acdb_id="146"/>
+ <device name="SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC" acdb_id="147"/>
</acdb_ids>
+
+ <module_ids>
+ <aec>
+ <device name="SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS" module_id="0x10F17" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+ <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE" module_id="0x10F18" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+ <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+ <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+ <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+ <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+ </aec>
+ <ns>
+ <device name="SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS" module_id="0x10F17" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+ <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE" module_id="0x10F18" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+ <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+ <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+ <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F0A" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+ <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F09" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+ </ns>
+ </module_ids>
+
<bit_width_configs>
<device name="SND_DEVICE_OUT_SPEAKER" bit_width="24"/>
</bit_width_configs>
diff --git a/configs/sdm845/audio_policy_configuration.xml b/configs/sdm845/audio_policy_configuration.xml
index d775641..a19151c 100644
--- a/configs/sdm845/audio_policy_configuration.xml
+++ b/configs/sdm845/audio_policy_configuration.xml
@@ -77,6 +77,7 @@
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
+ <mixPort name="hifi_playback" role="source" />
<mixPort name="compress_passthrough" role="source"
flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
<profile name="" format="dynamic"
@@ -200,6 +201,7 @@
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3"/>
</mixPort>
+ <mixPort name="hifi_input" role="sink" />
</mixPorts>
<devicePorts>
@@ -329,7 +331,7 @@
<route type="mix" sink="BT SCO All"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
<route type="mix" sink="USB Device Out"
- sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out"/>
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback"/>
<route type="mix" sink="Telephony Tx"
sources="voice_tx"/>
<route type="mix" sink="voice_rx"
@@ -348,6 +350,7 @@
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
<route type="mix" sink="BT A2DP Speaker"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
+ <route type="mix" sink="hifi_input" sources="USB Device In" />
</routes>
</module>
diff --git a/configs/sdm845/mixer_paths_tavil.xml b/configs/sdm845/mixer_paths_tavil.xml
index b073fb2..8a6360b 100644
--- a/configs/sdm845/mixer_paths_tavil.xml
+++ b/configs/sdm845/mixer_paths_tavil.xml
@@ -154,6 +154,7 @@
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia15" value="0" />
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia16" value="0" />
<ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
<ctl name="MultiMedia10 Mixer USB_AUDIO_TX" value="0" />
@@ -193,6 +194,7 @@
<ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
<!-- usb headset -->
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia1" value="0" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="0" />
@@ -2431,6 +2433,22 @@
<path name="unprocessed-handset-mic" />
</path>
+ <path name="unprocessed-stereo-mic">
+ <path name="voice-rec-dmic-ef" />
+ </path>
+
+ <path name="unprocessed-three-mic">
+ <path name="three-mic" />
+ </path>
+
+ <path name="unprocessed-quad-mic">
+ <path name="quad-mic" />
+ </path>
+
+ <path name="unprocessed-headset-mic">
+ <path name="headset-mic" />
+ </path>
+
<!-- USB TTY start -->
<!-- full: both end tty -->
@@ -2658,4 +2676,24 @@
<ctl name="MultiMedia16 Mixer USB_AUDIO_TX" value="1" />
</path>
+ <path name="hifi-playback display-port">
+ <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback afe-proxy">
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headset">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-playback usb-headphones">
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="1" />
+ </path>
+
+ <path name="hifi-record usb-headset-mic">
+ <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="1" />
+ </path>
+
</mixer>
diff --git a/configs/sdm845/sdm845.mk b/configs/sdm845/sdm845.mk
index 7d3a51f..e6f2b3d 100644
--- a/configs/sdm845/sdm845.mk
+++ b/configs/sdm845/sdm845.mk
@@ -7,6 +7,7 @@
USE_CUSTOM_AUDIO_POLICY := 1
AUDIO_FEATURE_ENABLED_COMPRESS_CAPTURE := false
AUDIO_FEATURE_ENABLED_COMPRESS_VOIP := false
+AUDIO_FEATURE_ENABLED_DYNAMIC_ECNS := false
AUDIO_FEATURE_ENABLED_EXTN_FORMATS := true
AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER := true
AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER := true
@@ -53,6 +54,7 @@
AUDIO_FEATURE_ENABLED_SPKR_PROTECTION := true
AUDIO_FEATURE_ENABLED_ACDB_LICENSE := false
AUDIO_FEATURE_ENABLED_DEV_ARBI := false
+AUDIO_FEATURE_ENABLED_DYNAMIC_LOG := true
MM_AUDIO_ENABLED_FTM := true
TARGET_USES_QCOM_MM_AUDIO := true
AUDIO_FEATURE_ENABLED_SOURCE_TRACKING := true
@@ -189,7 +191,7 @@
#split a2dp DSP supported encoder list
PRODUCT_PROPERTY_OVERRIDES += \
-persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxhd-aac
+persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxtws-aptxhd-aac
#enable software decoders for ALAC and APE
PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/configs/sdm845/sound_trigger_platform_info.xml b/configs/sdm845/sound_trigger_platform_info.xml
index b9e36f5..e1f21a7 100644
--- a/configs/sdm845/sound_trigger_platform_info.xml
+++ b/configs/sdm845/sound_trigger_platform_info.xml
@@ -61,7 +61,7 @@
<param library="libsmwrapper.so" />
<param max_cpe_phrases="6" />
<param max_cpe_users="3" />
- <param max_ape_phrases="10" />
+ <param max_ape_phrases="20" />
<param max_ape_users="10" />
<!-- Profile specific data which the algorithm can support -->
<param sample_rate="16000" />
diff --git a/hal/Android.mk b/hal/Android.mk
index d2ef726..cbf766a 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -368,6 +368,10 @@
LOCAL_SRC_FILES += audio_extn/ip_hdlr_intf.c
endif
+ifeq ($(strip $($AUDIO_FEATURE_ENABLED_DYNAMIC_ECNS)),true)
+ LOCAL_CFLAGS += -DDYNAMIC_ECNS_ENABLED
+endif
+
LOCAL_CFLAGS += -Wall -Werror
LOCAL_COPY_HEADERS_TO := mm-audio
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index 4393418..2c0c53b 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -100,6 +100,7 @@
ENC_CODEC_TYPE_SBC = 520093696u, // 0x1F000000UL
ENC_CODEC_TYPE_APTX = 536870912u, // 0x20000000UL
ENC_CODEC_TYPE_APTX_HD = 553648128u, // 0x21000000UL
+ ENC_CODEC_TYPE_APTX_DUAL_MONO = 570425344u, // 0x22000000UL
ENC_CODEC_TYPE_CELT = 603979776u, // 0x24000000UL
}enc_codec_t;
@@ -147,6 +148,7 @@
int a2dp_total_active_session_request;
bool is_a2dp_offload_supported;
bool is_handoff_in_progress;
+ bool is_aptx_dual_mono_supported;
};
struct a2dp_data a2dp;
@@ -169,7 +171,7 @@
uint16_t aac_fmt_flag;
uint16_t channel_cfg;
uint32_t sample_rate;
-} ;
+} __packed;
/* SBC encoder configuration structure. */
typedef struct sbc_enc_cfg_t sbc_enc_cfg_t;
@@ -189,14 +191,14 @@
uint32_t alloc_method;
uint32_t bit_rate;
uint32_t sample_rate;
-};
+} __packed;
/* supported num_channels are Mono/Stereo
* supported channel_mapping for mono is CHANNEL_C
* supported channel mapping for stereo is CHANNEL_L and CHANNEL_R
* custom size and reserved are not used(for future enhancement)
- */
+ */
struct custom_enc_cfg_t
{
uint32_t enc_format;
@@ -205,7 +207,7 @@
uint16_t reserved;
uint8_t channel_mapping[8];
uint32_t custom_size;
-};
+} __packed;
struct celt_specific_enc_cfg_t
{
@@ -214,13 +216,31 @@
uint16_t complexity;
uint16_t prediction_mode;
uint16_t vbr_flag;
-};
+} __packed;
struct celt_enc_cfg_t
{
struct custom_enc_cfg_t custom_cfg;
struct celt_specific_enc_cfg_t celt_cfg;
-};
+} __packed;
+
+/* sync_mode introduced with APTX V2 libraries
+ * sync mode: 0x0 = stereo sync mode
+ * 0x01 = dual mono sync mode
+ * 0x02 = dual mono with no sync on either L or R codewords
+ */
+struct aptx_v2_enc_cfg_ext_t
+{
+ uint32_t sync_mode;
+} __packed;
+
+/* APTX struct for combining custom enc and V2 fields */
+struct aptx_enc_cfg_t
+{
+ struct custom_enc_cfg_t custom_cfg;
+ struct aptx_v2_enc_cfg_ext_t aptx_v2_cfg;
+} __packed;
+
/* In LE BT source code uses system/audio.h for below
* structure definition. To avoid multiple definition
* compilation error for audiohal in LE , masking structure
@@ -252,8 +272,19 @@
uint16_t sampling_rate;
uint8_t channels;
uint32_t bitrate;
-} audio_aptx_encoder_config;
+} audio_aptx_default_config;
+typedef struct {
+ uint16_t sampling_rate;
+ uint8_t channels;
+ uint32_t bitrate;
+ uint32_t sync_mode;
+} audio_aptx_dual_mono_config;
+
+typedef union {
+ audio_aptx_default_config *default_cfg;
+ audio_aptx_dual_mono_config *dual_mono_cfg;
+} audio_aptx_encoder_config;
/* Information about BT AAC encoder configuration
* This data is used between audio HAL module and
@@ -299,6 +330,10 @@
ALOGD("%s: aptx offload supported\n",__func__);
a2dp.is_a2dp_offload_supported = true;
break;
+ } else if (strcmp(tok, "aptxtws") == 0) {
+ ALOGD("%s: aptx dual mono offload supported\n",__func__);
+ a2dp.is_a2dp_offload_supported = true;
+ break;
} else if (strcmp(tok, "aptxhd") == 0) {
ALOGD("%s: aptx HD offload supported\n",__func__);
a2dp.is_a2dp_offload_supported = true;
@@ -489,7 +524,7 @@
bool configure_aptx_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
{
struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
- struct custom_enc_cfg_t aptx_dsp_cfg;
+ struct aptx_enc_cfg_t aptx_dsp_cfg;
bool is_configured = false;
int ret = 0;
@@ -502,22 +537,31 @@
is_configured = false;
goto fail;
}
- memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_t));
- aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX;
- aptx_dsp_cfg.sample_rate = aptx_bt_cfg->sampling_rate;
- aptx_dsp_cfg.num_channels = aptx_bt_cfg->channels;
- switch(aptx_dsp_cfg.num_channels) {
+
+ memset(&aptx_dsp_cfg, 0x0, sizeof(struct aptx_enc_cfg_t));
+ aptx_dsp_cfg.custom_cfg.enc_format = ENC_MEDIA_FMT_APTX;
+
+ if (!a2dp.is_aptx_dual_mono_supported) {
+ aptx_dsp_cfg.custom_cfg.sample_rate = aptx_bt_cfg->default_cfg->sampling_rate;
+ aptx_dsp_cfg.custom_cfg.num_channels = aptx_bt_cfg->default_cfg->channels;
+ } else {
+ aptx_dsp_cfg.custom_cfg.sample_rate = aptx_bt_cfg->dual_mono_cfg->sampling_rate;
+ aptx_dsp_cfg.custom_cfg.num_channels = aptx_bt_cfg->dual_mono_cfg->channels;
+ aptx_dsp_cfg.aptx_v2_cfg.sync_mode = aptx_bt_cfg->dual_mono_cfg->sync_mode;
+ }
+
+ switch(aptx_dsp_cfg.custom_cfg.num_channels) {
case 1:
- aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_C;
+ aptx_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_C;
break;
case 2:
default:
- aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_L;
- aptx_dsp_cfg.channel_mapping[1] = PCM_CHANNEL_R;
+ aptx_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
+ aptx_dsp_cfg.custom_cfg.channel_mapping[1] = PCM_CHANNEL_R;
break;
}
ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
- sizeof(struct custom_enc_cfg_t));
+ sizeof(struct aptx_enc_cfg_t));
if (ret != 0) {
ALOGE("%s: Failed to set APTX encoder config", __func__);
is_configured = false;
@@ -539,16 +583,26 @@
}
is_configured = true;
a2dp.bt_encoder_format = ENC_CODEC_TYPE_APTX;
- a2dp.enc_sampling_rate = aptx_bt_cfg->sampling_rate;
- ALOGV("Successfully updated APTX enc format with samplingrate: %d channels:%d",
- aptx_dsp_cfg.sample_rate, aptx_dsp_cfg.num_channels);
+ if (!a2dp.is_aptx_dual_mono_supported) {
+ a2dp.enc_sampling_rate = aptx_bt_cfg->default_cfg->sampling_rate;
+ ALOGV("Successfully updated APTX enc format with samplingrate: %d \
+ channels:%d", aptx_dsp_cfg.custom_cfg.sample_rate,
+ aptx_dsp_cfg.custom_cfg.num_channels);
+ } else {
+ a2dp.enc_sampling_rate = aptx_bt_cfg->dual_mono_cfg->sampling_rate;
+ ALOGV("Successfully updated APTX dual mono enc format with \
+ samplingrate: %d channels:%d syncmode %d",
+ aptx_dsp_cfg.custom_cfg.sample_rate,
+ aptx_dsp_cfg.custom_cfg.num_channels,
+ aptx_dsp_cfg.aptx_v2_cfg.sync_mode);
+ }
fail:
return is_configured;
}
/* API to configure APTX HD DSP encoder
*/
-bool configure_aptx_hd_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
+bool configure_aptx_hd_enc_format(audio_aptx_default_config *aptx_bt_cfg)
{
struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
struct custom_enc_cfg_t aptx_dsp_cfg;
@@ -743,6 +797,7 @@
uint8_t multi_cast = 0, num_dev = 1;
enc_codec_t codec_type = ENC_CODEC_TYPE_INVALID;
bool is_configured = false;
+ audio_aptx_encoder_config aptx_encoder_cfg;
if (!a2dp.audio_get_codec_config) {
ALOGE(" a2dp handle is not identified, ignoring a2dp encoder config");
@@ -756,17 +811,26 @@
case ENC_CODEC_TYPE_SBC:
ALOGD(" Received SBC encoder supported BT device");
is_configured =
- configure_sbc_enc_format((audio_sbc_encoder_config *)codec_info);
+ configure_sbc_enc_format((audio_sbc_encoder_config *)codec_info);
break;
case ENC_CODEC_TYPE_APTX:
ALOGD(" Received APTX encoder supported BT device");
+ a2dp.is_aptx_dual_mono_supported = false;
+ aptx_encoder_cfg.default_cfg = (audio_aptx_default_config *)codec_info;
is_configured =
- configure_aptx_enc_format((audio_aptx_encoder_config *)codec_info);
+ configure_aptx_enc_format(&aptx_encoder_cfg);
break;
case ENC_CODEC_TYPE_APTX_HD:
ALOGD(" Received APTX HD encoder supported BT device");
is_configured =
- configure_aptx_hd_enc_format((audio_aptx_encoder_config *)codec_info);
+ configure_aptx_hd_enc_format((audio_aptx_default_config *)codec_info);
+ break;
+ case ENC_CODEC_TYPE_APTX_DUAL_MONO:
+ ALOGD(" Received APTX dual mono encoder supported BT device");
+ a2dp.is_aptx_dual_mono_supported = true;
+ aptx_encoder_cfg.dual_mono_cfg = (audio_aptx_dual_mono_config *)codec_info;
+ is_configured =
+ configure_aptx_enc_format(&aptx_encoder_cfg);
break;
case ENC_CODEC_TYPE_AAC:
ALOGD(" Received AAC encoder supported BT device");
@@ -1044,6 +1108,7 @@
a2dp.enc_sampling_rate = 48000;
a2dp.is_a2dp_offload_supported = false;
a2dp.is_handoff_in_progress = false;
+ a2dp.is_aptx_dual_mono_supported = false;
reset_a2dp_enc_config_params();
update_offload_codec_capabilities();
}
diff --git a/hal/audio_extn/audio_defs.h b/hal/audio_extn/audio_defs.h
index 4e5f4d8..7abc89b 100644
--- a/hal/audio_extn/audio_defs.h
+++ b/hal/audio_extn/audio_defs.h
@@ -240,11 +240,12 @@
uint16_t num_output_channels;
uint16_t num_input_channels;
uint8_t has_output_channel_map;
- uint32_t output_channel_map[AUDIO_CHANNEL_COUNT_MAX];
+ uint16_t output_channel_map[AUDIO_CHANNEL_COUNT_MAX];
uint8_t has_input_channel_map;
- uint32_t input_channel_map[AUDIO_CHANNEL_COUNT_MAX];
+ uint16_t input_channel_map[AUDIO_CHANNEL_COUNT_MAX];
uint8_t has_mixer_coeffs;
- float mixer_coeffs[AUDIO_CHANNEL_COUNT_MAX][AUDIO_CHANNEL_COUNT_MAX];
+ /* member for coefficient gains in Q14 format */
+ uint32_t mixer_coeffs[AUDIO_CHANNEL_COUNT_MAX][AUDIO_CHANNEL_COUNT_MAX];
} mix_matrix_params_t;
typedef union {
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index c62226a..072d202 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -51,7 +51,7 @@
#endif
#ifndef INCALL_MUSIC_ENABLED
-#define AUDIO_OUTPUT_FLAG_INCALL_MUSIC 0x8000
+#define AUDIO_OUTPUT_FLAG_INCALL_MUSIC 0x80000000 //0x8000
#endif
#ifndef AUDIO_DEVICE_OUT_FM_TX
@@ -86,7 +86,7 @@
#endif
#ifndef AUDIO_FORMAT_AAC_LATM
-#define AUDIO_FORMAT_AAC_LATM 0x23000000UL
+#define AUDIO_FORMAT_AAC_LATM 0x80000000UL
#define AUDIO_FORMAT_AAC_LATM_LC (AUDIO_FORMAT_AAC_LATM |\
AUDIO_FORMAT_AAC_SUB_LC)
#define AUDIO_FORMAT_AAC_LATM_HE_V1 (AUDIO_FORMAT_AAC_LATM |\
@@ -116,7 +116,7 @@
#endif
#ifndef AUDIO_OUTPUT_FLAG_INTERACTIVE
-#define AUDIO_OUTPUT_FLAG_INTERACTIVE 0x80000000
+#define AUDIO_OUTPUT_FLAG_INTERACTIVE 0x4000000
#endif
#ifndef COMPRESS_METADATA_NEEDED
@@ -213,6 +213,9 @@
#define audio_extn_usb_enable_sidetone(device, enable) (0)
#define audio_extn_usb_set_sidetone_gain(parms, value, len) (0)
#define audio_extn_usb_is_capture_supported() (0)
+#define audio_extn_usb_get_max_channels(p) (0)
+#define audio_extn_usb_get_max_bit_width(p) (0)
+#define audio_extn_usb_get_sup_sample_rates(t, s, l) (0)
#else
void audio_extn_usb_init(void *adev);
void audio_extn_usb_deinit();
@@ -226,6 +229,9 @@
int audio_extn_usb_set_sidetone_gain(struct str_parms *parms,
char *value, int len);
bool audio_extn_usb_is_capture_supported();
+int audio_extn_usb_get_max_channels(bool playback);
+int audio_extn_usb_get_max_bit_width(bool playback);
+int audio_extn_usb_get_sup_sample_rates(int type, uint32_t *sr, uint32_t l);
#endif
#ifndef SPLIT_A2DP_ENABLED
diff --git a/hal/audio_extn/keep_alive.c b/hal/audio_extn/keep_alive.c
index 3e9a91c..dad4946 100644
--- a/hal/audio_extn/keep_alive.c
+++ b/hal/audio_extn/keep_alive.c
@@ -124,7 +124,7 @@
if (cmd == NULL) {
ALOGE("%s: cmd is NULL", __func__);
- return -ENOMEM;
+ return;
}
cmd->req = r;
diff --git a/hal/audio_extn/qaf.c b/hal/audio_extn/qaf.c
index ca83b1d..20d0ae4 100644
--- a/hal/audio_extn/qaf.c
+++ b/hal/audio_extn/qaf.c
@@ -129,6 +129,8 @@
FILE *fp_output_writer_hdmi = NULL;
#endif
+void set_hdmi_configuration_to_module();
+
struct qaf_adsp_hdlr_config_state {
struct audio_adsp_event event_params;
/* For holding client audio_adsp_event payload */
@@ -386,7 +388,7 @@
static int get_media_fmt_array_index_for_output_id(
struct qaf_module* qaf_mod,
- int output_id)
+ uint32_t output_id)
{
int i;
for (i = 0; i < MAX_QAF_MODULE_OUT; i++) {
@@ -496,7 +498,7 @@
{
DEBUG_MSG();
- int ret = 0, k;
+ int ret = 0;
struct stream_out *out = p_qaf->passthrough_in;
if (!out) return -EINVAL;
@@ -592,7 +594,7 @@
static int audio_extn_qaf_stream_stop(struct stream_out *out)
{
int ret = 0;
- DEBUG_MSG("Output Stream 0x%x", out);
+ DEBUG_MSG("Output Stream 0x%p", out);
if (!check_stream_state(out, RUN)) return ret;
@@ -837,7 +839,7 @@
return fragment_size;
}
-static uint32_t qaf_get_pcm_offload_input_buffer_size(info)
+static uint32_t qaf_get_pcm_offload_input_buffer_size(audio_offload_info_t* info)
{
return qaf_get_pcm_offload_buffer_size(info, MS12_PCM_IN_FRAGMENT_SIZE);
}
@@ -1132,21 +1134,22 @@
DEBUG_MSG("Output Stream %p", out);
lock_output_stream(out);
- //If QAF passthrough is active then block the flush on module input streams.
- if (p_qaf->passthrough_out) {
- pthread_mutex_lock(&p_qaf->lock);
- //If flush is received for the QAF passthrough stream then call the primary HAL api.
- if (p_qaf->passthrough_in == out) {
- status = p_qaf->passthrough_out->stream.flush(
- (struct audio_stream_out *)p_qaf->passthrough_out);
- out->offload_state = OFFLOAD_STATE_IDLE;
+ if (!out->standby) {
+ //If QAF passthrough is active then block the flush on module input streams.
+ if (p_qaf->passthrough_out) {
+ pthread_mutex_lock(&p_qaf->lock);
+ //If flush is received for the QAF passthrough stream then call the primary HAL api.
+ if (p_qaf->passthrough_in == out) {
+ status = p_qaf->passthrough_out->stream.flush(
+ (struct audio_stream_out *)p_qaf->passthrough_out);
+ out->offload_state = OFFLOAD_STATE_IDLE;
+ }
+ pthread_mutex_unlock(&p_qaf->lock);
+ } else {
+ //Flush the module input stream.
+ status = audio_extn_qaf_stream_flush(out);
}
- pthread_mutex_unlock(&p_qaf->lock);
- } else {
- //Flush the module input stream.
- status = audio_extn_qaf_stream_flush(out);
}
-
unlock_output_stream(out);
DEBUG_MSG("Exit");
return status;
@@ -1227,7 +1230,7 @@
if (media_fmt == NULL || out == NULL) {
return;
}
- struct audio_out_channel_map_param chmap = {0};
+ struct audio_out_channel_map_param chmap = {0,{0}};
int i = 0;
chmap.channels = media_fmt->channels;
for (i = 0; i < chmap.channels && i < AUDIO_CHANNEL_COUNT_MAX && i < AUDIO_QAF_MAX_CHANNELS;
@@ -1238,7 +1241,7 @@
}
/* Call back function for mm module. */
-static void notify_event_callback(audio_session_handle_t session_handle /*__unused*/,
+static void notify_event_callback(audio_session_handle_t session_handle __unused,
void *prv_data,
void *buf,
audio_event_id_t event_id,
@@ -1255,7 +1258,7 @@
1.Open compress device for HDMI(PCM or AC3) based on current hdmi o/p format and write
data to the HDMI device.
*/
- int ret, i;
+ int ret;
audio_output_flags_t flags;
struct qaf_module* qaf_mod = (struct qaf_module*)prv_data;
struct audio_stream_out *bt_stream = NULL;
@@ -1293,7 +1296,7 @@
audio_qaf_out_buffer_t *buf_payload = (audio_qaf_out_buffer_t*)buf;
int index = -1;
- if (size < sizeof(audio_qaf_out_buffer_t)) {
+ if ((uint32_t)size < sizeof(audio_qaf_out_buffer_t)) {
ERROR_MSG("AUDIO_DATA_EVENT_V2 payload size is not sufficient.");
return;
}
@@ -1338,7 +1341,7 @@
audio_qaf_media_format_t *p_cached_fmt = NULL;
int index = -1;
- if (size < sizeof(audio_qaf_media_format_t)) {
+ if ( (uint32_t)size < sizeof(audio_qaf_media_format_t)) {
ERROR_MSG("Size is not proper for the event AUDIO_OUTPUT_MEDIA_FORMAT_EVENT.");
return ;
}
@@ -1448,7 +1451,6 @@
/* CASE 2: Multi-Channel PCM output to HDMI.
* If any other HDMI output is already enabled then this has to be dropped.
*/
- bool create_mch_out_stream = false;
if (p_qaf->passthrough_enabled) {
//Closing all the multi-Channel PCM HDMI output stream from QAF.
@@ -1487,7 +1489,7 @@
}
devices = AUDIO_DEVICE_OUT_AUX_DIGITAL;
- flags = (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_DIRECT_PCM);
+ flags = AUDIO_OUTPUT_FLAG_DIRECT;
ret = adev_open_output_stream((struct audio_hw_device *)p_qaf->adev,
QAF_DEFAULT_COMPR_AUDIO_HANDLE,
@@ -1603,7 +1605,7 @@
devices = device;
}
- flags = (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_DIRECT_PCM);
+ flags = AUDIO_OUTPUT_FLAG_DIRECT;
/* TODO:: Need to Propagate errors to framework */
ret = adev_open_output_stream((struct audio_hw_device *)p_qaf->adev,
@@ -1855,7 +1857,7 @@
{
ALOGV("%s %d", __func__, __LINE__);
unsigned char* license_data = NULL;
- device_license_config_t lic_config = {0};
+ device_license_config_t lic_config = {NULL, 0, 0};
int ret = -ENOSYS, size = 0;
char value[PROPERTY_VALUE_MAX] = {0};
struct qaf_module *qaf_mod = NULL;
@@ -2264,9 +2266,8 @@
/* Sets the stream set parameters (device routing information). */
static int qaf_out_set_parameters(struct audio_stream *stream, const char *kvpairs)
{
- struct str_parms *parms, *new_parms;
+ struct str_parms *parms;
char value[32];
- char *new_kv_pairs;
int val = 0;
struct stream_out *out = (struct stream_out *)stream;
int ret = 0;
@@ -2410,7 +2411,7 @@
/*ADSP event is not supported for passthrough*/
if ((param_id == AUDIO_EXTN_PARAM_ADSP_STREAM_CMD)
- && !(new_out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM)) continue;
+ && !(new_out->flags == AUDIO_OUTPUT_FLAG_DIRECT)) continue;
if (new_out->standby)
new_out->stream.write((struct audio_stream_out *)new_out, NULL, 0);
lock_output_stream(new_out);
@@ -2427,8 +2428,7 @@
audio_extn_param_payload *payload)
{
int ret = -EINVAL, i;
- struct stream_out *new_out;
- struct audio_usecase *uc_info;
+ struct stream_out *new_out = NULL;
struct qaf_module *qaf_mod = get_qaf_module_for_input_stream(out);
if (!out || !qaf_mod || !payload) {
@@ -2521,7 +2521,7 @@
out->config.period_count = DEEP_BUFFER_OUTPUT_PERIOD_COUNT;
out->config.start_threshold = QAF_DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4;
out->config.avail_min = QAF_DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4;
- } else if(out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
+ } else if(out->flags == AUDIO_OUTPUT_FLAG_DIRECT) {
out->compr_config.fragment_size = qaf_get_pcm_offload_input_buffer_size(&(config->offload_info));
}
@@ -2541,7 +2541,12 @@
struct stream_out *out = (struct stream_out *)stream;
struct qaf_module* qaf_mod = get_qaf_module_for_input_stream(out);
- if (!qaf_mod) return;
+ if (!qaf_mod) {
+ DEBUG_MSG("qaf module is NULL, by passing qaf on close output stream");
+ /*closing non-MS12/default output stream opened with qaf */
+ adev_close_output_stream(dev, stream);
+ return;
+ }
DEBUG_MSG("stream_handle(%p) format = %x", out, out->format);
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index 7b0309b..60216b1 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -53,10 +53,14 @@
#define SAMPLE_RATE_11025 11025
// Supported sample rates for USB
static uint32_t supported_sample_rates[] =
- {8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000, 352800, 384000};
+ {384000, 352800, 192000, 176400, 96000, 88200, 64000, 48000, 44100, 32000, 22050, 16000, 11025, 8000};
+static uint32_t supported_sample_rates_mask[2];
#define MAX_SAMPLE_RATE_SIZE sizeof(supported_sample_rates)/sizeof(supported_sample_rates[0])
+#define _MAX(x, y) (((x) >= (y)) ? (x) : (y))
+#define _MIN(x, y) (((x) <= (y)) ? (x) : (y))
+
enum usb_usecase_type{
USB_PLAYBACK = 0,
USB_CAPTURE,
@@ -246,7 +250,7 @@
return 0;
}
-static int usb_get_sample_rates(char *rates_str,
+static int usb_get_sample_rates(int type, char *rates_str,
struct usb_device_config *config)
{
uint32_t i;
@@ -277,6 +281,7 @@
if (supported_sample_rates[i] >= min_sr &&
supported_sample_rates[i] <= max_sr) {
config->rates[sr_size++] = supported_sample_rates[i];
+ supported_sample_rates_mask[type] |= (1<<i);
ALOGI_IF(usb_audio_debug_enable,
"%s: continuous sample rate supported_sample_rates[%d] %d",
__func__, i, supported_sample_rates[i]);
@@ -291,6 +296,7 @@
"%s: sr %d, supported_sample_rates[%d] %d -> matches!!",
__func__, sr, i, supported_sample_rates[i]);
config->rates[sr_size++] = supported_sample_rates[i];
+ supported_sample_rates_mask[type] |= (1<<i);
}
}
next_sr_string = strtok_r(NULL, " ,.-", &temp_ptr);
@@ -455,7 +461,7 @@
}
memcpy(rates_str, rates_str_start, size);
rates_str[size] = '\0';
- ret = usb_get_sample_rates(rates_str, usb_device_info);
+ ret = usb_get_sample_rates(type, rates_str, usb_device_info);
if (rates_str)
free(rates_str);
if (ret < 0) {
@@ -551,13 +557,24 @@
return;
}
-static bool usb_valid_device(int device)
+static inline bool usb_output_device(audio_devices_t device) {
+ // ignore accessory for now
+ if (device == AUDIO_DEVICE_OUT_USB_ACCESSORY)
+ return false;
+ return audio_is_usb_out_device(device);
+}
+
+static inline bool usb_input_device(audio_devices_t device) {
+ // ignore accessory for now
+ if (device == AUDIO_DEVICE_IN_USB_ACCESSORY)
+ return false;
+ return audio_is_usb_in_device(device);
+}
+
+static bool usb_valid_device(audio_devices_t device)
{
- bool is_usb_device = false;
- if ((device & AUDIO_DEVICE_OUT_USB_DEVICE) ||
- (device & AUDIO_DEVICE_IN_USB_DEVICE))
- is_usb_device = true;
- return is_usb_device;
+ return usb_output_device(device) ||
+ usb_input_device(device);
}
static void usb_print_active_device(void){
@@ -852,7 +869,7 @@
card_info = node_to_item(node_i, struct usb_card_config, list);
ALOGV("%s: card_dev_type (0x%x), card_no(%d)",
__func__, card_info->usb_device_type, card_info->usb_card);
- if (card_info->usb_device_type == AUDIO_DEVICE_OUT_USB_DEVICE) {
+ if (usb_output_device(card_info->usb_device_type)) {
if ((i = card_info->usb_sidetone_index[USB_SIDETONE_ENABLE_INDEX]) != -1) {
struct mixer_ctl *ctl = mixer_get_ctl_by_name(
card_info->usb_snd_mixer,
@@ -898,8 +915,8 @@
"%s: card_dev_type (0x%x), card_no(%d)",
__func__, card_info->usb_device_type, card_info->usb_card);
/* Currently only apply the first playback sound card configuration */
- if ((is_playback && card_info->usb_device_type == AUDIO_DEVICE_OUT_USB_DEVICE) ||
- ((!is_playback) && card_info->usb_device_type == AUDIO_DEVICE_IN_USB_DEVICE)){
+ if ((is_playback && usb_output_device(card_info->usb_device_type)) ||
+ (!is_playback && usb_input_device(card_info->usb_device_type))){
is_usb_supported = usb_audio_backend_apply_policy(
&card_info->usb_device_conf_list,
bit_width,
@@ -914,6 +931,70 @@
return is_usb_supported;
}
+int audio_extn_usb_get_max_channels(bool is_playback)
+{
+ struct listnode *node_i, *node_j;
+ struct usb_device_config *dev_info;
+ struct usb_card_config *card_info;
+ unsigned int max_ch = 1;
+ list_for_each(node_i, &usbmod->usb_card_conf_list) {
+ card_info = node_to_item(node_i, struct usb_card_config, list);
+ if (usb_output_device(card_info->usb_device_type) && !is_playback)
+ continue;
+ else if (usb_input_device(card_info->usb_device_type) && is_playback)
+ continue;
+
+ list_for_each(node_j, &card_info->usb_device_conf_list) {
+ dev_info = node_to_item(node_j, struct usb_device_config, list);
+ max_ch = _MAX(max_ch, dev_info->channels);
+ }
+ }
+
+ return max_ch;
+}
+
+int audio_extn_usb_get_max_bit_width(bool is_playback)
+{
+ struct listnode *node_i, *node_j;
+ struct usb_device_config *dev_info;
+ struct usb_card_config *card_info;
+ unsigned int max_bw = 16;
+ list_for_each(node_i, &usbmod->usb_card_conf_list) {
+ card_info = node_to_item(node_i, struct usb_card_config, list);
+ if (usb_output_device(card_info->usb_device_type) && !is_playback)
+ continue;
+ else if (usb_input_device(card_info->usb_device_type) && is_playback)
+ continue;
+
+ list_for_each(node_j, &card_info->usb_device_conf_list) {
+ dev_info = node_to_item(node_j, struct usb_device_config, list);
+ max_bw = _MAX(max_bw, dev_info->bit_width);
+ }
+ }
+
+ return max_bw;
+}
+
+int audio_extn_usb_get_sup_sample_rates(bool is_playback,
+ uint32_t *sample_rates,
+ uint32_t sample_rate_size)
+{
+ int type = is_playback ? USB_PLAYBACK : USB_CAPTURE;
+
+ ALOGV("%s supported_sample_rates_mask 0x%x", __func__, supported_sample_rates_mask[type]);
+ uint32_t bm = supported_sample_rates_mask[type];
+ uint32_t tries = _MIN(sample_rate_size, (uint32_t)__builtin_popcount(bm));
+
+ int i = 0;
+ while (tries--) {
+ int idx = __builtin_ffs(bm) - 1;
+ sample_rates[i++] = supported_sample_rates[idx];
+ bm &= ~(1<<idx);
+ }
+
+ return i;
+}
+
bool audio_extn_usb_is_capture_supported()
{
if (usbmod == NULL) {
@@ -968,18 +1049,18 @@
goto exit;
}
list_init(&usb_card_info->usb_device_conf_list);
- if (device & AUDIO_DEVICE_OUT_USB_DEVICE) {
+ if (usb_output_device(device)) {
if (!usb_get_device_pb_config(usb_card_info, card)){
usb_card_info->usb_card = card;
- usb_card_info->usb_device_type = AUDIO_DEVICE_OUT_USB_DEVICE;
+ usb_card_info->usb_device_type = device;
usb_get_sidetone_mixer(usb_card_info);
list_add_tail(&usbmod->usb_card_conf_list, &usb_card_info->list);
goto exit;
}
- } else if (device & AUDIO_DEVICE_IN_USB_DEVICE) {
+ } else if (usb_input_device(device)) {
if (!usb_get_device_cap_config(usb_card_info, card)) {
usb_card_info->usb_card = card;
- usb_card_info->usb_device_type = AUDIO_DEVICE_IN_USB_DEVICE;
+ usb_card_info->usb_device_type = device;
usbmod->is_capture_supported = true;
list_add_tail(&usbmod->usb_card_conf_list, &usb_card_info->list);
goto exit;
@@ -1034,7 +1115,12 @@
free(node_to_item(node_i, struct usb_card_config, list));
}
}
- usbmod->is_capture_supported = false;
+ if (audio_is_usb_in_device(device)) { // XXX not sure if we need to check for card
+ usbmod->is_capture_supported = false;
+ supported_sample_rates_mask[USB_CAPTURE] = 0;
+ } else
+ supported_sample_rates_mask[USB_PLAYBACK] = 0;
+
exit:
if (usb_audio_debug_enable)
usb_print_active_device();
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index c01e6f7..9f99a94 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -955,7 +955,9 @@
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
}
- if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
+ 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) {
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 ||
@@ -1016,6 +1018,8 @@
app_type = usecase->stream.in->app_type_cfg.app_type;
app_type_cfg[len++] = app_type;
app_type_cfg[len++] = acdb_dev_id;
+ if (usecase->id == USECASE_AUDIO_RECORD_VOIP)
+ usecase->stream.in->app_type_cfg.sample_rate = usecase->stream.in->sample_rate;
sample_rate = usecase->stream.in->app_type_cfg.sample_rate;
app_type_cfg[len++] = sample_rate;
if (snd_device_be_idx > 0)
@@ -1246,8 +1250,7 @@
*be multiple of (number of channels * bytes per sample)
*For writes to succeed, the buffer must be written at address which is multiple of 32
*/
- fragment_size = ALIGN(fragment_size, (bytes_per_sample * noOfChannels));
- fragment_size = ALIGN(fragment_size, 32);
+ fragment_size = ALIGN(fragment_size, (bytes_per_sample * noOfChannels * 32));
ALOGI("PCM offload Fragment size to %d bytes", fragment_size);
return fragment_size;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 1699340..be65139 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -63,6 +63,7 @@
#include <cutils/sched_policy.h>
#include <hardware/audio_effect.h>
+#include <hardware/audio_alsaops.h>
#include <system/thread_defs.h>
#include <tinyalsa/asoundlib.h>
#include <audio_effects/effect_aec.h>
@@ -116,6 +117,10 @@
.format = PCM_FORMAT_S16_LE,
};
+#define MIN_CHANNEL_COUNT 1
+#define DEFAULT_CHANNEL_COUNT 2
+#define MAX_HIFI_CHANNEL_COUNT 8
+
static unsigned int configured_low_latency_capture_period_size =
LOW_LATENCY_CAPTURE_PERIOD_SIZE;
@@ -184,6 +189,17 @@
.avail_min = MMAP_PERIOD_SIZE, //1 ms
};
+struct pcm_config pcm_config_hifi = {
+ .channels = DEFAULT_CHANNEL_COUNT, /* changed when the stream is opened */
+ .rate = DEFAULT_OUTPUT_SAMPLING_RATE, /* changed when the stream is opened */
+ .period_size = HIFI_BUFFER_OUTPUT_PERIOD_SIZE, /* change #define */
+ .period_count = HIFI_BUFFER_OUTPUT_PERIOD_COUNT,
+ .format = PCM_FORMAT_S24_3LE,
+ .start_threshold = 0,
+ .stop_threshold = INT_MAX,
+ .avail_min = 0,
+};
+
struct pcm_config pcm_config_audio_capture = {
.channels = 2,
.period_count = AUDIO_CAPTURE_PERIOD_COUNT,
@@ -276,6 +292,7 @@
[USECASE_AUDIO_PLAYBACK_OFFLOAD9] = "compress-offload-playback9",
[USECASE_AUDIO_PLAYBACK_FM] = "play-fm",
[USECASE_AUDIO_PLAYBACK_MMAP] = "mmap-playback",
+ [USECASE_AUDIO_PLAYBACK_HIFI] = "hifi-playback",
[USECASE_AUDIO_RECORD] = "audio-record",
[USECASE_AUDIO_RECORD_COMPRESS] = "audio-record-compress",
@@ -285,6 +302,7 @@
[USECASE_AUDIO_RECORD_LOW_LATENCY] = "low-latency-record",
[USECASE_AUDIO_RECORD_FM_VIRTUAL] = "fm-virtual-record",
[USECASE_AUDIO_RECORD_MMAP] = "mmap-record",
+ [USECASE_AUDIO_RECORD_HIFI] = "hifi-record",
[USECASE_AUDIO_HFP_SCO] = "hfp-sco",
[USECASE_AUDIO_HFP_SCO_WB] = "hfp-sco-wb",
@@ -361,7 +379,7 @@
uint32_t value;
};
-static const struct string_to_enum out_channels_name_to_enum_table[] = {
+static const struct string_to_enum channels_name_to_enum_table[] = {
STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
STRING_TO_ENUM(AUDIO_CHANNEL_OUT_2POINT1),
STRING_TO_ENUM(AUDIO_CHANNEL_OUT_QUAD),
@@ -370,9 +388,23 @@
STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
STRING_TO_ENUM(AUDIO_CHANNEL_OUT_6POINT1),
STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
+ STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO),
+ STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO),
+ STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK),
+ STRING_TO_ENUM(AUDIO_CHANNEL_INDEX_MASK_1),
+ STRING_TO_ENUM(AUDIO_CHANNEL_INDEX_MASK_2),
+ STRING_TO_ENUM(AUDIO_CHANNEL_INDEX_MASK_3),
+ STRING_TO_ENUM(AUDIO_CHANNEL_INDEX_MASK_4),
+ STRING_TO_ENUM(AUDIO_CHANNEL_INDEX_MASK_5),
+ STRING_TO_ENUM(AUDIO_CHANNEL_INDEX_MASK_6),
+ STRING_TO_ENUM(AUDIO_CHANNEL_INDEX_MASK_7),
+ STRING_TO_ENUM(AUDIO_CHANNEL_INDEX_MASK_8),
};
-static const struct string_to_enum out_formats_name_to_enum_table[] = {
+static const struct string_to_enum formats_name_to_enum_table[] = {
+ STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT),
+ STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED),
+ STRING_TO_ENUM(AUDIO_FORMAT_PCM_32_BIT),
STRING_TO_ENUM(AUDIO_FORMAT_AC3),
STRING_TO_ENUM(AUDIO_FORMAT_E_AC3),
STRING_TO_ENUM(AUDIO_FORMAT_E_AC3_JOC),
@@ -387,7 +419,7 @@
32000, 44100, 48000, 88200, 96000, 176400, 192000,
};
-static const struct string_to_enum out_hdmi_sample_rates_name_to_enum_table[] = {
+static const struct string_to_enum out_sample_rates_name_to_enum_table[] = {
STRING_TO_ENUM(32000),
STRING_TO_ENUM(44100),
STRING_TO_ENUM(48000),
@@ -524,6 +556,17 @@
return 0;
}
+static inline void adjust_frames_for_device_delay(struct stream_out *out,
+ 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) {
+ unsigned long offset =
+ (audio_extn_a2dp_get_encoder_latency() * out->sample_rate / 1000);
+ *dsp_frames = (*dsp_frames > offset) ? (*dsp_frames - offset) : 0;
+ }
+}
+
__attribute__ ((visibility ("default")))
bool audio_hw_send_gain_dep_calibration(int level) {
bool ret_val = false;
@@ -771,6 +814,126 @@
}
}
+#ifdef DYNAMIC_ECNS_ENABLED
+static int send_effect_enable_disable_mixer_ctl(struct audio_device *adev,
+ struct audio_effect_config effect_config,
+ unsigned int param_value)
+{
+ char mixer_ctl_name[] = "Audio Effect";
+ struct mixer_ctl *ctl;
+ long set_values[6];
+ struct stream_in *in = adev->active_input;
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get mixer ctl - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+
+ set_values[0] = 1; //0:Rx 1:Tx
+ set_values[1] = in->app_type_cfg.app_type;
+ set_values[2] = (long)effect_config.module_id;
+ set_values[3] = (long)effect_config.instance_id;
+ set_values[4] = (long)effect_config.param_id;
+ set_values[5] = param_value;
+
+ mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+
+ return 0;
+
+}
+
+static int update_effect_param_ecns(struct audio_device *adev, unsigned int module_id,
+ int effect_type, unsigned int *param_value)
+{
+ int ret = 0;
+ struct audio_effect_config other_effect_config;
+ struct audio_usecase *usecase = NULL;
+ struct stream_in *in = adev->active_input;
+
+ usecase = get_usecase_from_list(adev, in->usecase);
+ if (!usecase)
+ return -EINVAL;
+
+ ret = platform_get_effect_config_data(usecase->in_snd_device, &other_effect_config,
+ effect_type == EFFECT_AEC ? EFFECT_NS : EFFECT_AEC);
+ if (ret < 0) {
+ ALOGE("%s Failed to get effect params %d", __func__, ret);
+ return ret;
+ }
+
+ if (module_id == other_effect_config.module_id) {
+ //Same module id for AEC/NS. Values need to be combined
+ if (((effect_type == EFFECT_AEC) && (in->enable_ns)) ||
+ ((effect_type == EFFECT_NS) && (in->enable_aec))) {
+ *param_value |= other_effect_config.param_value;
+ }
+ }
+
+ return ret;
+}
+
+static int enable_disable_effect(struct audio_device *adev, int effect_type, bool enable)
+{
+ struct audio_effect_config effect_config;
+ struct audio_usecase *usecase = NULL;
+ int ret = 0;
+ unsigned int param_value = 0;
+ struct stream_in *in = adev->active_input;
+
+ if (!in) {
+ ALOGE("%s: Invalid input stream", __func__);
+ return -EINVAL;
+ }
+
+ ALOGD("%s: effect_type:%d enable:%d", __func__, effect_type, enable);
+
+ usecase = get_usecase_from_list(adev, in->usecase);
+
+ ret = platform_get_effect_config_data(usecase->in_snd_device, &effect_config, effect_type);
+ if (ret < 0) {
+ ALOGE("%s Failed to get module id %d", __func__, ret);
+ return ret;
+ }
+ ALOGV("%s: %d %d usecase->id:%d usecase->in_snd_device:%d", __func__, effect_config.module_id,
+ in->app_type_cfg.app_type, usecase->id, usecase->in_snd_device);
+
+ if(enable)
+ param_value = effect_config.param_value;
+
+ /*Special handling for AEC & NS effects Param values need to be
+ updated if module ids are same*/
+
+ if ((effect_type == EFFECT_AEC) || (effect_type == EFFECT_NS)) {
+ ret = update_effect_param_ecns(adev, effect_config.module_id, effect_type, ¶m_value);
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = send_effect_enable_disable_mixer_ctl(adev, effect_config, param_value);
+
+ return ret;
+}
+
+static void check_and_enable_effect(struct audio_device *adev)
+{
+
+ if (adev->active_input->enable_aec) {
+ enable_disable_effect(adev, EFFECT_AEC, true);
+ }
+
+ if (adev->active_input->enable_ns &&
+ adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
+ enable_disable_effect(adev, EFFECT_NS, true);
+ }
+}
+#else
+#define enable_disable_effect(x, y, z) ENOSYS
+#define check_and_enable_effect(x) ENOSYS
+#endif
+
+
int pcm_ioctl(struct pcm *pcm, int request, ...)
{
va_list ap;
@@ -971,6 +1134,10 @@
if (platform_can_enable_spkr_prot_on_device(snd_device) &&
audio_extn_spkr_prot_is_enabled()) {
audio_extn_spkr_prot_stop_processing(snd_device);
+
+ // when speaker device is disabled, reset swap.
+ // will be renabled on usecase start
+ platform_set_swap_channels(adev, false);
} else if (platform_split_snd_device(adev->platform,
snd_device,
&num_devices,
@@ -1444,6 +1611,118 @@
return ret;
}
+static inline ssize_t read_usb_sup_sample_rates(bool is_playback __unused,
+ uint32_t *supported_sample_rates __unused,
+ uint32_t max_rates __unused)
+{
+ ssize_t count = audio_extn_usb_get_sup_sample_rates(is_playback,
+ supported_sample_rates,
+ max_rates);
+ ssize_t i = 0;
+
+ for (i=0; i<count; i++) {
+ ALOGV("%s %s %d", __func__, is_playback ? "P" : "C",
+ supported_sample_rates[i]);
+ }
+ return count;
+}
+
+static inline int read_usb_sup_channel_masks(bool is_playback,
+ audio_channel_mask_t *supported_channel_masks,
+ uint32_t max_masks)
+{
+ int channels = audio_extn_usb_get_max_channels(is_playback);
+ int channel_count;
+ uint32_t num_masks = 0;
+ if (channels > MAX_HIFI_CHANNEL_COUNT)
+ channels = MAX_HIFI_CHANNEL_COUNT;
+
+ if (is_playback) {
+ // For playback we never report mono because the framework always outputs stereo
+ channel_count = DEFAULT_CHANNEL_COUNT;
+ // audio_channel_out_mask_from_count() does return positional masks for channel counts
+ // above 2 but we want indexed masks here. So we
+ for ( ; channel_count <= channels && num_masks < max_masks; channel_count++) {
+ supported_channel_masks[num_masks++] = audio_channel_out_mask_from_count(channel_count);
+ }
+ for ( ; channel_count <= channels && num_masks < max_masks; channel_count++) {
+ supported_channel_masks[num_masks++] =
+ audio_channel_mask_for_index_assignment_from_count(channel_count);
+ }
+ } else {
+ // For capture we report all supported channel masks from 1 channel up.
+ channel_count = MIN_CHANNEL_COUNT;
+ // audio_channel_in_mask_from_count() does the right conversion to either positional or
+ // indexed mask
+ for ( ; channel_count <= channels && num_masks < max_masks; channel_count++) {
+ supported_channel_masks[num_masks++] =
+ audio_channel_in_mask_from_count(channel_count);
+ }
+ }
+ ALOGV("%s: %s supported ch %d supported_channel_masks[0] %08x num_masks %d", __func__,
+ is_playback ? "P" : "C", channels, supported_channel_masks[0], num_masks);
+ return num_masks;
+}
+
+static inline int read_usb_sup_formats(bool is_playback __unused,
+ audio_format_t *supported_formats,
+ uint32_t max_formats __unused)
+{
+ int bitwidth = audio_extn_usb_get_max_bit_width(is_playback);
+ switch (bitwidth) {
+ case 24:
+ // XXX : usb.c returns 24 for s24 and s24_le?
+ supported_formats[0] = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ break;
+ case 32:
+ supported_formats[0] = AUDIO_FORMAT_PCM_32_BIT;
+ break;
+ case 16:
+ default :
+ supported_formats[0] = AUDIO_FORMAT_PCM_16_BIT;
+ break;
+ }
+ ALOGV("%s: %s supported format %d", __func__,
+ is_playback ? "P" : "C", bitwidth);
+ return 1;
+}
+
+static inline int read_usb_sup_params_and_compare(bool is_playback,
+ audio_format_t *format,
+ audio_format_t *supported_formats,
+ uint32_t max_formats,
+ audio_channel_mask_t *mask,
+ audio_channel_mask_t *supported_channel_masks,
+ uint32_t max_masks,
+ uint32_t *rate,
+ uint32_t *supported_sample_rates,
+ uint32_t max_rates) {
+ int ret = 0;
+ int num_formats;
+ int num_masks;
+ int num_rates;
+ int i;
+
+ num_formats = read_usb_sup_formats(is_playback, supported_formats,
+ max_formats);
+ num_masks = read_usb_sup_channel_masks(is_playback, supported_channel_masks,
+ max_masks);
+
+ num_rates = read_usb_sup_sample_rates(is_playback,
+ supported_sample_rates, max_rates);
+
+#define LUT(table, len, what, dflt) \
+ for (i=0; i<len && (table[i] != what); i++); \
+ if (i==len) { ret |= (what == dflt ? 0 : -1); what=table[0]; }
+
+ LUT(supported_formats, num_formats, *format, AUDIO_FORMAT_DEFAULT);
+ LUT(supported_channel_masks, num_masks, *mask, AUDIO_CHANNEL_NONE);
+ LUT(supported_sample_rates, num_rates, *rate, 0);
+
+#undef LUT
+ return ret < 0 ? -EINVAL : 0; // HACK TBD
+}
+
audio_usecase_t get_usecase_id_from_usecase_type(const struct audio_device *adev,
usecase_type_t type)
{
@@ -1634,8 +1913,12 @@
bool ret = false;
bool is_it_true_mode = false;
+ if(usecase->stream.out == NULL) {
+ ALOGE("%s: stream.out is NULL", __func__);
+ return false;
+ }
+
if (is_offload_usecase(usecase->id) &&
- (usecase->stream.out) &&
(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)) {
@@ -1650,8 +1933,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) &&
- (usecase->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) &&
+ if((usecase->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) &&
audio_extn_a2dp_is_force_device_switch()) {
ALOGD("Force a2dp device switch to update new encoder config");
ret = true;
@@ -1968,6 +2250,11 @@
}
enable_audio_route(adev, usecase);
+ /* If input stream is already running then effect needs to be
+ applied on the new input device that's being enabled here. */
+ if ((in_snd_device != SND_DEVICE_NONE) && (!adev->active_input->standby))
+ check_and_enable_effect(adev);
+
if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL) {
/* Enable aanc only if voice call exists */
if (voice_is_call_state_active(adev))
@@ -2162,8 +2449,10 @@
__func__, adev->snd_card, in->pcm_device_id, in->config.channels);
while (1) {
+ ATRACE_BEGIN("pcm_in_open");
in->pcm = pcm_open(adev->snd_card, in->pcm_device_id,
flags, &config);
+ ATRACE_END();
if (in->pcm == NULL || !pcm_is_ready(in->pcm)) {
ALOGE("%s: %s", __func__, pcm_get_error(in->pcm));
if (in->pcm != NULL) {
@@ -2181,7 +2470,9 @@
}
ALOGV("%s: pcm_prepare", __func__);
+ ATRACE_BEGIN("pcm_in_prepare");
ret = pcm_prepare(in->pcm);
+ ATRACE_END();
if (ret < 0) {
ALOGE("%s: pcm_prepare returned %d", __func__, ret);
pcm_close(in->pcm);
@@ -2190,7 +2481,9 @@
}
register_in_stream(in);
if (in->realtime) {
+ ATRACE_BEGIN("pcm_in_start");
ret = pcm_start(in->pcm);
+ ATRACE_END();
if (ret < 0) {
ALOGE("%s: RT pcm_start failed ret %d", __func__, ret);
pcm_close(in->pcm);
@@ -2200,6 +2493,8 @@
}
}
+ check_and_enable_effect(adev);
+
done_open:
audio_extn_perf_lock_release(&adev->perf_lock_handle);
ALOGD("%s: exit", __func__);
@@ -2584,6 +2879,7 @@
char* perf_mode[] = {"ULL", "ULL_PP", "LL"};
bool a2dp_combo = false;
+ ATRACE_BEGIN("start_output_stream");
if ((out->usecase < 0) || (out->usecase >= AUDIO_USECASE_MAX)) {
ret = -EINVAL;
goto error_config;
@@ -2723,8 +3019,10 @@
}
while (1) {
+ ATRACE_BEGIN("pcm_open");
out->pcm = pcm_open(adev->snd_card, out->pcm_device_id,
flags, &out->config);
+ ATRACE_END();
if (out->pcm == NULL || !pcm_is_ready(out->pcm)) {
ALOGE("%s: %s", __func__, pcm_get_error(out->pcm));
if (out->pcm != NULL) {
@@ -2743,7 +3041,9 @@
ALOGV("%s: pcm_prepare", __func__);
if (pcm_is_ready(out->pcm)) {
+ ATRACE_BEGIN("pcm_prepare");
ret = pcm_prepare(out->pcm);
+ ATRACE_END();
if (ret < 0) {
ALOGE("%s: pcm_prepare returned %d", __func__, ret);
pcm_close(out->pcm);
@@ -2763,9 +3063,11 @@
adev->dsp_bit_width_enforce_mode,
true);
out->pcm = NULL;
+ ATRACE_BEGIN("compress_open");
out->compr = compress_open(adev->snd_card,
out->pcm_device_id,
COMPRESS_IN, &out->compr_config);
+ ATRACE_END();
if (out->compr && !is_compress_ready(out->compr)) {
ALOGE("%s: %s", __func__, compress_get_error(out->compr));
compress_close(out->compr);
@@ -2816,7 +3118,9 @@
ALOGE("%s: pcm stream not ready", __func__);
goto error_open;
}
+ ATRACE_BEGIN("pcm_start");
ret = pcm_start(out->pcm);
+ ATRACE_END();
if (ret < 0)
goto error_open;
}
@@ -2831,6 +3135,14 @@
ALOGE("%s: audio_extn_ip_hdlr_intf_open failed %d",__func__, ret);
}
+ // consider a scenario where on pause lower layers are tear down.
+ // so on resume, swap mixer control need to be sent only when
+ // backend is active, hence rather than sending from enable device
+ // sending it from start of streamtream
+
+ platform_set_swap_channels(adev, true);
+
+ ATRACE_END();
return ret;
error_open:
audio_extn_perf_lock_release(&adev->perf_lock_handle);
@@ -2841,6 +3153,7 @@
* drivers to recover incases like SSR.
*/
usleep(50000);
+ ATRACE_END();
return ret;
}
@@ -2854,7 +3167,8 @@
(format != AUDIO_FORMAT_PCM_24_BIT_PACKED) && (format != AUDIO_FORMAT_PCM_32_BIT) &&
(format != AUDIO_FORMAT_PCM_FLOAT)) &&
!voice_extn_compress_voip_is_format_supported(format) &&
- !audio_extn_compr_cap_format_supported(format)) ret = -EINVAL;
+ !audio_extn_compr_cap_format_supported(format))
+ ret = -EINVAL;
switch (channel_count) {
case 1:
@@ -3129,6 +3443,7 @@
stream, out->usecase, use_case_table[out->usecase]);
if (!out->standby) {
+ ATRACE_BEGIN("out_standby_l");
if (adev->adm_deregister_stream)
adev->adm_deregister_stream(adev->adm_data, out->handle);
@@ -3140,6 +3455,7 @@
voice_extn_compress_voip_close_output_stream(stream);
out->started = 0;
ALOGD("VOIP output entered standby");
+ ATRACE_END();
return 0;
} else if (!is_offload_usecase(out->usecase)) {
if (out->pcm) {
@@ -3158,6 +3474,7 @@
}
}
stop_output_stream(out);
+ ATRACE_END();
}
ALOGD("%s: exit", __func__);
return 0;
@@ -3356,8 +3673,13 @@
select_devices(adev, out->usecase);
out->devices = new_dev;
}
- if (!same_dev)
+
+ if (!same_dev) {
+ // on device switch force swap, lower functions will make sure
+ // to check if swap is allowed or not.
+ platform_set_swap_channels(adev, true);
audio_extn_perf_lock_release(&adev->perf_lock_handle);
+ }
if ((out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
out->a2dp_compress_mute &&
(!(out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) || audio_extn_a2dp_is_ready())) {
@@ -3442,6 +3764,103 @@
return ret;
}
+static bool stream_get_parameter_channels(struct str_parms *query,
+ struct str_parms *reply,
+ audio_channel_mask_t *supported_channel_masks) {
+ int ret = -1;
+ char value[512];
+ bool first = true;
+ size_t i, j;
+
+ if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
+ ret = 0;
+ value[0] = '\0';
+ i = 0;
+ while (supported_channel_masks[i] != 0) {
+ for (j = 0; j < ARRAY_SIZE(channels_name_to_enum_table); j++) {
+ if (channels_name_to_enum_table[j].value == supported_channel_masks[i]) {
+ if (!first)
+ strlcat(value, "|", sizeof(value));
+
+ strlcat(value, channels_name_to_enum_table[j].name, sizeof(value));
+ first = false;
+ break;
+ }
+ }
+ i++;
+ }
+ str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
+ }
+ return ret == 0;
+}
+
+static bool stream_get_parameter_formats(struct str_parms *query,
+ struct str_parms *reply,
+ audio_format_t *supported_formats) {
+ int ret = -1;
+ char value[256];
+ size_t i, j;
+ bool first = true;
+
+ if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
+ ret = 0;
+ value[0] = '\0';
+ i = 0;
+ while (supported_formats[i] != 0) {
+ for (j = 0; j < ARRAY_SIZE(formats_name_to_enum_table); j++) {
+ if (formats_name_to_enum_table[j].value == supported_formats[i]) {
+ if (!first) {
+ strlcat(value, "|", sizeof(value));
+ }
+ strlcat(value, formats_name_to_enum_table[j].name, sizeof(value));
+ first = false;
+ break;
+ }
+ }
+ i++;
+ }
+ str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_FORMATS, value);
+ }
+ return ret == 0;
+}
+
+static bool stream_get_parameter_rates(struct str_parms *query,
+ struct str_parms *reply,
+ uint32_t *supported_sample_rates) {
+
+ int i;
+ char value[256];
+ int ret = -1;
+ if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
+ ret = 0;
+ value[0] = '\0';
+ i=0;
+ int cursor = 0;
+ while (supported_sample_rates[i]) {
+ int avail = sizeof(value) - cursor;
+ ret = snprintf(value + cursor, avail, "%s%d",
+ cursor > 0 ? "|" : "",
+ supported_sample_rates[i]);
+ if (ret < 0 || ret >= avail) {
+ // if cursor is at the last element of the array
+ // overwrite with \0 is duplicate work as
+ // snprintf already put a \0 in place.
+ // else
+ // we had space to write the '|' at value[cursor]
+ // (which will be overwritten) or no space to fill
+ // the first element (=> cursor == 0)
+ value[cursor] = '\0';
+ break;
+ }
+ cursor += ret;
+ ++i;
+ }
+ str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES,
+ value);
+ }
+ return ret >= 0;
+}
+
static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
{
struct stream_out *out = (struct stream_out *)stream;
@@ -3464,18 +3883,18 @@
return NULL;
}
- ALOGV("%s: enter: keys - %s", __func__, keys);
+ ALOGV("%s: %s enter: keys - %s", __func__, use_case_table[out->usecase], keys);
ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
if (ret >= 0) {
value[0] = '\0';
i = 0;
while (out->supported_channel_masks[i] != 0) {
- for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
- if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
+ for (j = 0; j < ARRAY_SIZE(channels_name_to_enum_table); j++) {
+ if (channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
if (!first) {
strlcat(value, "|", sizeof(value));
}
- strlcat(value, out_channels_name_to_enum_table[j].name, sizeof(value));
+ strlcat(value, channels_name_to_enum_table[j].name, sizeof(value));
first = false;
break;
}
@@ -3513,12 +3932,12 @@
i = 0;
first = true;
while (out->supported_formats[i] != 0) {
- for (j = 0; j < ARRAY_SIZE(out_formats_name_to_enum_table); j++) {
- if (out_formats_name_to_enum_table[j].value == out->supported_formats[i]) {
+ for (j = 0; j < ARRAY_SIZE(formats_name_to_enum_table); j++) {
+ if (formats_name_to_enum_table[j].value == out->supported_formats[i]) {
if (!first) {
strlcat(value, "|", sizeof(value));
}
- strlcat(value, out_formats_name_to_enum_table[j].name, sizeof(value));
+ strlcat(value, formats_name_to_enum_table[j].name, sizeof(value));
first = false;
break;
}
@@ -3537,12 +3956,12 @@
i = 0;
first = true;
while (out->supported_sample_rates[i] != 0) {
- for (j = 0; j < ARRAY_SIZE(out_hdmi_sample_rates_name_to_enum_table); j++) {
- if (out_hdmi_sample_rates_name_to_enum_table[j].value == out->supported_sample_rates[i]) {
+ for (j = 0; j < ARRAY_SIZE(out_sample_rates_name_to_enum_table); j++) {
+ if (out_sample_rates_name_to_enum_table[j].value == out->supported_sample_rates[i]) {
if (!first) {
strlcat(value, "|", sizeof(value));
}
- strlcat(value, out_hdmi_sample_rates_name_to_enum_table[j].name, sizeof(value));
+ strlcat(value, out_sample_rates_name_to_enum_table[j].name, sizeof(value));
first = false;
break;
}
@@ -3743,6 +4162,7 @@
ssize_t ret = 0;
int channels = 0;
+ ATRACE_BEGIN("out_write");
lock_output_stream(out);
if (CARD_STATUS_OFFLINE == out->card_status) {
@@ -3751,6 +4171,7 @@
/*during SSR for compress usecase we should return error to flinger*/
ALOGD(" copl %s: sound card is not active/SSR state", __func__);
pthread_mutex_unlock(&out->lock);
+ ATRACE_END();
return -ENETRESET;
} else {
ALOGD(" %s: sound card is not active/SSR state", __func__);
@@ -3879,6 +4300,7 @@
ALOGW("Error written bytes %zu > %d (fragment_size)",
bytes, out->hal_fragment_size);
pthread_mutex_unlock(&out->lock);
+ ATRACE_END();
return -EINVAL;
} else {
audio_format_t dst_format = out->hal_op_format;
@@ -3919,6 +4341,7 @@
out->card_status = CARD_STATUS_OFFLINE;
pthread_mutex_unlock(&out->lock);
out_on_error(&out->stream.common);
+ ATRACE_END();
return ret;
}
@@ -3939,6 +4362,7 @@
out->playback_started);
}
pthread_mutex_unlock(&out->lock);
+ ATRACE_END();
return ret;
} else {
if (out->pcm) {
@@ -4028,9 +4452,11 @@
if (audio_extn_passthru_is_passthrough_stream(out)) {
ALOGE("%s: write error, ret = %ld", __func__, ret);
+ ATRACE_END();
return ret;
}
}
+ ATRACE_END();
return bytes;
}
@@ -4052,6 +4478,7 @@
if (!out->non_blocking && !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
*dsp_frames = get_actual_pcm_frames_rendered(out);
ALOGVV("dsp_frames %d sampleRate %d",(int)*dsp_frames,out->sample_rate);
+ adjust_frames_for_device_delay(out, dsp_frames);
return 0;
}
@@ -4080,11 +4507,13 @@
ret = -EINVAL;
} else {
ret = 0;
+ adjust_frames_for_device_delay(out, dsp_frames);
}
pthread_mutex_unlock(&out->lock);
return ret;
} else if (audio_is_linear_pcm(out->format)) {
*dsp_frames = out->written;
+ adjust_frames_for_device_delay(out, dsp_frames);
return 0;
} else
return -EINVAL;
@@ -4364,8 +4793,8 @@
struct stream_out *out = (struct stream_out *)stream;
struct audio_device *adev = out->dev;
int ret = 0;
- unsigned int offset1;
- unsigned int frames1;
+ unsigned int offset1 = 0;
+ unsigned int frames1 = 0;
const char *step = "";
uint32_t mmap_size;
@@ -4558,7 +4987,9 @@
if (do_stop) {
if (in->pcm) {
+ ATRACE_BEGIN("pcm_in_close");
pcm_close(in->pcm);
+ ATRACE_END();
in->pcm = NULL;
}
status = stop_input_stream(in);
@@ -4705,10 +5136,16 @@
return NULL;
}
- ALOGV("%s: enter: keys - %s", __func__, keys);
+ ALOGV("%s: enter: keys - %s %s ", __func__, use_case_table[in->usecase], keys);
voice_extn_in_get_parameters(in, query, reply);
+ stream_get_parameter_channels(query, reply,
+ &in->supported_channel_masks[0]);
+ stream_get_parameter_formats(query, reply,
+ &in->supported_formats[0]);
+ stream_get_parameter_rates(query, reply,
+ &in->supported_sample_rates[0]);
str = str_parms_to_str(reply);
str_parms_destroy(query);
str_parms_destroy(reply);
@@ -4845,6 +5282,8 @@
effect_descriptor_t desc;
status = (*effect)->get_descriptor(effect, &desc);
+ ALOGV("%s: status %d in->standby %d enable:%d", __func__, status, in->standby, enable);
+
if (status != 0)
return status;
@@ -4854,14 +5293,22 @@
in->enable_aec != enable &&
(memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
in->enable_aec = enable;
- if (!in->standby)
- select_devices(in->dev, in->usecase);
+ if (!in->standby) {
+ if (enable_disable_effect(in->dev, EFFECT_AEC, enable) == ENOSYS)
+ select_devices(in->dev, in->usecase);
+ }
+
}
if (in->enable_ns != enable &&
(memcmp(&desc.type, FX_IID_NS, sizeof(effect_uuid_t)) == 0)) {
in->enable_ns = enable;
- if (!in->standby)
- select_devices(in->dev, in->usecase);
+ if (!in->standby) {
+ if (in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
+ if (enable_disable_effect(in->dev, EFFECT_NS, enable) == ENOSYS)
+ select_devices(in->dev, in->usecase);
+ } else
+ select_devices(in->dev, in->usecase);
+ }
}
pthread_mutex_unlock(&in->dev->lock);
pthread_mutex_unlock(&in->lock);
@@ -5043,6 +5490,10 @@
audio_format_t format;
struct adsp_hdlr_stream_cfg hdlr_stream_cfg;
bool is_direct_passthough = false;
+ bool is_hdmi = devices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
+ bool is_usb_dev = audio_is_usb_out_device(devices) &&
+ (devices != AUDIO_DEVICE_OUT_USB_ACCESSORY);
+ bool direct_dev = is_hdmi || is_usb_dev;
*stream_out = NULL;
@@ -5087,25 +5538,41 @@
(property_get_bool("audio.matrix.limiter.enable", false)))
platform_set_device_params(out, DEVICE_PARAM_LIMITER_ID, 1);
- if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL &&
- (flags & AUDIO_OUTPUT_FLAG_DIRECT)) {
- pthread_mutex_lock(&adev->lock);
- ALOGV("AUDIO_DEVICE_OUT_AUX_DIGITAL and DIRECT|OFFLOAD, check hdmi caps");
- ret = read_hdmi_sink_caps(out);
- pthread_mutex_unlock(&adev->lock);
- if (ret != 0) {
+ if (audio_is_linear_pcm(out->format) &&
+ out->flags == AUDIO_OUTPUT_FLAG_NONE && direct_dev) {
+ pthread_mutex_lock(&adev->lock);
+ if (is_hdmi) {
+ ALOGV("AUDIO_DEVICE_OUT_AUX_DIGITAL and DIRECT|OFFLOAD, check hdmi caps");
+ ret = read_hdmi_sink_caps(out);
+ } else if (is_usb_dev) {
+ ret = read_usb_sup_params_and_compare(true /*is_playback*/,
+ &config->format,
+ &out->supported_formats[0],
+ MAX_SUPPORTED_FORMATS,
+ &config->channel_mask,
+ &out->supported_channel_masks[0],
+ MAX_SUPPORTED_CHANNEL_MASKS,
+ &config->sample_rate,
+ &out->supported_sample_rates[0],
+ MAX_SUPPORTED_SAMPLE_RATES);
+ ALOGV("plugged dev USB ret %d", ret);
+ } else {
+ ret = -1;
+ }
+ pthread_mutex_unlock(&adev->lock);
+ if (ret != 0) {
if (ret == -ENOSYS) {
/* ignore and go with default */
ret = 0;
} else {
- ALOGE("error reading hdmi sink caps");
+ ALOGE("error reading direct dev sink caps");
goto error_open;
}
}
}
/* Init use case and pcm_config */
-#ifndef COMPRES_ENABLED
+#ifndef COMPRESS_VOIP_ENABLED
if (out->flags == (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_VOIP_RX) &&
(out->sample_rate == 8000 || out->sample_rate == 16000 ||
out->sample_rate == 32000 || out->sample_rate == 48000)) {
@@ -5118,7 +5585,7 @@
out->config.rate = out->sample_rate;
#else
- } else if ((out->dev->mode == AUDIO_MODE_IN_COMMUNICATION || voice_extn_compress_voip_is_active(out->dev)) &&
+ if ((out->dev->mode == AUDIO_MODE_IN_COMMUNICATION || voice_extn_compress_voip_is_active(out->dev)) &&
(out->flags == (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_VOIP_RX)) &&
(voice_extn_compress_voip_is_config_supported(config))) {
ret = voice_extn_compress_voip_open_output_stream(out);
@@ -5128,6 +5595,19 @@
goto error_open;
}
#endif
+ } else if (audio_is_linear_pcm(out->format) &&
+ out->flags == AUDIO_OUTPUT_FLAG_NONE && is_usb_dev) {
+ out->channel_mask = config->channel_mask;
+ out->sample_rate = config->sample_rate;
+ out->format = config->format;
+ out->usecase = USECASE_AUDIO_PLAYBACK_HIFI;
+ // does this change?
+ out->config = is_hdmi ? pcm_config_hdmi_multi : pcm_config_hifi;
+ out->config.rate = config->sample_rate;
+ out->config.channels = audio_channel_count_from_out_mask(out->channel_mask);
+ out->config.period_size = HDMI_MULTI_PERIOD_BYTES / (out->config.channels *
+ audio_bytes_per_sample(config->format));
+ out->config.format = pcm_format_from_audio_format(out->format);
} else if ((out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) ||
(out->flags == AUDIO_OUTPUT_FLAG_DIRECT)) {
pthread_mutex_lock(&adev->lock);
@@ -5183,8 +5663,8 @@
out->stream.pause = out_pause;
out->stream.resume = out_resume;
out->stream.flush = out_flush;
+ out->stream.set_callback = out_set_callback;
if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
- out->stream.set_callback = out_set_callback;
out->stream.drain = out_drain;
out->usecase = get_offload_usecase(adev, true /* is_compress */);
ALOGV("Compress Offload usecase .. usecase selected %d", out->usecase);
@@ -5615,7 +6095,7 @@
struct audio_device *adev = out->dev;
int ret = 0;
- ALOGD("%s: enter:stream_handle(%p)",__func__, out);
+ ALOGD("%s: enter:stream_handle(%s)",__func__, use_case_table[out->usecase]);
// must deregister from sndmonitor first to prevent races
// between the callback and close_stream
@@ -5744,19 +6224,10 @@
status = -EINVAL;
}
if (status == 0) {
- if (adev->speaker_lr_swap != reverse_speakers) {
- adev->speaker_lr_swap = reverse_speakers;
- // only update the selected device if there is active pcm playback
- struct audio_usecase *usecase;
- struct listnode *node;
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == PCM_PLAYBACK) {
- select_devices(adev, usecase->id);
- break;
- }
- }
- }
+ // check and set swap
+ // - check if orientation changed and speaker active
+ // - set rotation and cache the rotation value
+ platform_check_and_set_swap_lr_channels(adev, reverse_speakers);
}
}
@@ -6014,6 +6485,42 @@
false /* is_low_latency: since we don't know, be conservative */);
}
+static bool adev_input_allow_hifi_record(struct audio_device *adev,
+ audio_devices_t devices,
+ audio_input_flags_t flags,
+ audio_source_t source) {
+ const bool allowed = true;
+
+ if (!audio_is_usb_in_device(devices))
+ return !allowed;
+
+ switch (flags) {
+ case AUDIO_INPUT_FLAG_NONE:
+ case AUDIO_INPUT_FLAG_FAST: // just fast, not fast|raw || fast|mmap
+ break;
+ default:
+ return !allowed;
+ }
+
+ switch (source) {
+ case AUDIO_SOURCE_DEFAULT:
+ case AUDIO_SOURCE_MIC:
+ case AUDIO_SOURCE_UNPROCESSED:
+ break;
+ default:
+ return !allowed;
+ }
+
+ switch (adev->mode) {
+ case 0:
+ break;
+ default:
+ return !allowed;
+ }
+
+ return allowed;
+}
+
static int adev_open_input_stream(struct audio_hw_device *dev,
audio_io_handle_t handle,
audio_devices_t devices,
@@ -6029,11 +6536,26 @@
int channel_count = audio_channel_count_from_in_mask(config->channel_mask);
bool is_low_latency = false;
bool channel_mask_updated = false;
+ bool is_usb_dev = audio_is_usb_in_device(devices);
+ bool may_use_hifi_record = adev_input_allow_hifi_record(adev,
+ devices,
+ flags,
+ source);
*stream_in = NULL;
- if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) {
- ALOGE("%s: invalid input parameters", __func__);
- return -EINVAL;
+
+ if (!(is_usb_dev && may_use_hifi_record)) {
+ if (config->sample_rate == 0)
+ config->sample_rate = 48000;
+ if (config->channel_mask == AUDIO_CHANNEL_NONE)
+ config->channel_mask = AUDIO_CHANNEL_IN_MONO;
+ if (config->format == AUDIO_FORMAT_DEFAULT)
+ config->format = AUDIO_FORMAT_PCM_16_BIT;
+
+ channel_count = audio_channel_count_from_in_mask(config->channel_mask);
+
+ if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0)
+ return -EINVAL;
}
in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
@@ -6069,47 +6591,31 @@
in->source = source;
in->dev = adev;
in->standby = 1;
- in->channel_mask = config->channel_mask;
in->capture_handle = handle;
in->flags = flags;
- in->usecase = USECASE_AUDIO_RECORD;
- if (config->sample_rate == LOW_LATENCY_CAPTURE_SAMPLE_RATE &&
- (flags & AUDIO_INPUT_FLAG_FAST) != 0) {
- is_low_latency = true;
-#if LOW_LATENCY_CAPTURE_USE_CASE
- in->usecase = USECASE_AUDIO_RECORD_LOW_LATENCY;
-#endif
- in->realtime = may_use_noirq_mode(adev, in->usecase, in->flags);
- }
- in->format = config->format;
- if ((config->sample_rate == LOW_LATENCY_CAPTURE_SAMPLE_RATE) &&
- ((in->flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0)) {
- in->realtime = 0;
- in->usecase = USECASE_AUDIO_RECORD_MMAP;
- in->config = pcm_config_mmap_capture;
- in->stream.start = in_start;
- in->stream.stop = in_stop;
- in->stream.create_mmap_buffer = in_create_mmap_buffer;
- in->stream.get_mmap_position = in_get_mmap_position;
- in->af_period_multiplier = 1;
- ALOGV("%s: USECASE_AUDIO_RECORD_MMAP", __func__);
- } else if (in->realtime) {
- in->config = pcm_config_audio_capture_rt;
- in->sample_rate = in->config.rate;
- in->af_period_multiplier = af_period_multiplier;
- } else {
- in->config = pcm_config_audio_capture;
- in->config.rate = config->sample_rate;
- in->sample_rate = config->sample_rate;
- in->af_period_multiplier = 1;
- }
- in->bit_width = 16;
-
/* restrict 24 bit capture for unprocessed source only
* for other sources if 24 bit requested reject 24 and set 16 bit capture only
*/
- if (config->format == AUDIO_FORMAT_DEFAULT) {
+ if (is_usb_dev && may_use_hifi_record) {
+ /* HiFi record selects an appropriate format, channel, rate combo
+ depending on sink capabilities*/
+ ret = read_usb_sup_params_and_compare(false /*is_playback*/,
+ &config->format,
+ &in->supported_formats[0],
+ MAX_SUPPORTED_FORMATS,
+ &config->channel_mask,
+ &in->supported_channel_masks[0],
+ MAX_SUPPORTED_CHANNEL_MASKS,
+ &config->sample_rate,
+ &in->supported_sample_rates[0],
+ MAX_SUPPORTED_SAMPLE_RATES);
+ if (ret != 0) {
+ ret = -EINVAL;
+ goto err_open;
+ }
+ channel_count = audio_channel_count_from_in_mask(config->channel_mask);
+ } else if (config->format == AUDIO_FORMAT_DEFAULT) {
config->format = AUDIO_FORMAT_PCM_16_BIT;
} else if ((config->format == AUDIO_FORMAT_PCM_FLOAT) ||
(config->format == AUDIO_FORMAT_PCM_32_BIT) ||
@@ -6147,6 +6653,42 @@
}
}
+ in->channel_mask = config->channel_mask;
+ in->format = config->format;
+
+ in->usecase = USECASE_AUDIO_RECORD;
+ if (config->sample_rate == LOW_LATENCY_CAPTURE_SAMPLE_RATE &&
+ (flags & AUDIO_INPUT_FLAG_FAST) != 0) {
+ is_low_latency = true;
+#if LOW_LATENCY_CAPTURE_USE_CASE
+ in->usecase = USECASE_AUDIO_RECORD_LOW_LATENCY;
+#endif
+ in->realtime = may_use_noirq_mode(adev, in->usecase, in->flags);
+ }
+
+ if ((config->sample_rate == LOW_LATENCY_CAPTURE_SAMPLE_RATE) &&
+ ((in->flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0)) {
+ in->realtime = 0;
+ in->usecase = USECASE_AUDIO_RECORD_MMAP;
+ in->config = pcm_config_mmap_capture;
+ in->stream.start = in_start;
+ in->stream.stop = in_stop;
+ in->stream.create_mmap_buffer = in_create_mmap_buffer;
+ in->stream.get_mmap_position = in_get_mmap_position;
+ in->af_period_multiplier = 1;
+ ALOGV("%s: USECASE_AUDIO_RECORD_MMAP", __func__);
+ } else if (in->realtime) {
+ in->config = pcm_config_audio_capture_rt;
+ in->sample_rate = in->config.rate;
+ in->af_period_multiplier = af_period_multiplier;
+ } else {
+ in->config = pcm_config_audio_capture;
+ in->config.rate = config->sample_rate;
+ in->sample_rate = config->sample_rate;
+ in->af_period_multiplier = 1;
+ }
+ in->bit_width = 16;
+
/* Update config params with the requested sample rate and channels */
if ((in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) &&
(adev->mode != AUDIO_MODE_IN_CALL)) {
@@ -6154,7 +6696,20 @@
goto err_open;
}
- if ((in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) ||
+ if (is_usb_dev && may_use_hifi_record) {
+ in->usecase = USECASE_AUDIO_RECORD_HIFI;
+ in->config = pcm_config_audio_capture;
+ frame_size = audio_stream_in_frame_size(&in->stream);
+ buffer_size = get_input_buffer_size(config->sample_rate,
+ config->format,
+ channel_count,
+ false /*is_low_latency*/);
+ in->config.period_size = buffer_size / frame_size;
+ in->config.rate = config->sample_rate;
+ in->af_period_multiplier = 1;
+ in->config.format = pcm_format_from_audio_format(config->format);
+ in->config.channels = channel_count;
+ } else if ((in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) ||
(in->device == AUDIO_DEVICE_IN_PROXY)) {
if (config->sample_rate == 0)
config->sample_rate = AFE_PROXY_SAMPLING_RATE;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index fda0672..56ee9d0 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -90,6 +90,19 @@
#define MAX_PERF_LOCK_OPTS 20
#define MAX_STREAM_PROFILE_STR_LEN 32
+typedef enum {
+ EFFECT_NONE = 0,
+ EFFECT_AEC,
+ EFFECT_NS,
+ EFFECT_MAX
+} effect_type_t;
+
+struct audio_effect_config {
+ uint32_t module_id;
+ uint32_t instance_id;
+ uint32_t param_id;
+ uint32_t param_value;
+};
#define MAX_MIXER_PATH_LEN 64
@@ -119,6 +132,7 @@
USECASE_AUDIO_PLAYBACK_OFFLOAD9,
USECASE_AUDIO_PLAYBACK_ULL,
USECASE_AUDIO_PLAYBACK_MMAP,
+ USECASE_AUDIO_PLAYBACK_HIFI,
/* FM usecase */
USECASE_AUDIO_PLAYBACK_FM,
@@ -135,6 +149,7 @@
USECASE_AUDIO_RECORD_COMPRESS4,
USECASE_AUDIO_RECORD_LOW_LATENCY,
USECASE_AUDIO_RECORD_FM_VIRTUAL,
+ USECASE_AUDIO_RECORD_HIFI,
USECASE_AUDIO_PLAYBACK_VOIP,
USECASE_AUDIO_RECORD_VOIP,
@@ -361,6 +376,11 @@
struct audio_device *dev;
card_status_t card_status;
int capture_started;
+
+ /* Array of supported channel mask configurations. +1 so that the last entry is always 0 */
+ audio_channel_mask_t supported_channel_masks[MAX_SUPPORTED_CHANNEL_MASKS + 1];
+ audio_format_t supported_formats[MAX_SUPPORTED_FORMATS + 1];
+ uint32_t supported_sample_rates[MAX_SUPPORTED_SAMPLE_RATES + 1];
};
typedef enum {
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 6dfa0eb..45b02e3 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -165,6 +165,8 @@
#define MAX_CAL_NAME 20
#define MAX_MIME_TYPE_LENGTH 30
+#define GET_IN_DEVICE_INDEX(SND_DEVICE) ((SND_DEVICE) - (SND_DEVICE_IN_BEGIN))
+
char cal_name_info[WCD9XXX_MAX_CAL][MAX_CAL_NAME] = {
[WCD9XXX_ANC_CAL] = "anc_cal",
[WCD9XXX_MBHC_CAL] = "mbhc_cal",
@@ -249,6 +251,7 @@
bool external_spk_1;
bool external_spk_2;
bool external_mic;
+ bool speaker_lr_swap;
int fluence_type;
char fluence_cap[PROPERTY_VALUE_MAX];
int fluence_mode;
@@ -311,6 +314,8 @@
LOWLATENCY_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
MULTIMEDIA2_PCM_DEVICE},
+ [USECASE_AUDIO_PLAYBACK_HIFI] = {MULTIMEDIA2_PCM_DEVICE,
+ MULTIMEDIA2_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_OFFLOAD] =
{PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
/* Below entries are initialized with invalid values
@@ -335,6 +340,8 @@
LOWLATENCY_PCM_DEVICE},
[USECASE_AUDIO_RECORD_FM_VIRTUAL] = {MULTIMEDIA2_PCM_DEVICE,
MULTIMEDIA2_PCM_DEVICE},
+ [USECASE_AUDIO_RECORD_HIFI] = {MULTIMEDIA2_PCM_DEVICE,
+ MULTIMEDIA2_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_FM] = {FM_PLAYBACK_PCM_DEVICE, FM_CAPTURE_PCM_DEVICE},
[USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
[USECASE_AUDIO_HFP_SCO_WB] = {HFP_PCM_RX, HFP_SCO_RX},
@@ -546,6 +553,23 @@
// Platform specific backend bit width table
static int backend_bit_width_table[SND_DEVICE_MAX] = {0};
+static struct audio_effect_config effect_config_table[GET_IN_DEVICE_INDEX(SND_DEVICE_MAX)][EFFECT_MAX] = {
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)][EFFECT_AEC] = {TX_VOICE_FLUENCE_PROV2, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)][EFFECT_NS] = {TX_VOICE_FLUENCE_PROV2, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)][EFFECT_AEC] = {TX_VOICE_DM_FV5_BROADSIDE, 0x0,
+ 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)][EFFECT_NS] = {TX_VOICE_DM_FV5_BROADSIDE, 0x0,
+ 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)][EFFECT_AEC] = {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)][EFFECT_NS] = {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)][EFFECT_AEC] = {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)][EFFECT_NS] = {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)][EFFECT_AEC] = {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)][EFFECT_NS] = {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)][EFFECT_AEC] = {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)][EFFECT_NS] = {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x02},
+};
+
/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
static int acdb_device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_NONE] = -1,
@@ -2881,6 +2905,35 @@
return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
}
+int platform_get_effect_config_data(snd_device_t snd_device,
+ struct audio_effect_config *effect_config,
+ effect_type_t effect_type)
+{
+ int ret = 0;
+
+ if ((snd_device < SND_DEVICE_IN_BEGIN) || (snd_device >= SND_DEVICE_MAX) ||
+ (effect_type <= EFFECT_NONE) || (effect_type >= EFFECT_MAX)) {
+ ALOGE("%s: Invalid snd_device = %d",
+ __func__, snd_device);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (effect_config == NULL) {
+ ALOGE("%s: Invalid effect_config", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ALOGV("%s: snd_device = %d module_id = %d",
+ __func__, snd_device, effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type].module_id);
+ memcpy(effect_config, &effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type],
+ sizeof(struct audio_effect_config));
+
+done:
+ return ret;
+}
+
int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
{
int ret = 0;
@@ -2899,6 +2952,29 @@
return ret;
}
+int platform_set_effect_config_data(snd_device_t snd_device,
+ struct audio_effect_config effect_config,
+ effect_type_t effect_type)
+{
+ int ret = 0;
+
+ if ((snd_device < SND_DEVICE_IN_BEGIN) || (snd_device >= SND_DEVICE_MAX) ||
+ (effect_type <= EFFECT_NONE) || (effect_type >= EFFECT_MAX)) {
+ ALOGE("%s: Invalid snd_device = %d",
+ __func__, snd_device);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ALOGV("%s 0x%x 0x%x 0x%x 0x%x", __func__, effect_config.module_id,
+ effect_config.instance_id, effect_config.param_id,
+ effect_config.param_value);
+ effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type] = effect_config;
+
+done:
+ return ret;
+}
+
int platform_set_acdb_metainfo_key(void *platform, char *name, int key)
{
struct meta_key_list *key_info;
@@ -3993,6 +4069,148 @@
return snd_device;
}
+#ifdef DYNAMIC_ECNS_ENABLED
+static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+ audio_devices_t out_device,
+ audio_devices_t in_device)
+{
+ struct audio_device *adev = my_data->adev;
+ snd_device_t snd_device = SND_DEVICE_NONE;
+
+ if (my_data->fluence_type != FLUENCE_NONE) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ if (my_data->fluence_mode == FLUENCE_BROADSIDE)
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
+ else
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
+ }
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ }
+
+ return snd_device;
+}
+#else
+static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+ audio_devices_t out_device,
+ audio_devices_t in_device)
+{
+ struct audio_device *adev = my_data->adev;
+ snd_device_t snd_device = SND_DEVICE_NONE;
+
+ if (my_data->fluence_type != FLUENCE_NONE && adev->active_input->enable_aec &&
+ adev->active_input->enable_ns) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ if (my_data->fluence_mode == FLUENCE_BROADSIDE)
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
+ else
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
+ }
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
+ } else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
+ snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ } else if (my_data->fluence_type != FLUENCE_NONE &&
+ adev->active_input->enable_aec) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ if (my_data->fluence_mode == FLUENCE_BROADSIDE)
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
+ else
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
+ }
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
+ } else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
+ snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ } else if (my_data->fluence_type != FLUENCE_NONE &&
+ adev->active_input->enable_ns) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ if (my_data->fluence_mode == FLUENCE_BROADSIDE)
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
+ else
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
+ }
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
+ }
+ platform_set_echo_reference(adev, false, out_device);
+ } else
+ platform_set_echo_reference(adev, false, out_device);
+
+ return snd_device;
+}
+#endif //DYNAMIC_ECNS_ENABLED
+
snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
{
struct platform_data *my_data = (struct platform_data *)platform;
@@ -4218,97 +4436,7 @@
if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
in_device = AUDIO_DEVICE_IN_BACK_MIC;
if (adev->active_input) {
- if (my_data->fluence_type != FLUENCE_NONE &&
- adev->active_input->enable_aec &&
- adev->active_input->enable_ns) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_in_spkr_mode) {
- if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
- (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
- snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
- } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- if (my_data->fluence_mode == FLUENCE_BROADSIDE)
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
- else
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
- }
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- } else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
- snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
- }
- platform_set_echo_reference(adev, true, out_device);
- } else if (my_data->fluence_type != FLUENCE_NONE &&
- adev->active_input->enable_aec) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_in_spkr_mode) {
- if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
- (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
- snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
- } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- if (my_data->fluence_mode == FLUENCE_BROADSIDE)
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
- else
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
- }
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- } else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
- snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
- }
- platform_set_echo_reference(adev, true, out_device);
- } else if (my_data->fluence_type != FLUENCE_NONE &&
- adev->active_input->enable_ns) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_in_spkr_mode) {
- if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
- (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
- snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
- } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- if (my_data->fluence_mode == FLUENCE_BROADSIDE)
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
- else
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
- }
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- }
- platform_set_echo_reference(adev, false, out_device);
- } else
- platform_set_echo_reference(adev, false, out_device);
+ snd_device = get_snd_device_for_voice_comm(my_data, out_device, in_device);
}
} else if (source == AUDIO_SOURCE_MIC) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
@@ -6305,12 +6433,7 @@
int iter_i = 0;
int iter_j = 0;
int length = 0;
- int pan_scale_data[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0};
-
- if (sizeof(mm_params) > MAX_LENGTH_MIXER_CONTROL_IN_INT) {
- ret = -EINVAL;
- goto end;
- }
+ char *pan_scale_data = NULL;
snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
"Audio Stream %d Pan Scale Control", snd_id);
@@ -6323,40 +6446,60 @@
ret = -EINVAL;
goto end;
}
- pan_scale_data[length++] = mm_params.num_output_channels;
- pan_scale_data[length++] = mm_params.num_input_channels;
+ pan_scale_data = (char *) calloc(1, sizeof(mm_params));
+ if (!pan_scale_data) {
+ ret = -ENOMEM;
+ goto end;
+ }
+ memcpy(&pan_scale_data[length], &mm_params.num_output_channels,
+ sizeof(mm_params.num_output_channels));
+ length += sizeof(mm_params.num_output_channels);
+ memcpy(&pan_scale_data[length], &mm_params.num_input_channels,
+ sizeof(mm_params.num_input_channels));
+ length += sizeof(mm_params.num_input_channels);
- pan_scale_data[length++] = mm_params.has_output_channel_map;
+ memcpy(&pan_scale_data[length], &mm_params.has_output_channel_map,
+ sizeof(mm_params.has_output_channel_map));
+ length += sizeof(mm_params.has_output_channel_map);
if (mm_params.has_output_channel_map &&
mm_params.num_output_channels <= MAX_CHANNELS_SUPPORTED &&
- mm_params.num_output_channels > 0)
- for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
- pan_scale_data[length++] = mm_params.output_channel_map[iter_i];
- else {
+ mm_params.num_output_channels > 0) {
+ memcpy(&pan_scale_data[length], mm_params.output_channel_map,
+ (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0])));
+ length += (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0]));
+ } else {
ret = -EINVAL;
goto end;
}
- pan_scale_data[length++] = mm_params.has_input_channel_map;
+ memcpy(&pan_scale_data[length], &mm_params.has_input_channel_map,
+ sizeof(mm_params.has_input_channel_map));
+ length += sizeof(mm_params.has_input_channel_map);
if (mm_params.has_input_channel_map &&
mm_params.num_input_channels <= MAX_CHANNELS_SUPPORTED &&
- mm_params.num_input_channels > 0)
- for (iter_i = 0; iter_i < mm_params.num_input_channels; iter_i++)
- pan_scale_data[length++] = mm_params.input_channel_map[iter_i];
- else {
+ mm_params.num_input_channels > 0) {
+ memcpy(&pan_scale_data[length], mm_params.input_channel_map,
+ (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0])));
+ length += (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0]));
+ } else {
ret = -EINVAL;
goto end;
}
-
- pan_scale_data[length++] = mm_params.has_mixer_coeffs;
+ pan_scale_data[length] = mm_params.has_mixer_coeffs;
+ length += sizeof(mm_params.has_mixer_coeffs);
if (mm_params.has_mixer_coeffs)
for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
- for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++)
- pan_scale_data[length++] =
- mm_params.mixer_coeffs[iter_i][iter_j];
+ for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++) {
+ memcpy(&pan_scale_data[length],
+ &mm_params.mixer_coeffs[iter_i][iter_j],
+ (sizeof(mm_params.mixer_coeffs[0][0])));
+ length += (sizeof(mm_params.mixer_coeffs[0][0]));
+ }
ret = mixer_ctl_set_array(ctl, pan_scale_data, length);
end:
+ if (pan_scale_data)
+ free(pan_scale_data);
return ret;
}
@@ -6369,20 +6512,13 @@
struct audio_device *adev = my_data->adev;
struct mixer_ctl *ctl;
char mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
- int downmix_param_data[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0};
+ char *downmix_param_data = NULL;
int ret = 0;
int iter_i = 0;
int iter_j = 0;
int length = 0;
int be_idx = 0;
- if ((sizeof(mm_params) +
- sizeof(be_idx)) >
- MAX_LENGTH_MIXER_CONTROL_IN_INT) {
- ret = -EINVAL;
- goto end;
- }
-
snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
"Audio Device %d Downmix Control", snd_id);
ALOGD("%s mixer_ctl_name:%s", __func__, mixer_ctl_name);
@@ -6392,45 +6528,66 @@
ALOGE("%s: Could not get ctl for mixer cmd - %s",
__func__, mixer_ctl_name);
ret = -EINVAL;
- goto end;
}
+ downmix_param_data = (char *) calloc(1, sizeof(mm_params) + sizeof(be_idx));
+ if (!downmix_param_data) {
+ ret = -ENOMEM;
+ goto end;
+ }
be_idx = platform_get_snd_device_backend_index(snd_device);
- downmix_param_data[length] = be_idx;
- downmix_param_data[length++] = mm_params.num_output_channels;
- downmix_param_data[length++] = mm_params.num_input_channels;
+ memcpy(&downmix_param_data[length], &be_idx, sizeof(be_idx));
+ length += sizeof(be_idx);
+ memcpy(&downmix_param_data[length], &mm_params.num_output_channels,
+ sizeof(mm_params.num_output_channels));
+ length += sizeof(mm_params.num_output_channels);
+ memcpy(&downmix_param_data[length], &mm_params.num_input_channels,
+ sizeof(mm_params.num_input_channels));
+ length += sizeof(mm_params.num_input_channels);
- downmix_param_data[length++] = mm_params.has_output_channel_map;
+ memcpy(&downmix_param_data[length], &mm_params.has_output_channel_map,
+ sizeof(mm_params.has_output_channel_map));
+ length += sizeof(mm_params.has_output_channel_map);
if (mm_params.has_output_channel_map &&
mm_params.num_output_channels <= MAX_CHANNELS_SUPPORTED &&
- mm_params.num_output_channels > 0)
- for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
- downmix_param_data[length++] = mm_params.output_channel_map[iter_i];
- else {
+ mm_params.num_output_channels > 0) {
+ memcpy(&downmix_param_data[length], mm_params.output_channel_map,
+ (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0])));
+ length += (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0]));
+ } else {
ret = -EINVAL;
goto end;
}
- downmix_param_data[length++] = mm_params.has_input_channel_map;
+ memcpy(&downmix_param_data[length], &mm_params.has_input_channel_map,
+ sizeof(mm_params.has_input_channel_map));
+ length += sizeof(mm_params.has_input_channel_map);
if (mm_params.has_input_channel_map &&
mm_params.num_input_channels <= MAX_CHANNELS_SUPPORTED &&
- mm_params.num_input_channels > 0)
- for (iter_i = 0; iter_i < mm_params.num_input_channels; iter_i++)
- downmix_param_data[length++] = mm_params.input_channel_map[iter_i];
- else {
+ mm_params.num_input_channels > 0) {
+ memcpy(&downmix_param_data[length], mm_params.input_channel_map,
+ (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0])));
+ length += (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0]));
+ } else {
ret = -EINVAL;
goto end;
}
-
- downmix_param_data[length++] = mm_params.has_mixer_coeffs;
+ memcpy(&downmix_param_data[length], &mm_params.has_mixer_coeffs,
+ sizeof(mm_params.has_mixer_coeffs));
+ length += sizeof(mm_params.has_mixer_coeffs);
if (mm_params.has_mixer_coeffs)
for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
- for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++)
- downmix_param_data[length++] =
- mm_params.mixer_coeffs[iter_i][iter_j];
+ for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++) {
+ memcpy((uint32_t *) &downmix_param_data[length],
+ &mm_params.mixer_coeffs[iter_i][iter_j],
+ (sizeof(mm_params.mixer_coeffs[0][0])));
+ length += (sizeof(mm_params.mixer_coeffs[0][0]));
+ }
ret = mixer_ctl_set_array(ctl, downmix_param_data, length);
end:
+ if (downmix_param_data)
+ free(downmix_param_data);
return ret;
}
@@ -7171,6 +7328,7 @@
bool ret = false;
if (snd_device == SND_DEVICE_OUT_SPEAKER ||
+ snd_device == SND_DEVICE_OUT_SPEAKER_REVERSE ||
snd_device == SND_DEVICE_OUT_SPEAKER_WSA ||
snd_device == SND_DEVICE_OUT_SPEAKER_VBAT ||
snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT ||
@@ -7492,6 +7650,151 @@
return my_data->max_mic_count;
}
+#define DEFAULT_NOMINAL_SPEAKER_GAIN 20
+int ramp_speaker_gain(struct audio_device *adev, bool ramp_up, int target_ramp_up_gain) {
+ // backup_gain: gain to try to set in case of an error during ramp
+ int start_gain, end_gain, step, backup_gain, i;
+ bool error = false;
+ const char *mixer_ctl_name_gain_left = "Left Speaker Gain";
+ const char *mixer_ctl_name_gain_right = "Right Speaker Gain";
+ struct mixer_ctl *ctl_left = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name_gain_left);
+ struct mixer_ctl *ctl_right = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name_gain_right);
+ if (!ctl_left || !ctl_right) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s or %s, not applying speaker gain ramp",
+ __func__, mixer_ctl_name_gain_left, mixer_ctl_name_gain_right);
+ return -EINVAL;
+ } else if ((mixer_ctl_get_num_values(ctl_left) != 1)
+ || (mixer_ctl_get_num_values(ctl_right) != 1)) {
+ ALOGE("%s: Unexpected num values for mixer cmd - %s or %s, not applying speaker gain ramp",
+ __func__, mixer_ctl_name_gain_left, mixer_ctl_name_gain_right);
+ return -EINVAL;
+ }
+ if (ramp_up) {
+ start_gain = 0;
+ end_gain = target_ramp_up_gain > 0 ? target_ramp_up_gain : DEFAULT_NOMINAL_SPEAKER_GAIN;
+ step = +1;
+ backup_gain = end_gain;
+ } else {
+ // using same gain on left and right
+ const int left_gain = mixer_ctl_get_value(ctl_left, 0);
+ start_gain = left_gain > 0 ? left_gain : DEFAULT_NOMINAL_SPEAKER_GAIN;
+ end_gain = 0;
+ step = -1;
+ backup_gain = start_gain;
+ }
+ for (i = start_gain ; i != (end_gain + step) ; i += step) {
+ if (mixer_ctl_set_value(ctl_left, 0, i)) {
+ ALOGE("%s: error setting %s to %d during gain ramp",
+ __func__, mixer_ctl_name_gain_left, i);
+ error = true;
+ break;
+ }
+ if (mixer_ctl_set_value(ctl_right, 0, i)) {
+ ALOGE("%s: error setting %s to %d during gain ramp",
+ __func__, mixer_ctl_name_gain_right, i);
+ error = true;
+ break;
+ }
+ usleep(1000);
+ }
+ if (error) {
+ // an error occured during the ramp, let's still try to go back to a safe volume
+ if (mixer_ctl_set_value(ctl_left, 0, backup_gain)) {
+ ALOGE("%s: error restoring left gain to %d", __func__, backup_gain);
+ }
+ if (mixer_ctl_set_value(ctl_right, 0, backup_gain)) {
+ ALOGE("%s: error restoring right gain to %d", __func__, backup_gain);
+ }
+ }
+ return start_gain;
+}
+
+int platform_set_swap_mixer(struct audio_device *adev, bool swap_channels)
+{
+ const char *mixer_ctl_name = "Swap channel";
+ struct mixer_ctl *ctl;
+ const char *mixer_path;
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
+
+ // forced to set to swap, but device not rotated ... ignore set
+ if (swap_channels && !my_data->speaker_lr_swap)
+ return 0;
+
+ ALOGV("%s:", __func__);
+
+ if (swap_channels)
+ mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
+ else
+ mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
+
+ audio_route_apply_and_update_path(adev->audio_route, mixer_path);
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+
+ if (mixer_ctl_set_value(ctl, 0, swap_channels) < 0) {
+ ALOGE("%s: Could not set reverse cotrol %d",__func__, swap_channels);
+ return -EINVAL;
+ }
+
+ ALOGV("platfor_force_swap_channel :: Channel orientation ( %s ) ",
+ swap_channels?"R --> L":"L --> R");
+
+ return 0;
+}
+
+int platform_check_and_set_swap_lr_channels(struct audio_device *adev, bool swap_channels)
+{
+ // only update if there is active pcm playback on speaker
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
+
+ my_data->speaker_lr_swap = swap_channels;
+
+ return platform_set_swap_channels(adev, swap_channels);
+}
+
+int platform_set_swap_channels(struct audio_device *adev, bool swap_channels)
+{
+ // only update if there is active pcm playback on speaker
+ struct audio_usecase *usecase;
+ struct listnode *node;
+
+ // do not swap channels in audio modes with concurrent capture and playback
+ // as this may break the echo reference
+ if ((adev->mode == AUDIO_MODE_IN_COMMUNICATION) || (adev->mode == AUDIO_MODE_IN_CALL)) {
+ ALOGV("%s: will not swap due to audio mode %d", __func__, adev->mode);
+ return 0;
+ }
+
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+ if (usecase->type == PCM_PLAYBACK &&
+ usecase->stream.out->devices & 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
+ * enable it with new acdb data.
+ */
+ if (acdb_device_table[SND_DEVICE_OUT_SPEAKER] !=
+ acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE]) {
+ const int initial_skpr_gain = ramp_speaker_gain(adev, false /*ramp_up*/, -1);
+ select_devices(adev, usecase->id);
+ if (initial_skpr_gain != -EINVAL)
+ ramp_speaker_gain(adev, true /*ramp_up*/, initial_skpr_gain);
+
+ } else {
+ platform_set_swap_mixer(adev, swap_channels);
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+
bool platform_add_gain_level_mapping(struct amp_db_and_gain_table *tbl_entry __unused)
{
return false;
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 13247ff..d128d0f 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -299,6 +299,10 @@
#define LOW_LATENCY_CAPTURE_PERIOD_SIZE 240
#define LOW_LATENCY_CAPTURE_USE_CASE 1
+#define HIFI_BUFFER_OUTPUT_PERIOD_SIZE 1920
+#define HIFI_BUFFER_OUTPUT_PERIOD_DURATION 40 /* 40 millisecs */
+#define HIFI_BUFFER_OUTPUT_PERIOD_COUNT 2
+
#define HDMI_MULTI_PERIOD_SIZE 336
#define HDMI_MULTI_PERIOD_COUNT 8
#define HDMI_MULTI_DEFAULT_CHANNEL_COUNT 6
@@ -379,6 +383,11 @@
#define PLATFORM_MAX_MIC_COUNT "input_mic_max_count"
#define PLATFORM_DEFAULT_MIC_COUNT 2
+#define TX_VOICE_FLUENCE_PROV2 0x10F17
+#define TX_VOICE_DM_FV5_BROADSIDE 0x10F18
+#define TX_VOICE_FV5ECNS_SM 0x10F09
+#define TX_VOICE_FV5ECNS_DM 0x10F0A
+
#define LIB_CSD_CLIENT "libcsd-client.so"
/* CSD-CLIENT related functions */
typedef int (*init_t)();
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 61ef223..64dde86 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -140,6 +140,8 @@
#define MAX_CAL_NAME 20
#define MAX_MIME_TYPE_LENGTH 30
+#define GET_IN_DEVICE_INDEX(SND_DEVICE) ((SND_DEVICE) - (SND_DEVICE_IN_BEGIN))
+
#ifdef DYNAMIC_LOG_ENABLED
extern void log_utils_init(void);
extern void log_utils_deinit(void);
@@ -222,6 +224,7 @@
bool external_spk_1;
bool external_spk_2;
bool external_mic;
+ bool speaker_lr_swap;
int fluence_type;
int fluence_mode;
char fluence_cap[PROPERTY_VALUE_MAX];
@@ -281,6 +284,8 @@
MULTIMEDIA3_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
MULTIMEDIA2_PCM_DEVICE},
+ [USECASE_AUDIO_PLAYBACK_HIFI] = {MULTIMEDIA2_PCM_DEVICE,
+ MULTIMEDIA2_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_OFFLOAD] =
{PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
[USECASE_AUDIO_PLAYBACK_OFFLOAD2] =
@@ -310,6 +315,8 @@
LOWLATENCY_PCM_DEVICE},
[USECASE_AUDIO_RECORD_FM_VIRTUAL] = {MULTIMEDIA2_PCM_DEVICE,
MULTIMEDIA2_PCM_DEVICE},
+ [USECASE_AUDIO_RECORD_HIFI] = {MULTIMEDIA2_PCM_DEVICE,
+ MULTIMEDIA2_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_FM] = {FM_PLAYBACK_PCM_DEVICE, FM_CAPTURE_PCM_DEVICE},
[USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
[USECASE_AUDIO_HFP_SCO_WB] = {HFP_PCM_RX, HFP_SCO_RX},
@@ -511,15 +518,32 @@
[SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
[SND_DEVICE_IN_VOICE_REC_TMIC] = "three-mic",
[SND_DEVICE_IN_UNPROCESSED_MIC] = "unprocessed-mic",
- [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = "voice-rec-dmic-ef",
- [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = "three-mic",
- [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = "quad-mic",
- [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = "headset-mic",
+ [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = "unprocessed-stereo-mic",
+ [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = "unprocessed-three-mic",
+ [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = "unprocessed-quad-mic",
+ [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = "unprocessed-headset-mic",
};
// Platform specific backend bit width table
static int backend_bit_width_table[SND_DEVICE_MAX] = {0};
+static struct audio_effect_config effect_config_table[GET_IN_DEVICE_INDEX(SND_DEVICE_MAX)][EFFECT_MAX] = {
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)][EFFECT_AEC] = {TX_VOICE_FLUENCE_PROV2, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)][EFFECT_NS] = {TX_VOICE_FLUENCE_PROV2, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)][EFFECT_AEC] = {TX_VOICE_DM_FV5_BROADSIDE, 0x0,
+ 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)][EFFECT_NS] = {TX_VOICE_DM_FV5_BROADSIDE, 0x0,
+ 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)][EFFECT_AEC] = {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)][EFFECT_NS] = {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)][EFFECT_AEC] = {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)][EFFECT_NS] = {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)][EFFECT_AEC] = {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)][EFFECT_NS] = {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)][EFFECT_AEC] = {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x01},
+ [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)][EFFECT_NS] = {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x02},
+};
+
/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
static int acdb_device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_NONE] = -1,
@@ -2642,6 +2666,35 @@
return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
}
+int platform_get_effect_config_data(snd_device_t snd_device,
+ struct audio_effect_config *effect_config,
+ effect_type_t effect_type)
+{
+ int ret = 0;
+
+ if ((snd_device < SND_DEVICE_IN_BEGIN) || (snd_device >= SND_DEVICE_MAX) ||
+ (effect_type <= EFFECT_NONE) || (effect_type >= EFFECT_MAX)) {
+ ALOGE("%s: Invalid snd_device = %d",
+ __func__, snd_device);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if(effect_config == NULL) {
+ ALOGE("%s: Invalid effect_config", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ALOGV("%s: snd_device = %d module_id = %d",
+ __func__, snd_device, effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type].module_id);
+ memcpy(effect_config, &effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type],
+ sizeof(struct audio_effect_config));
+
+done:
+ return ret;
+}
+
int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
{
int ret = 0;
@@ -2660,6 +2713,29 @@
return ret;
}
+int platform_set_effect_config_data(snd_device_t snd_device,
+ struct audio_effect_config effect_config,
+ effect_type_t effect_type)
+{
+ int ret = 0;
+
+ if ((snd_device < SND_DEVICE_IN_BEGIN) || (snd_device >= SND_DEVICE_MAX) ||
+ (effect_type <= EFFECT_NONE) || (effect_type >= EFFECT_MAX)) {
+ ALOGE("%s: Invalid snd_device = %d",
+ __func__, snd_device);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ALOGV("%s 0x%x 0x%x 0x%x 0x%x", __func__, effect_config.module_id,
+ effect_config.instance_id, effect_config.param_id,
+ effect_config.param_value);
+ effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type] = effect_config;
+
+done:
+ return ret;
+}
+
int platform_set_acdb_metainfo_key(void *platform, char *name, int key)
{
struct meta_key_list *key_info;
@@ -3726,6 +3802,148 @@
return snd_device;
}
+#ifdef DYNAMIC_ECNS_ENABLED
+static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+ audio_devices_t out_device,
+ audio_devices_t in_device)
+{
+ struct audio_device *adev = my_data->adev;
+ snd_device_t snd_device = SND_DEVICE_NONE;
+
+ if (my_data->fluence_type != FLUENCE_NONE) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ if (my_data->fluence_mode == FLUENCE_BROADSIDE)
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
+ else
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
+ }
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ }
+
+ return snd_device;
+}
+#else
+static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+ audio_devices_t out_device,
+ audio_devices_t in_device)
+{
+ struct audio_device *adev = my_data->adev;
+ snd_device_t snd_device = SND_DEVICE_NONE;
+
+ if (my_data->fluence_type != FLUENCE_NONE && adev->active_input->enable_aec &&
+ adev->active_input->enable_ns) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ if (my_data->fluence_mode == FLUENCE_BROADSIDE)
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
+ else
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
+ }
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
+ } else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
+ snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ } else if (my_data->fluence_type != FLUENCE_NONE &&
+ adev->active_input->enable_aec) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ if (my_data->fluence_mode == FLUENCE_BROADSIDE)
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
+ else
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
+ }
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
+ } else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
+ snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ } else if (my_data->fluence_type != FLUENCE_NONE &&
+ adev->active_input->enable_ns) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_in_spkr_mode) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ if (my_data->fluence_mode == FLUENCE_BROADSIDE)
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
+ else
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
+ }
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
+ }
+ platform_set_echo_reference(adev, false, out_device);
+ } else
+ platform_set_echo_reference(adev, false, out_device);
+
+ return snd_device;
+}
+#endif //DYNAMIC_ECNS_ENABLED
+
snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
{
struct platform_data *my_data = (struct platform_data *)platform;
@@ -3965,97 +4183,7 @@
if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
in_device = AUDIO_DEVICE_IN_BACK_MIC;
if (adev->active_input) {
- if (my_data->fluence_type != FLUENCE_NONE &&
- adev->active_input->enable_aec &&
- adev->active_input->enable_ns) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_in_spkr_mode) {
- if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
- (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
- snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
- } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- if (my_data->fluence_mode == FLUENCE_BROADSIDE)
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
- else
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
- }
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- } else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
- snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
- }
- platform_set_echo_reference(adev, true, out_device);
- } else if (my_data->fluence_type != FLUENCE_NONE &&
- adev->active_input->enable_aec) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_in_spkr_mode) {
- if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
- (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
- snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
- } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- if (my_data->fluence_mode == FLUENCE_BROADSIDE)
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
- else
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
- }
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- } else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
- snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
- }
- platform_set_echo_reference(adev, true, out_device);
- } else if (my_data->fluence_type != FLUENCE_NONE &&
- adev->active_input->enable_ns) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_in_spkr_mode) {
- if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
- (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
- snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
- } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- if (my_data->fluence_mode == FLUENCE_BROADSIDE)
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
- else
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
- }
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- }
- platform_set_echo_reference(adev, false, out_device);
- } else
- platform_set_echo_reference(adev, false, out_device);
+ snd_device = get_snd_device_for_voice_comm(my_data, out_device, in_device);
}
} else if (source == AUDIO_SOURCE_MIC) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
@@ -6123,7 +6251,7 @@
int iter_i = 0;
int iter_j = 0;
int length = 0;
- int *pan_scale_data = NULL;
+ char *pan_scale_data = NULL;
snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
"Audio Stream %d Pan Scale Control", snd_id);
@@ -6136,41 +6264,55 @@
ret = -EINVAL;
goto end;
}
- pan_scale_data = (int* ) calloc(1, sizeof(mm_params));
+ pan_scale_data = (char *) calloc(1, sizeof(mm_params));
if (!pan_scale_data) {
ret = -ENOMEM;
goto end;
}
- pan_scale_data[length++] = mm_params.num_output_channels;
- pan_scale_data[length++] = mm_params.num_input_channels;
+ memcpy(&pan_scale_data[length], &mm_params.num_output_channels,
+ sizeof(mm_params.num_output_channels));
+ length += sizeof(mm_params.num_output_channels);
+ memcpy(&pan_scale_data[length], &mm_params.num_input_channels,
+ sizeof(mm_params.num_input_channels));
+ length += sizeof(mm_params.num_input_channels);
- pan_scale_data[length++] = mm_params.has_output_channel_map;
+ memcpy(&pan_scale_data[length], &mm_params.has_output_channel_map,
+ sizeof(mm_params.has_output_channel_map));
+ length += sizeof(mm_params.has_output_channel_map);
if (mm_params.has_output_channel_map &&
mm_params.num_output_channels <= MAX_CHANNELS_SUPPORTED &&
- mm_params.num_output_channels > 0)
- for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
- pan_scale_data[length++] = mm_params.output_channel_map[iter_i];
- else {
+ mm_params.num_output_channels > 0) {
+ memcpy(&pan_scale_data[length], mm_params.output_channel_map,
+ (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0])));
+ length += (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0]));
+ } else {
ret = -EINVAL;
goto end;
}
- pan_scale_data[length++] = mm_params.has_input_channel_map;
+ memcpy(&pan_scale_data[length], &mm_params.has_input_channel_map,
+ sizeof(mm_params.has_input_channel_map));
+ length += sizeof(mm_params.has_input_channel_map);
if (mm_params.has_input_channel_map &&
mm_params.num_input_channels <= MAX_CHANNELS_SUPPORTED &&
- mm_params.num_input_channels > 0)
- for (iter_i = 0; iter_i < mm_params.num_input_channels; iter_i++)
- pan_scale_data[length++] = mm_params.input_channel_map[iter_i];
- else {
+ mm_params.num_input_channels > 0) {
+ memcpy(&pan_scale_data[length], mm_params.input_channel_map,
+ (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0])));
+ length += (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0]));
+ } else {
ret = -EINVAL;
goto end;
}
- pan_scale_data[length++] = mm_params.has_mixer_coeffs;
+ pan_scale_data[length] = mm_params.has_mixer_coeffs;
+ length += sizeof(mm_params.has_mixer_coeffs);
if (mm_params.has_mixer_coeffs)
for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
- for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++)
- pan_scale_data[length++] =
- mm_params.mixer_coeffs[iter_i][iter_j];
+ for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++) {
+ memcpy(&pan_scale_data[length],
+ &mm_params.mixer_coeffs[iter_i][iter_j],
+ (sizeof(mm_params.mixer_coeffs[0][0])));
+ length += (sizeof(mm_params.mixer_coeffs[0][0]));
+ }
ret = mixer_ctl_set_array(ctl, pan_scale_data, length);
end:
@@ -6188,7 +6330,7 @@
struct audio_device *adev = my_data->adev;
struct mixer_ctl *ctl;
char mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
- int *downmix_param_data = NULL;
+ char *downmix_param_data = NULL;
int ret = 0;
int iter_i = 0;
int iter_j = 0;
@@ -6206,44 +6348,59 @@
ret = -EINVAL;
}
- downmix_param_data = (int* ) calloc(1, sizeof(mm_params) + sizeof(be_idx));
+ downmix_param_data = (char *) calloc(1, sizeof(mm_params) + sizeof(be_idx));
if (!downmix_param_data) {
ret = -ENOMEM;
goto end;
}
be_idx = platform_get_snd_device_backend_index(snd_device);
- downmix_param_data[length++] = be_idx;
- downmix_param_data[length++] = mm_params.num_output_channels;
- downmix_param_data[length++] = mm_params.num_input_channels;
+ memcpy(&downmix_param_data[length], &be_idx, sizeof(be_idx));
+ length += sizeof(be_idx);
+ memcpy(&downmix_param_data[length], &mm_params.num_output_channels,
+ sizeof(mm_params.num_output_channels));
+ length += sizeof(mm_params.num_output_channels);
+ memcpy(&downmix_param_data[length], &mm_params.num_input_channels,
+ sizeof(mm_params.num_input_channels));
+ length += sizeof(mm_params.num_input_channels);
- downmix_param_data[length++] = mm_params.has_output_channel_map;
+ memcpy(&downmix_param_data[length], &mm_params.has_output_channel_map,
+ sizeof(mm_params.has_output_channel_map));
+ length += sizeof(mm_params.has_output_channel_map);
if (mm_params.has_output_channel_map &&
mm_params.num_output_channels <= MAX_CHANNELS_SUPPORTED &&
- mm_params.num_output_channels > 0)
- for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
- downmix_param_data[length++] = mm_params.output_channel_map[iter_i];
- else {
+ mm_params.num_output_channels > 0) {
+ memcpy(&downmix_param_data[length], mm_params.output_channel_map,
+ (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0])));
+ length += (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0]));
+ } else {
ret = -EINVAL;
goto end;
}
- downmix_param_data[length++] = mm_params.has_input_channel_map;
+ memcpy(&downmix_param_data[length], &mm_params.has_input_channel_map,
+ sizeof(mm_params.has_input_channel_map));
+ length += sizeof(mm_params.has_input_channel_map);
if (mm_params.has_input_channel_map &&
mm_params.num_input_channels <= MAX_CHANNELS_SUPPORTED &&
- mm_params.num_input_channels > 0)
- for (iter_i = 0; iter_i < mm_params.num_input_channels; iter_i++)
- downmix_param_data[length++] = mm_params.input_channel_map[iter_i];
- else {
+ mm_params.num_input_channels > 0) {
+ memcpy(&downmix_param_data[length], mm_params.input_channel_map,
+ (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0])));
+ length += (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0]));
+ } else {
ret = -EINVAL;
goto end;
}
-
- downmix_param_data[length++] = mm_params.has_mixer_coeffs;
+ memcpy(&downmix_param_data[length], &mm_params.has_mixer_coeffs,
+ sizeof(mm_params.has_mixer_coeffs));
+ length += sizeof(mm_params.has_mixer_coeffs);
if (mm_params.has_mixer_coeffs)
for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
- for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++)
- downmix_param_data[length++] =
- mm_params.mixer_coeffs[iter_i][iter_j];
+ for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++) {
+ memcpy((uint32_t *) &downmix_param_data[length],
+ &mm_params.mixer_coeffs[iter_i][iter_j],
+ (sizeof(mm_params.mixer_coeffs[0][0])));
+ length += (sizeof(mm_params.mixer_coeffs[0][0]));
+ }
ret = mixer_ctl_set_array(ctl, downmix_param_data, length);
end:
@@ -6836,6 +6993,7 @@
bool ret = false;
if (snd_device == SND_DEVICE_OUT_SPEAKER ||
+ snd_device == SND_DEVICE_OUT_SPEAKER_REVERSE ||
snd_device == SND_DEVICE_OUT_SPEAKER_VBAT ||
snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT ||
snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_2_VBAT ||
@@ -7191,6 +7349,151 @@
return my_data->max_mic_count;
}
+#define DEFAULT_NOMINAL_SPEAKER_GAIN 20
+int ramp_speaker_gain(struct audio_device *adev, bool ramp_up, int target_ramp_up_gain) {
+ // backup_gain: gain to try to set in case of an error during ramp
+ int start_gain, end_gain, step, backup_gain, i;
+ bool error = false;
+ const char *mixer_ctl_name_gain_left = "Left Speaker Gain";
+ const char *mixer_ctl_name_gain_right = "Right Speaker Gain";
+ struct mixer_ctl *ctl_left = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name_gain_left);
+ struct mixer_ctl *ctl_right = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name_gain_right);
+ if (!ctl_left || !ctl_right) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s or %s, not applying speaker gain ramp",
+ __func__, mixer_ctl_name_gain_left, mixer_ctl_name_gain_right);
+ return -EINVAL;
+ } else if ((mixer_ctl_get_num_values(ctl_left) != 1)
+ || (mixer_ctl_get_num_values(ctl_right) != 1)) {
+ ALOGE("%s: Unexpected num values for mixer cmd - %s or %s, not applying speaker gain ramp",
+ __func__, mixer_ctl_name_gain_left, mixer_ctl_name_gain_right);
+ return -EINVAL;
+ }
+ if (ramp_up) {
+ start_gain = 0;
+ end_gain = target_ramp_up_gain > 0 ? target_ramp_up_gain : DEFAULT_NOMINAL_SPEAKER_GAIN;
+ step = +1;
+ backup_gain = end_gain;
+ } else {
+ // using same gain on left and right
+ const int left_gain = mixer_ctl_get_value(ctl_left, 0);
+ start_gain = left_gain > 0 ? left_gain : DEFAULT_NOMINAL_SPEAKER_GAIN;
+ end_gain = 0;
+ step = -1;
+ backup_gain = start_gain;
+ }
+ for (i = start_gain ; i != (end_gain + step) ; i += step) {
+ if (mixer_ctl_set_value(ctl_left, 0, i)) {
+ ALOGE("%s: error setting %s to %d during gain ramp",
+ __func__, mixer_ctl_name_gain_left, i);
+ error = true;
+ break;
+ }
+ if (mixer_ctl_set_value(ctl_right, 0, i)) {
+ ALOGE("%s: error setting %s to %d during gain ramp",
+ __func__, mixer_ctl_name_gain_right, i);
+ error = true;
+ break;
+ }
+ usleep(1000);
+ }
+ if (error) {
+ // an error occured during the ramp, let's still try to go back to a safe volume
+ if (mixer_ctl_set_value(ctl_left, 0, backup_gain)) {
+ ALOGE("%s: error restoring left gain to %d", __func__, backup_gain);
+ }
+ if (mixer_ctl_set_value(ctl_right, 0, backup_gain)) {
+ ALOGE("%s: error restoring right gain to %d", __func__, backup_gain);
+ }
+ }
+ return start_gain;
+}
+
+int platform_set_swap_mixer(struct audio_device *adev, bool swap_channels)
+{
+ const char *mixer_ctl_name = "Swap channel";
+ struct mixer_ctl *ctl;
+ const char *mixer_path;
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
+
+ // forced to set to swap, but device not rotated ... ignore set
+ if (swap_channels && !my_data->speaker_lr_swap)
+ return 0;
+
+ ALOGV("%s:", __func__);
+
+ if (swap_channels)
+ mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
+ else
+ mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
+
+ audio_route_apply_and_update_path(adev->audio_route, mixer_path);
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+
+ if (mixer_ctl_set_value(ctl, 0, swap_channels) < 0) {
+ ALOGE("%s: Could not set reverse cotrol %d",__func__, swap_channels);
+ return -EINVAL;
+ }
+
+ ALOGV("platfor_force_swap_channel :: Channel orientation ( %s ) ",
+ swap_channels?"R --> L":"L --> R");
+
+ return 0;
+}
+
+int platform_check_and_set_swap_lr_channels(struct audio_device *adev, bool swap_channels)
+{
+ // only update if there is active pcm playback on speaker
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
+
+ my_data->speaker_lr_swap = swap_channels;
+
+ return platform_set_swap_channels(adev, swap_channels);
+}
+
+int platform_set_swap_channels(struct audio_device *adev, bool swap_channels)
+{
+ // only update if there is active pcm playback on speaker
+ struct audio_usecase *usecase;
+ struct listnode *node;
+
+ // do not swap channels in audio modes with concurrent capture and playback
+ // as this may break the echo reference
+ if ((adev->mode == AUDIO_MODE_IN_COMMUNICATION) || (adev->mode == AUDIO_MODE_IN_CALL)) {
+ ALOGV("%s: will not swap due to audio mode %d", __func__, adev->mode);
+ return 0;
+ }
+
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+ if (usecase->type == PCM_PLAYBACK &&
+ usecase->stream.out->devices & 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
+ * enable it with new acdb data.
+ */
+ if (acdb_device_table[SND_DEVICE_OUT_SPEAKER] !=
+ acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE]) {
+ const int initial_skpr_gain = ramp_speaker_gain(adev, false /*ramp_up*/, -1);
+ select_devices(adev, usecase->id);
+ if (initial_skpr_gain != -EINVAL)
+ ramp_speaker_gain(adev, true /*ramp_up*/, initial_skpr_gain);
+
+ } else {
+ platform_set_swap_mixer(adev, swap_channels);
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+
static struct amp_db_and_gain_table tbl_mapping[MAX_VOLUME_CAL_STEPS];
static int num_gain_tbl_entry = 0;
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index ba1a195..387ef25 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -302,6 +302,9 @@
#define HDMI_MULTI_DEFAULT_CHANNEL_COUNT 6
#define HDMI_MULTI_PERIOD_BYTES (HDMI_MULTI_PERIOD_SIZE * HDMI_MULTI_DEFAULT_CHANNEL_COUNT * 2)
+#define HIFI_BUFFER_OUTPUT_PERIOD_SIZE 1920
+#define HIFI_BUFFER_OUTPUT_PERIOD_DURATION 40 /* 40 milisecs */
+#define HIFI_BUFFER_OUTPUT_PERIOD_COUNT 2
/* Used in calculating fragment size for pcm offload */
#define PCM_OFFLOAD_BUFFER_DURATION 80 /* 80 millisecs */
@@ -497,6 +500,11 @@
#define PLATFORM_MAX_MIC_COUNT "input_mic_max_count"
#define PLATFORM_DEFAULT_MIC_COUNT 2
+#define TX_VOICE_FLUENCE_PROV2 0x10F17
+#define TX_VOICE_DM_FV5_BROADSIDE 0x10F18
+#define TX_VOICE_FV5ECNS_SM 0x10F09
+#define TX_VOICE_FV5ECNS_DM 0x10F0A
+
#define LIB_CSD_CLIENT "libcsd-client.so"
/* CSD-CLIENT related functions */
typedef int (*init_t)(bool);
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 924c1a4..4407d2c 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -100,6 +100,12 @@
int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id);
int platform_get_snd_device_acdb_id(snd_device_t snd_device);
int platform_set_snd_device_bit_width(snd_device_t snd_device, unsigned int bit_width);
+int platform_set_effect_config_data(snd_device_t snd_device,
+ struct audio_effect_config effect_config,
+ effect_type_t effect_type);
+int platform_get_effect_config_data(snd_device_t snd_device,
+ struct audio_effect_config *effect_config,
+ effect_type_t effect_type);
int platform_get_snd_device_bit_width(snd_device_t snd_device);
int platform_set_acdb_metainfo_key(void *platform, char *name, int key);
int platform_get_meta_info_key_from_list(void *platform, char *mod_name);
@@ -172,6 +178,8 @@
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);
+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);
int platform_set_channel_allocation(void *platform, int channel_alloc);
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 597d1f7..5140911 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -52,6 +52,9 @@
typedef enum {
ROOT,
ACDB,
+ MODULE,
+ AEC,
+ NS,
BITWIDTH,
PCM_ID,
BACKEND_NAME,
@@ -64,6 +67,9 @@
typedef void (* section_process_fn)(const XML_Char **attr);
static void process_acdb_id(const XML_Char **attr);
+static void process_audio_effect(const XML_Char **attr, effect_type_t effect_type);
+static void process_effect_aec(const XML_Char **attr);
+static void process_effect_ns(const XML_Char **attr);
static void process_bit_width(const XML_Char **attr);
static void process_pcm_id(const XML_Char **attr);
static void process_backend_name(const XML_Char **attr);
@@ -76,6 +82,8 @@
static section_process_fn section_table[] = {
[ROOT] = process_root,
[ACDB] = process_acdb_id,
+ [AEC] = process_effect_aec,
+ [NS] = process_effect_ns,
[BITWIDTH] = process_bit_width,
[PCM_ID] = process_pcm_id,
[BACKEND_NAME] = process_backend_name,
@@ -102,6 +110,11 @@
* ...
* ...
* </acdb_ids>
+ * <module_ids>
+ * <device name="???" module_id="???"/>
+ * ...
+ * ...
+ * </module_ids>
* <backend_names>
* <device name="???" backend="???"/>
* ...
@@ -279,6 +292,77 @@
return;
}
+static void process_audio_effect(const XML_Char **attr, effect_type_t effect_type)
+{
+ int index;
+ struct audio_effect_config effect_config;
+
+ if (strcmp(attr[0], "name") != 0) {
+ ALOGE("%s: 'name' not found, no MODULE ID set!", __func__);
+ goto done;
+ }
+
+ index = platform_get_snd_device_index((char *)attr[1]);
+ if (index < 0) {
+ ALOGE("%s: Device %s in platform info xml not found, no MODULE ID set!",
+ __func__, attr[1]);
+ goto done;
+ }
+
+ if (strcmp(attr[2], "module_id") != 0) {
+ ALOGE("%s: Device %s in platform info xml has no module_id, no MODULE ID set!",
+ __func__, attr[2]);
+ goto done;
+ }
+
+ if (strcmp(attr[4], "instance_id") != 0) {
+ ALOGE("%s: Device %s in platform info xml has no instance_id, no INSTANCE ID set!",
+ __func__, attr[4]);
+ goto done;
+ }
+
+ if (strcmp(attr[6], "param_id") != 0) {
+ ALOGE("%s: Device %s in platform info xml has no param_id, no PARAM ID set!",
+ __func__, attr[6]);
+ goto done;
+ }
+
+ if (strcmp(attr[8], "param_value") != 0) {
+ ALOGE("%s: Device %s in platform info xml has no param_value, no PARAM VALUE set!",
+ __func__, attr[8]);
+ goto done;
+ }
+
+ effect_config = (struct audio_effect_config){strtol((char *)attr[3], NULL, 0),
+ strtol((char *)attr[5], NULL, 0),
+ strtol((char *)attr[7], NULL, 0),
+ strtol((char *)attr[9], NULL, 0)};
+
+
+ if (platform_set_effect_config_data(index, effect_config, effect_type) < 0) {
+ ALOGE("%s: Effect = %d Device %s, MODULE/INSTANCE/PARAM ID %lu %lu %lu %lu was not set!",
+ __func__, effect_type, attr[1], strtol((char *)attr[3], NULL, 0),
+ strtol((char *)attr[5], NULL, 0), strtol((char *)attr[7], NULL, 0),
+ strtol((char *)attr[9], NULL, 0));
+ goto done;
+ }
+
+done:
+ return;
+}
+
+static void process_effect_aec(const XML_Char **attr)
+{
+ process_audio_effect(attr, EFFECT_AEC);
+ return;
+}
+
+static void process_effect_ns(const XML_Char **attr)
+{
+ process_audio_effect(attr, EFFECT_NS);
+ return;
+}
+
static void process_bit_width(const XML_Char **attr)
{
int index;
@@ -418,6 +502,8 @@
section = BITWIDTH;
} else if (strcmp(tag_name, "acdb_ids") == 0) {
section = ACDB;
+ } else if (strcmp(tag_name, "module_ids") == 0) {
+ section = MODULE;
} else if (strcmp(tag_name, "pcm_ids") == 0) {
section = PCM_ID;
} else if (strcmp(tag_name, "backend_names") == 0) {
@@ -431,7 +517,8 @@
} else if(strcmp(tag_name, "acdb_metainfo_key") == 0) {
section = ACDB_METAINFO_KEY;
} else if (strcmp(tag_name, "device") == 0) {
- if ((section != ACDB) && (section != BACKEND_NAME) && (section != BITWIDTH) &&
+ if ((section != ACDB) && (section != AEC) && (section != NS) &&
+ (section != BACKEND_NAME) && (section != BITWIDTH) &&
(section != INTERFACE_NAME)) {
ALOGE("device tag only supported for acdb/backend names/bitwitdh/interface names");
return;
@@ -465,6 +552,20 @@
section_process_fn fn = section_table[section];
fn(attr);
}
+ else if (strcmp(tag_name, "aec") == 0) {
+ if (section != MODULE) {
+ ALOGE("aec tag only supported with MODULE section");
+ return;
+ }
+ section = AEC;
+ }
+ else if (strcmp(tag_name, "ns") == 0) {
+ if (section != MODULE) {
+ ALOGE("ns tag only supported with MODULE section");
+ return;
+ }
+ section = NS;
+ }
} else {
ALOGE("%s: unknown caller!", __func__);
}
@@ -477,6 +578,12 @@
section = ROOT;
} else if (strcmp(tag_name, "acdb_ids") == 0) {
section = ROOT;
+ } else if (strcmp(tag_name, "module_ids") == 0) {
+ section = ROOT;
+ } else if (strcmp(tag_name, "aec") == 0) {
+ section = MODULE;
+ } else if (strcmp(tag_name, "ns") == 0) {
+ section = MODULE;
} else if (strcmp(tag_name, "pcm_ids") == 0) {
section = ROOT;
} else if (strcmp(tag_name, "backend_names") == 0) {
diff --git a/hal/voice.c b/hal/voice.c
index 5a3ff33..b3645be 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -221,6 +221,13 @@
uc_info->in_snd_device = SND_DEVICE_NONE;
uc_info->out_snd_device = SND_DEVICE_NONE;
+ if (audio_is_bluetooth_sco_device(uc_info->devices) && !adev->bt_sco_on) {
+ ALOGE("start_call: couldn't find BT SCO, SCO is not ready");
+ adev->voice.in_call = false;
+ ret = -EIO;
+ goto error_start_voice;
+ }
+
list_add_tail(&adev->usecase_list, &uc_info->list);
select_devices(adev, usecase_id);
diff --git a/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h b/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h
index 374611a..6041ffe 100644
--- a/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h
+++ b/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h
@@ -53,6 +53,7 @@
#include "QOMX_AudioIndexExtensions.h"
#include "OMX_Core.h"
#include "OMX_Audio.h"
+#include "OMX_IndexExt.h"
#include "aenc_svr.h"
#include "qc_omx_component.h"
#include "Map.h"
diff --git a/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp b/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp
index ca6bb6e..51b2056 100644
--- a/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp
+++ b/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp
@@ -45,6 +45,14 @@
#define SLEEP_MS 100
+static const OMX_U32 supported_profiles[] = {
+ OMX_AUDIO_AACObjectLC,
+ OMX_AUDIO_AACObjectHE,
+ OMX_AUDIO_AACObjectHE_PS,
+};
+
+static const int num_profiles = sizeof(supported_profiles) / sizeof(supported_profiles[0]);
+
// omx_cmd_queue destructor
omx_aac_aenc::omx_cmd_queue::~omx_cmd_queue()
{
@@ -2777,6 +2785,25 @@
break;
}
+ case OMX_IndexParamAudioProfileQuerySupported:
+ {
+ DEBUG_PRINT("OMX_IndexParamAudioProfileQuerySupported");
+ OMX_AUDIO_PARAM_ANDROID_PROFILETYPE *profileParams =
+ (OMX_AUDIO_PARAM_ANDROID_PROFILETYPE *)paramData;
+
+ if (profileParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (profileParams->nProfileIndex >= num_profiles) {
+ return OMX_ErrorNoMore;
+ }
+
+ profileParams->eProfile =
+ supported_profiles[profileParams->nProfileIndex];
+
+ return OMX_ErrorNone;
+ }
default:
{
DEBUG_PRINT_ERROR("unknown param %08x\n", paramIndex);
diff --git a/qahw_api/inc/qahw_defs.h b/qahw_api/inc/qahw_defs.h
index c13a1a4..a301bf9 100644
--- a/qahw_api/inc/qahw_defs.h
+++ b/qahw_api/inc/qahw_defs.h
@@ -347,9 +347,9 @@
uint16_t num_output_channels;
uint16_t num_input_channels;
uint8_t has_output_channel_map;
- uint32_t output_channel_map[AUDIO_CHANNEL_COUNT_MAX];
+ uint16_t output_channel_map[AUDIO_CHANNEL_COUNT_MAX];
uint8_t has_input_channel_map;
- uint32_t input_channel_map[AUDIO_CHANNEL_COUNT_MAX];
+ uint16_t input_channel_map[AUDIO_CHANNEL_COUNT_MAX];
uint8_t has_mixer_coeffs;
float mixer_coeffs[AUDIO_CHANNEL_COUNT_MAX][AUDIO_CHANNEL_COUNT_MAX];
} qahw_mix_matrix_params_t;
diff --git a/qahw_api/test/qahw_playback_test.c b/qahw_api/test/qahw_playback_test.c
index 1338591..fc55f83 100644
--- a/qahw_api/test/qahw_playback_test.c
+++ b/qahw_api/test/qahw_playback_test.c
@@ -162,7 +162,7 @@
#endif
#ifndef AUDIO_OUTPUT_FLAG_INTERACTIVE
-#define AUDIO_OUTPUT_FLAG_INTERACTIVE 0x80000000
+#define AUDIO_OUTPUT_FLAG_INTERACTIVE 0x4000000
#endif
static bool request_wake_lock(bool wakelock_acquired, bool enable)
@@ -1830,7 +1830,7 @@
return channel_type;
}
-int extract_channel_mapping(uint32_t *channel_map, const char * arg_string){
+int extract_channel_mapping(uint16_t *channel_map, const char * arg_string){
char *token_string = NULL;
char *init_ptr = NULL;
diff --git a/qahw_api/test/qap_wrapper_extn.c b/qahw_api/test/qap_wrapper_extn.c
index 4c35711..d9f27d4 100644
--- a/qahw_api/test/qap_wrapper_extn.c
+++ b/qahw_api/test/qap_wrapper_extn.c
@@ -62,6 +62,7 @@
#define DEFAULT_SAMPLE_RATE 48000
#define MAX_QAP_MODULE_OUT 3
+extern bool stop_playback;
bool is_media_fmt_changed[MAX_QAP_MODULE_OUT];
int new_output_conf_index = 0;
@@ -1491,9 +1492,12 @@
buffer->common_params.offset = 0;
buffer->common_params.size = bytes_read;
memcpy(buffer->common_params.data, data_buf, bytes_read);
- if (bytes_read <= 0) {
+ if (bytes_read <= 0 || stop_playback) {
buffer->buffer_parms.input_buf_params.flags = QAP_BUFFER_EOS;
bytes_consumed = qap_module_process(qap_module_handle, buffer);
+ if (stop_playback)
+ qap_module_cmd(qap_module_handle, QAP_MODULE_CMD_FLUSH, sizeof(QAP_MODULE_CMD_FLUSH), NULL, NULL, NULL);
+
ret = qap_module_cmd(qap_module_handle, QAP_MODULE_CMD_STOP, sizeof(QAP_MODULE_CMD_STOP), NULL, NULL, NULL);
fprintf(stdout, "Stopped feeding input %s : %p\n", stream_info->filename, fp_input);
ALOGV("Stopped feeding input %s : %p", stream_info->filename, fp_input);
@@ -1546,7 +1550,7 @@
}
}
}
- } while (buffer->common_params.size > 0);
+ } while (buffer->common_params.size > 0 && !stop_playback);
if (reply_data)
free(reply_data);
buffer->common_params.data = temp_ptr;