Promotion of audio-userspace.lnx.2.1-00010.
CRs Change ID Subject
--------------------------------------------------------------------------------------------------------------
1038106 I07f7a12f07f6fedfd65e1d456e7c57e9ed819d3e hal: limit AFE sample rate at 48Khz for non-44.1-support
1037083 I363b5e76fde1d170641bfd778823953fb09b0ad2 msmcobalt: Add support for split a2dp
1037083 I5d710fda1a8d8fa3b5d85aaa2b3096cff8fd7ce5 audio: Add support to enable split A2DP
1033873 I735277d21dbdde7117eb7a4f765993e23cdea45c hal: allow VOIP standby to enable correct device for sub
1033873 I19419a44e509e27be41ce06c36ca14592f7b09c1 hal: restore device for other active usecases when VOIP
1050665 I2244eec21aa683e13011e1183d8073ddc3963893 hal: Add Quad mic voice recognition device
Change-Id: Ib10f6fd0f40d9e674f2ced254d8a458e848116a4
CRs-Fixed: 1038106, 1033873, 1050665, 1037083
diff --git a/configs/msmcobalt/audio_policy.conf b/configs/msmcobalt/audio_policy.conf
index dd827fe..a3b0c55 100644
--- a/configs/msmcobalt/audio_policy.conf
+++ b/configs/msmcobalt/audio_policy.conf
@@ -26,21 +26,21 @@
sampling_rates 44100|48000
channel_masks AUDIO_CHANNEL_OUT_STEREO
formats AUDIO_FORMAT_PCM_16_BIT
- devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_USB_DEVICE
+ devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
flags AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_PRIMARY
}
raw {
sampling_rates 48000
channel_masks AUDIO_CHANNEL_OUT_STEREO
formats AUDIO_FORMAT_PCM_16_BIT
- devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE
+ devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
flags AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_RAW
}
deep_buffer {
sampling_rates 44100|48000
channel_masks AUDIO_CHANNEL_OUT_STEREO
formats AUDIO_FORMAT_PCM_16_BIT
- devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_USB_DEVICE
+ devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
flags AUDIO_OUTPUT_FLAG_DEEP_BUFFER
}
compress_passthrough {
@@ -61,14 +61,14 @@
sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000|64000|88200|96000|176400|192000
channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_2POINT1|AUDIO_CHANNEL_OUT_QUAD|AUDIO_CHANNEL_OUT_PENTA|AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_6POINT1|AUDIO_CHANNEL_OUT_7POINT1
formats AUDIO_FORMAT_PCM_16_BIT|AUDIO_FORMAT_PCM_24_BIT_PACKED|AUDIO_FORMAT_PCM_8_24_BIT
- devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE
+ devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_DIRECT_PCM
}
compress_offload {
sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000|64000|88200|96000|176400|192000
channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_2POINT1|AUDIO_CHANNEL_OUT_QUAD|AUDIO_CHANNEL_OUT_PENTA|AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_6POINT1|AUDIO_CHANNEL_OUT_7POINT1
formats AUDIO_FORMAT_MP3|AUDIO_FORMAT_FLAC|AUDIO_FORMAT_ALAC|AUDIO_FORMAT_APE|AUDIO_FORMAT_AAC_LC|AUDIO_FORMAT_AAC_HE_V1|AUDIO_FORMAT_AAC_HE_V2|AUDIO_FORMAT_WMA|AUDIO_FORMAT_WMA_PRO|AUDIO_FORMAT_VORBIS|AUDIO_FORMAT_AAC_ADTS_LC|AUDIO_FORMAT_AAC_ADTS_HE_V1|AUDIO_FORMAT_AAC_ADTS_HE_V2
- devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE
+ devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING
}
incall_music {
@@ -108,14 +108,6 @@
}
}
a2dp {
- outputs {
- a2dp {
- sampling_rates 44100
- channel_masks AUDIO_CHANNEL_OUT_STEREO
- formats AUDIO_FORMAT_PCM_16_BIT
- devices AUDIO_DEVICE_OUT_ALL_A2DP
- }
- }
inputs {
a2dp {
sampling_rates 44100|48000
diff --git a/configs/msmcobalt/audio_policy_configuration.xml b/configs/msmcobalt/audio_policy_configuration.xml
index 235c157..4336aa2 100644
--- a/configs/msmcobalt/audio_policy_configuration.xml
+++ b/configs/msmcobalt/audio_policy_configuration.xml
@@ -228,6 +228,18 @@
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
+ <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
@@ -288,12 +300,37 @@
sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic"/>
<route type="mix" sink="voice_rx"
sources="Telephony Rx"/>
+ <route type="mix" sink="BT A2DP Out"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
+ <route type="mix" sink="BT A2DP Headphones"
+ 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"/>
</routes>
</module>
- <!-- A2dp Audio HAL -->
- <xi:include href="a2dp_audio_policy_configuration.xml"/>
+ <!-- A2DP Audio HAL -->
+ <module name="a2dp" halVersion="2.0">
+ <mixPorts>
+ <mixPort name="a2dp input" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+ </mixPort>
+ </mixPorts>
+
+ <devicePorts>
+ <devicePort tagName="BT A2DP In" type="AUDIO_DEVICE_IN_BLUETOOTH_A2DP" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+ </devicePort>
+ </devicePorts>
+
+ <routes>
+ <route type="mix" sink="a2dp input"
+ sources="BT A2DP In"/>
+ </routes>
+ </module>
<!-- Usb Audio HAL -->
<xi:include href="usb_audio_policy_configuration.xml"/>
diff --git a/configs/msmcobalt/mixer_paths_tasha.xml b/configs/msmcobalt/mixer_paths_tasha.xml
index 860d014..0927678 100644
--- a/configs/msmcobalt/mixer_paths_tasha.xml
+++ b/configs/msmcobalt/mixer_paths_tasha.xml
@@ -548,6 +548,11 @@
<ctl name="LSM8 MUX" value="None" />
<ctl name="SLIMBUS_5_TX LSM Function" value="None" />
<!-- listen end-->
+ <!-- split a2dp -->
+ <ctl name="BT SampleRate" value="KHZ_8" />
+ <ctl name="AFE Input Channels" value="Zero" />
+ <ctl name="SLIM7_RX ADM Channels" value="Zero" />
+ <!-- split a2dp end-->
<!-- ADSP testfwk -->
<ctl name="SLIMBUS_DL_HL Switch" value="0" />
@@ -614,7 +619,7 @@
</path>
<path name="deep-buffer-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="deep-buffer-playback bt-sco" />
</path>
@@ -657,7 +662,7 @@
</path>
<path name="low-latency-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="low-latency-playback bt-sco" />
</path>
@@ -714,7 +719,7 @@
</path>
<path name="audio-ull-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="audio-ull-playback bt-sco" />
</path>
@@ -760,7 +765,7 @@
</path>
<path name="compress-offload-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback bt-sco" />
</path>
@@ -808,7 +813,7 @@
</path>
<path name="compress-offload-playback2 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback2 bt-sco" />
</path>
@@ -856,7 +861,7 @@
</path>
<path name="compress-offload-playback3 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback3 bt-sco" />
</path>
@@ -904,7 +909,7 @@
</path>
<path name="compress-offload-playback4 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback4 bt-sco" />
</path>
@@ -952,7 +957,7 @@
</path>
<path name="compress-offload-playback5 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback5 bt-sco" />
</path>
@@ -1000,7 +1005,7 @@
</path>
<path name="compress-offload-playback6 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback6 bt-sco" />
</path>
@@ -1048,7 +1053,7 @@
</path>
<path name="compress-offload-playback7 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback7 bt-sco" />
</path>
@@ -1096,7 +1101,7 @@
</path>
<path name="compress-offload-playback8 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback8 bt-sco" />
</path>
@@ -1144,7 +1149,7 @@
</path>
<path name="compress-offload-playback9 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback9 bt-sco" />
</path>
@@ -1192,7 +1197,7 @@
</path>
<path name="audio-record bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="audio-record bt-sco" />
</path>
@@ -1209,7 +1214,7 @@
</path>
<path name="audio-record-compress bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="audio-record-compress bt-sco" />
</path>
@@ -1226,7 +1231,7 @@
</path>
<path name="low-latency-record bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="low-latency-record bt-sco" />
</path>
@@ -1393,12 +1398,12 @@
</path>
<path name="hfp-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="hfp-sco" />
</path>
<path name="hfp-sco-wb headphones">
- <ctl name="AUX PCM SampleRate" value="16000" />
+ <ctl name="AUX PCM SampleRate" value="KHZ_16" />
<path name="hfp-sco headphones" />
</path>
@@ -1419,7 +1424,7 @@
</path>
<path name="compress-voip-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-voip-call bt-sco" />
</path>
@@ -1459,7 +1464,7 @@
</path>
<path name="vowlan-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="vowlan-call bt-sco" />
</path>
@@ -1499,7 +1504,7 @@
</path>
<path name="voicemmode1-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="voicemmode1-call bt-sco" />
</path>
@@ -1539,7 +1544,7 @@
</path>
<path name="voicemmode2-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="voicemmode2-call bt-sco" />
</path>
@@ -2376,4 +2381,122 @@
<ctl name="SLIMBUS_DL_HL Switch" value="1" />
</path>
+ <path name="bt-a2dp">
+ <ctl name="BT SampleRate" value="KHZ_48" />
+ <ctl name="AFE Input Channels" value="Two" />
+ <ctl name="SLIM7_RX ADM Channels" value="Two" />
+ </path>
+
+ <path name="speaker-and-bt-a2dp">
+ <path name="speaker" />
+ <path name="bt-a2dp" />
+ </path>
+
+ <path name="deep-buffer-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia1" value="1" />
+ </path>
+
+ <path name="low-latency-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia5" value="1" />
+ </path>
+
+ <path name="compress-offload-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia4" value="1" />
+ </path>
+
+ <path name="compress-offload-playback2 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia7" value="1" />
+ </path>
+
+ <path name="compress-offload-playback3 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia10" value="1" />
+ </path>
+
+ <path name="compress-offload-playback4 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia11" value="1" />
+ </path>
+
+ <path name="compress-offload-playback5 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia12" value="1" />
+ </path>
+
+ <path name="compress-offload-playback6 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia13" value="1" />
+ </path>
+
+ <path name="compress-offload-playback7 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia14" value="1" />
+ </path>
+
+ <path name="compress-offload-playback8 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia15" value="1" />
+ </path>
+
+ <path name="compress-offload-playback9 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia16" value="1" />
+ </path>
+
+ <path name="audio-ull-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia3" value="1" />
+ </path>
+
+ <path name="deep-buffer-playback speaker-and-bt-a2dp">
+ <path name="deep-buffer-playback bt-a2dp" />
+ <path name="deep-buffer-playback" />
+ </path>
+
+ <path name="compress-offload-playback speaker-and-bt-a2dp">
+ <path name="compress-offload-playback bt-a2dp" />
+ <path name="compress-offload-playback" />
+ </path>
+
+ <path name="low-latency-playback speaker-and-bt-a2dp">
+ <path name="low-latency-playback bt-a2dp" />
+ <path name="low-latency-playback" />
+ </path>
+
+ <path name="compress-offload-playback2 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback2 bt-a2dp" />
+ <path name="compress-offload-playback2" />
+ </path>
+
+ <path name="compress-offload-playback3 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback3 bt-a2dp" />
+ <path name="compress-offload-playback3" />
+ </path>
+
+ <path name="compress-offload-playback4 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback4 bt-a2dp" />
+ <path name="compress-offload-playback4" />
+ </path>
+
+ <path name="compress-offload-playback5 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback5 bt-a2dp" />
+ <path name="compress-offload-playback5" />
+ </path>
+
+ <path name="compress-offload-playback6 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback6 bt-a2dp" />
+ <path name="compress-offload-playback6" />
+ </path>
+
+ <path name="compress-offload-playback7 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback7 bt-a2dp" />
+ <path name="compress-offload-playback7" />
+ </path>
+
+ <path name="compress-offload-playback8 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback8 bt-a2dp" />
+ <path name="compress-offload-playback8" />
+ </path>
+
+ <path name="compress-offload-playback9 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback9 bt-a2dp" />
+ <path name="compress-offload-playback9" />
+ </path>
+
+ <path name="audio-ull-playback speaker-and-bt-a2dp">
+ <path name="audio-ull-playback bt-a2dp" />
+ <path name="audio-ull-playback" />
+ </path>
</mixer>
diff --git a/configs/msmcobalt/mixer_paths_tavil.xml b/configs/msmcobalt/mixer_paths_tavil.xml
index 1c92421..ea84785 100644
--- a/configs/msmcobalt/mixer_paths_tavil.xml
+++ b/configs/msmcobalt/mixer_paths_tavil.xml
@@ -262,6 +262,12 @@
<ctl name="MultiMedia8 Mixer AFE_PCM_TX" value="0" />
<!-- audio record compress end-->
+ <!-- split a2dp -->
+ <ctl name="BT SampleRate" value="KHZ_8" />
+ <ctl name="AFE Input Channels" value="Zero" />
+ <ctl name="SLIM7_RX ADM Channels" value="0" />
+ <!-- split a2dp end-->
+
<!-- ADSP testfwk -->
<ctl name="SLIMBUS_DL_HL Switch" value="0" />
<ctl name="SLIMBUS6_DL_HL Switch" value="0" />
@@ -357,7 +363,7 @@
</path>
<path name="deep-buffer-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="deep-buffer-playback bt-sco" />
</path>
@@ -400,7 +406,7 @@
</path>
<path name="low-latency-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="low-latency-playback bt-sco" />
</path>
@@ -457,7 +463,7 @@
</path>
<path name="audio-ull-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="audio-ull-playback bt-sco" />
</path>
@@ -503,7 +509,7 @@
</path>
<path name="compress-offload-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="compress-offload-playback bt-sco" />
</path>
@@ -551,7 +557,7 @@
</path>
<path name="compress-offload-playback2 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="compress-offload-playback2 bt-sco" />
</path>
@@ -599,7 +605,7 @@
</path>
<path name="compress-offload-playback3 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="compress-offload-playback3 bt-sco" />
</path>
@@ -647,7 +653,7 @@
</path>
<path name="compress-offload-playback4 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="compress-offload-playback4 bt-sco" />
</path>
@@ -695,7 +701,7 @@
</path>
<path name="compress-offload-playback5 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="compress-offload-playback5 bt-sco" />
</path>
@@ -743,7 +749,7 @@
</path>
<path name="compress-offload-playback6 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="compress-offload-playback6 bt-sco" />
</path>
@@ -791,7 +797,7 @@
</path>
<path name="compress-offload-playback7 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="compress-offload-playback7 bt-sco" />
</path>
@@ -839,7 +845,7 @@
</path>
<path name="compress-offload-playback8 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="compress-offload-playback8 bt-sco" />
</path>
@@ -887,7 +893,7 @@
</path>
<path name="compress-offload-playback9 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="compress-offload-playback9 bt-sco" />
</path>
@@ -935,7 +941,7 @@
</path>
<path name="audio-record bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="audio-record bt-sco" />
</path>
@@ -952,7 +958,7 @@
</path>
<path name="audio-record-compress bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="audio-record-compress bt-sco" />
</path>
@@ -969,7 +975,7 @@
</path>
<path name="low-latency-record bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="low-latency-record bt-sco" />
</path>
@@ -1150,7 +1156,7 @@
</path>
<path name="compress-voip-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="compress-voip-call bt-sco" />
</path>
@@ -1190,7 +1196,7 @@
</path>
<path name="voicemmode1-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="voicemmode1-call bt-sco" />
</path>
@@ -1230,7 +1236,7 @@
</path>
<path name="voicemmode2-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="16000" />
<path name="voicemmode2-call bt-sco" />
</path>
@@ -1715,4 +1721,122 @@
<ctl name="SLIMBUS_DL_HL Switch" value="1" />
</path>
+ <path name="bt-a2dp">
+ <ctl name="BT SampleRate" value="KHZ_48" />
+ <ctl name="AFE Input Channels" value="Two" />
+ <ctl name="SLIM7_RX ADM Channels" value="2" />
+ </path>
+
+ <path name="speaker-and-bt-a2dp">
+ <path name="speaker" />
+ <path name="bt-a2dp" />
+ </path>
+
+ <path name="deep-buffer-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia1" value="1" />
+ </path>
+
+ <path name="low-latency-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia5" value="1" />
+ </path>
+
+ <path name="compress-offload-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia4" value="1" />
+ </path>
+
+ <path name="compress-offload-playback2 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia7" value="1" />
+ </path>
+
+ <path name="compress-offload-playback3 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia10" value="1" />
+ </path>
+
+ <path name="compress-offload-playback4 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia11" value="1" />
+ </path>
+
+ <path name="compress-offload-playback5 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia12" value="1" />
+ </path>
+
+ <path name="compress-offload-playback6 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia13" value="1" />
+ </path>
+
+ <path name="compress-offload-playback7 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia14" value="1" />
+ </path>
+
+ <path name="compress-offload-playback8 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia15" value="1" />
+ </path>
+
+ <path name="compress-offload-playback9 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia16" value="1" />
+ </path>
+
+ <path name="audio-ull-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia3" value="1" />
+ </path>
+
+ <path name="deep-buffer-playback speaker-and-bt-a2dp">
+ <path name="deep-buffer-playback bt-a2dp" />
+ <path name="deep-buffer-playback" />
+ </path>
+
+ <path name="compress-offload-playback speaker-and-bt-a2dp">
+ <path name="compress-offload-playback bt-a2dp" />
+ <path name="compress-offload-playback" />
+ </path>
+
+ <path name="low-latency-playback speaker-and-bt-a2dp">
+ <path name="low-latency-playback bt-a2dp" />
+ <path name="low-latency-playback" />
+ </path>
+
+ <path name="compress-offload-playback2 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback2 bt-a2dp" />
+ <path name="compress-offload-playback2" />
+ </path>
+
+ <path name="compress-offload-playback3 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback3 bt-a2dp" />
+ <path name="compress-offload-playback3" />
+ </path>
+
+ <path name="compress-offload-playback4 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback4 bt-a2dp" />
+ <path name="compress-offload-playback4" />
+ </path>
+
+ <path name="compress-offload-playback5 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback5 bt-a2dp" />
+ <path name="compress-offload-playback5" />
+ </path>
+
+ <path name="compress-offload-playback6 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback6 bt-a2dp" />
+ <path name="compress-offload-playback6" />
+ </path>
+
+ <path name="compress-offload-playback7 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback7 bt-a2dp" />
+ <path name="compress-offload-playback7" />
+ </path>
+
+ <path name="compress-offload-playback8 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback8 bt-a2dp" />
+ <path name="compress-offload-playback8" />
+ </path>
+
+ <path name="compress-offload-playback9 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback9 bt-a2dp" />
+ <path name="compress-offload-playback9" />
+ </path>
+
+ <path name="audio-ull-playback speaker-and-bt-a2dp">
+ <path name="audio-ull-playback bt-a2dp" />
+ <path name="audio-ull-playback" />
+ </path>
</mixer>
diff --git a/configs/msmcobalt/msmcobalt.mk b/configs/msmcobalt/msmcobalt.mk
index ff73287..659cc05 100644
--- a/configs/msmcobalt/msmcobalt.mk
+++ b/configs/msmcobalt/msmcobalt.mk
@@ -52,6 +52,7 @@
AUDIO_FEATURE_ENABLED_SOURCE_TRACKING := true
AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
+AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
##AUDIO_FEATURE_FLAGS
#Audio Specific device overlays
@@ -189,3 +190,7 @@
#flac sw decoder 24 bit decode capability
PRODUCT_PROPERTY_OVERRIDES += \
flac.sw.decoder.24bit.support=true
+
+#split a2dp DSP supported encoder list
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bt.a2dp_offload_cap=sbc-aptx
diff --git a/hal/Android.mk b/hal/Android.mk
index 83787e3..adee78b 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -243,6 +243,11 @@
LOCAL_SRC_FILES += audio_extn/source_track.c
endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SPLIT_A2DP)),true)
+ LOCAL_CFLAGS += -DSPLIT_A2DP_ENABLED
+ LOCAL_SRC_FILES += audio_extn/a2dp.c
+endif
+
LOCAL_SHARED_LIBRARIES := \
liblog \
libcutils \
@@ -251,6 +256,7 @@
libaudioroute \
libdl \
libaudioutils \
+ libhardware \
libexpat
LOCAL_C_INCLUDES += \
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
new file mode 100644
index 0000000..414fc79
--- /dev/null
+++ b/hal/audio_extn/a2dp.c
@@ -0,0 +1,733 @@
+/*
+* Copyright (c) 2015-16, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#define LOG_TAG "split_a2dp"
+/*#define LOG_NDEBUG 0*/
+#define LOG_NDDEBUG 0
+#include <errno.h>
+#include <cutils/log.h>
+#include <dlfcn.h>
+#include "audio_hw.h"
+#include "platform.h"
+#include "platform_api.h"
+#include <stdlib.h>
+#include <cutils/str_parms.h>
+#include <hardware/audio.h>
+#include <hardware/hardware.h>
+#include <cutils/properties.h>
+
+#ifdef SPLIT_A2DP_ENABLED
+#define AUDIO_PARAMETER_A2DP_STARTED "A2dpStarted"
+#define BT_IPC_LIB_NAME "libbthost_if.so"
+#define ENC_MEDIA_FMT_NONE 0
+#define ENC_MEDIA_FMT_AAC 0x00010DA6
+#define ENC_MEDIA_FMT_APTX 0x000131ff
+#define ENC_MEDIA_FMT_APTX_HD 0x00013200
+#define ENC_MEDIA_FMT_SBC 0x00010BF2
+#define MEDIA_FMT_AAC_AOT_LC 2
+#define MEDIA_FMT_AAC_AOT_SBR 5
+#define MEDIA_FMT_AAC_AOT_PS 29
+#define MEDIA_FMT_AAC_FORMAT_FLAG_ADTS 0
+#define MEDIA_FMT_AAC_FORMAT_FLAG_RAW 3
+#define PCM_CHANNEL_L 1
+#define PCM_CHANNEL_R 2
+#define PCM_CHANNEL_C 3
+#define MEDIA_FMT_SBC_CHANNEL_MODE_MONO 1
+#define MEDIA_FMT_SBC_CHANNEL_MODE_STEREO 2
+#define MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO 8
+#define MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO 9
+#define MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS 0
+#define MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR 1
+#define MIXER_ENC_CONFIG_BLOCK "SLIM_7_RX Encoder Config"
+#define MIXER_ENC_FMT_SBC "SBC"
+#define MIXER_ENC_FMT_AAC "AAC"
+#define MIXER_ENC_FMT_APTX "APTX"
+#define MIXER_ENC_FMT_APTXHD "APTXHD"
+#define MIXER_ENC_FMT_NONE "NONE"
+
+
+typedef int (*audio_stream_open_t)(void);
+typedef int (*audio_stream_close_t)(void);
+typedef int (*audio_start_stream_t)(void);
+typedef int (*audio_stop_stream_t)(void);
+typedef int (*audio_suspend_stream_t)(void);
+typedef void (*audio_handoff_triggered_t)(void);
+typedef void (*clear_a2dpsuspend_flag_t)(void);
+typedef void * (*audio_get_codec_config_t)(uint8_t *multicast_status,uint8_t *num_dev,
+ audio_format_t *codec_type);
+
+enum A2DP_STATE {
+ A2DP_STATE_CONNECTED,
+ A2DP_STATE_STARTED,
+ A2DP_STATE_STOPPED,
+ A2DP_STATE_DISCONNECTED,
+};
+
+/* structure used to update a2dp state machine
+ * to communicate IPC library
+ * to store DSP encoder configuration information
+ */
+struct a2dp_data {
+ struct audio_device *adev;
+ void *bt_lib_handle;
+ audio_stream_open_t audio_stream_open;
+ audio_stream_close_t audio_stream_close;
+ audio_start_stream_t audio_start_stream;
+ audio_stop_stream_t audio_stop_stream;
+ audio_suspend_stream_t audio_suspend_stream;
+ audio_handoff_triggered_t audio_handoff_triggered;
+ clear_a2dpsuspend_flag_t clear_a2dpsuspend_flag;
+ audio_get_codec_config_t audio_get_codec_config;
+ enum A2DP_STATE bt_state;
+ audio_format_t bt_encoder_format;
+ void *enc_config_data;
+ bool a2dp_started;
+ bool a2dp_suspended;
+ int a2dp_total_active_session_request;
+ bool is_a2dp_offload_supported;
+ bool is_handoff_in_progress;
+};
+
+struct a2dp_data a2dp;
+
+/* START of DSP configurable structures
+ * These values should match with DSP interface defintion
+ */
+
+/* AAC encoder configuration structure. */
+typedef struct aac_enc_cfg_t aac_enc_cfg_t;
+
+/* supported enc_mode are AAC_LC, AAC_SBR, AAC_PS
+ * supported aac_fmt_flag are ADTS/RAW
+ * supported channel_cfg are Native mode, Mono , Stereo
+ */
+struct aac_enc_cfg_t {
+ uint32_t enc_format;
+ uint32_t bit_rate;
+ uint32_t enc_mode;
+ uint16_t aac_fmt_flag;
+ uint32_t channel_cfg;
+ uint32_t sample_rate;
+} ;
+
+/* SBC encoder configuration structure. */
+typedef struct sbc_enc_cfg_t sbc_enc_cfg_t;
+
+/* supported num_subbands are 4/8
+ * supported blk_len are 4, 8, 12, 16
+ * supported channel_mode are MONO, STEREO, DUAL_MONO, JOINT_STEREO
+ * supported alloc_method are LOUNDNESS/SNR
+ * supported bit_rate for mono channel is max 320kbps
+ * supported bit rate for stereo channel is max 512 kbps
+ */
+struct sbc_enc_cfg_t{
+ uint32_t enc_format;
+ uint32_t num_subbands;
+ uint32_t blk_len;
+ uint32_t channel_mode;
+ uint32_t alloc_method;
+ uint32_t bit_rate;
+ uint32_t sample_rate;
+};
+
+
+/* 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_aptx_t
+{
+ uint32_t enc_format;
+ uint32_t sample_rate;
+ uint16_t num_channels;
+ uint16_t reserved;
+ uint8_t channel_mapping[8];
+ uint32_t custom_size;
+};
+
+/*********** END of DSP configurable structures ********************/
+
+/* API to identify DSP encoder captabilities */
+static void a2dp_offload_codec_cap_parser(char *value)
+{
+ char *tok = NULL;
+
+ tok = strtok(value, "-");
+ while (tok != NULL) {
+ if (strcmp(tok, "sbc") == 0) {
+ ALOGD("%s: SBC offload supported\n",__func__);
+ a2dp.is_a2dp_offload_supported = true;
+ break;
+ } else if (strcmp(tok, "aptx") == 0) {
+ ALOGD("%s: aptx offload supported\n",__func__);
+ a2dp.is_a2dp_offload_supported = true;
+ break;
+ }
+ tok = strtok(NULL,"-");
+ };
+}
+
+static void update_offload_codec_capabilities()
+{
+ char value[PROPERTY_VALUE_MAX] = {'\0'};
+
+ property_get("persist.bt.a2dp_offload_cap", value, "false");
+ ALOGD("get_offload_codec_capabilities = %s",value);
+ a2dp.is_a2dp_offload_supported =
+ property_get_bool("persist.bt.a2dp_offload_cap", false);
+ if (strcmp(value, "false") != 0)
+ a2dp_offload_codec_cap_parser(value);
+ ALOGD("%s: codec cap = %s",__func__,value);
+}
+
+/* API to open BT IPC library to start IPC communication */
+static void open_a2dp_output()
+{
+ int ret = 0;
+
+ ALOGD(" Open A2DP output start ");
+ if (a2dp.bt_lib_handle == NULL){
+ ALOGD(" Requesting for BT lib handle");
+ a2dp.bt_lib_handle = dlopen(BT_IPC_LIB_NAME, RTLD_NOW);
+
+ if (a2dp.bt_lib_handle == NULL) {
+ ALOGE("%s: DLOPEN failed for %s", __func__, BT_IPC_LIB_NAME);
+ ret = -ENOSYS;
+ goto init_fail;
+ } else {
+ a2dp.audio_stream_open = (audio_stream_open_t)
+ dlsym(a2dp.bt_lib_handle, "audio_stream_open");
+ a2dp.audio_start_stream = (audio_start_stream_t)
+ dlsym(a2dp.bt_lib_handle, "audio_start_stream");
+ a2dp.audio_get_codec_config = (audio_get_codec_config_t)
+ dlsym(a2dp.bt_lib_handle, "audio_get_codec_config");
+ a2dp.audio_suspend_stream = (audio_suspend_stream_t)
+ dlsym(a2dp.bt_lib_handle, "audio_suspend_stream");
+ a2dp.audio_handoff_triggered = (audio_handoff_triggered_t)
+ dlsym(a2dp.bt_lib_handle, "audio_handoff_triggered");
+ a2dp.clear_a2dpsuspend_flag = (clear_a2dpsuspend_flag_t)
+ dlsym(a2dp.bt_lib_handle, "clear_a2dpsuspend_flag");
+ a2dp.audio_stop_stream = (audio_stop_stream_t)
+ dlsym(a2dp.bt_lib_handle, "audio_stop_stream");
+ a2dp.audio_stream_close = (audio_stream_close_t)
+ dlsym(a2dp.bt_lib_handle, "audio_stream_close");
+ }
+ }
+
+ if (a2dp.bt_lib_handle && a2dp.audio_stream_open) {
+ if (a2dp.bt_state == A2DP_STATE_DISCONNECTED) {
+ ALOGD("calling BT stream open");
+ ret = a2dp.audio_stream_open();
+ if(ret != 0) {
+ ALOGE("Failed to open output stream for a2dp: status %d", ret);
+ goto init_fail;
+ }
+ a2dp.bt_state = A2DP_STATE_CONNECTED;
+ } else {
+ ALOGD("Called a2dp open with improper state, Ignoring request state %d", a2dp.bt_state);
+ }
+ } else {
+ ALOGE("a2dp handle is not identified, Ignoring open request");
+ a2dp.bt_state = A2DP_STATE_DISCONNECTED;
+ goto init_fail;
+ }
+
+init_fail:
+ if(ret != 0 && (a2dp.bt_lib_handle != NULL)) {
+ dlclose(a2dp.bt_lib_handle);
+ a2dp.bt_lib_handle = NULL;
+ }
+}
+
+static int close_a2dp_output()
+{
+ ALOGV("%s\n",__func__);
+ if (!(a2dp.bt_lib_handle && a2dp.audio_stream_close)) {
+ ALOGE("a2dp handle is not identified, Ignoring close request");
+ return -ENOSYS;
+ }
+ if ((a2dp.bt_state == A2DP_STATE_CONNECTED) &&
+ (a2dp.bt_state == A2DP_STATE_STARTED) &&
+ (a2dp.bt_state == A2DP_STATE_STOPPED)) {
+ ALOGD("calling BT stream close");
+ if(a2dp.audio_stream_close() == false)
+ ALOGE("failed close a2dp control path from BT library");
+ a2dp.a2dp_started = false;
+ a2dp.a2dp_total_active_session_request = 0;
+ a2dp.a2dp_suspended = false;
+ a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
+ a2dp.enc_config_data = NULL;
+ a2dp.bt_state = A2DP_STATE_DISCONNECTED;
+ } else {
+ ALOGD("close a2dp called in improper state");
+ a2dp.a2dp_started = false;
+ a2dp.a2dp_total_active_session_request = 0;
+ a2dp.a2dp_suspended = false;
+ a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
+ a2dp.enc_config_data = NULL;
+ a2dp.bt_state = A2DP_STATE_DISCONNECTED;
+ }
+
+ return 0;
+}
+
+/* API to configure SBC DSP encoder */
+bool configure_sbc_enc_format(audio_sbc_encoder_config *sbc_bt_cfg)
+{
+ struct mixer_ctl *ctl_enc_data;
+ struct sbc_enc_cfg_t sbc_dsp_cfg;
+ bool is_configured = false;
+ int ret = 0;
+
+ if(sbc_bt_cfg == NULL)
+ return false;
+
+ ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
+ if (!ctl_enc_data) {
+ ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
+ is_configured = false;
+ goto fail;
+ }
+ a2dp.bt_encoder_format = AUDIO_FORMAT_SBC;
+ memset(&sbc_dsp_cfg, 0x0, sizeof(struct sbc_enc_cfg_t));
+ sbc_dsp_cfg.enc_format = ENC_MEDIA_FMT_SBC;
+ sbc_dsp_cfg.num_subbands = sbc_bt_cfg->subband;
+ sbc_dsp_cfg.blk_len = sbc_bt_cfg->blk_len;
+ switch(sbc_bt_cfg->channels) {
+ case 0:
+ sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_MONO;
+ break;
+ case 1:
+ sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO;
+ break;
+ case 3:
+ sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO;
+ break;
+ case 2:
+ default:
+ sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_STEREO;
+ break;
+ }
+ if (sbc_bt_cfg->alloc)
+ sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS;
+ else
+ sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR;
+ sbc_dsp_cfg.bit_rate = sbc_bt_cfg->bitrate;
+ sbc_dsp_cfg.sample_rate = sbc_bt_cfg->sampling_rate;
+ ret = mixer_ctl_set_array(ctl_enc_data, (void *)&sbc_dsp_cfg,
+ sizeof(struct sbc_enc_cfg_t));
+ if (ret != 0) {
+ ALOGE("%s: failed to set SBC encoder config", __func__);
+ is_configured = false;
+ } else
+ is_configured = true;
+fail:
+ return is_configured;
+}
+
+/* API to configure APTX DSP encoder */
+bool configure_aptx_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
+{
+ struct mixer_ctl *ctl_enc_data;
+ struct custom_enc_cfg_aptx_t aptx_dsp_cfg;
+ bool is_configured = false;
+ int ret = 0;
+
+ if(aptx_bt_cfg == NULL)
+ return false;
+
+ ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
+ if (!ctl_enc_data) {
+ ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
+ is_configured = false;
+ goto fail;
+ }
+ a2dp.bt_encoder_format = AUDIO_FORMAT_APTX;
+ memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_aptx_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) {
+ case 1:
+ aptx_dsp_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;
+ break;
+ }
+ ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
+ sizeof(struct custom_enc_cfg_aptx_t));
+ if (ret != 0) {
+ ALOGE("%s: Failed to set APTX encoder config", __func__);
+ is_configured = false;
+ goto fail;
+ }
+ is_configured = true;
+fail:
+ return is_configured;
+}
+
+/* API to configure APTX HD DSP encoder
+ * TODO: ADD 24 bit configuration support
+ */
+bool configure_aptx_hd_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
+{
+ struct mixer_ctl *ctl_enc_data;
+ struct custom_enc_cfg_aptx_t aptx_dsp_cfg;
+ bool is_configured = false;
+ int ret = 0;
+
+ if(aptx_bt_cfg == NULL)
+ return false;
+
+ ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
+ if (!ctl_enc_data) {
+ ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
+ is_configured = false;
+ goto fail;
+ }
+ a2dp.bt_encoder_format = AUDIO_FORMAT_APTX_HD;
+ memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_aptx_t));
+ aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX_HD;
+ 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) {
+ case 1:
+ aptx_dsp_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;
+ break;
+ }
+ ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
+ sizeof(struct custom_enc_cfg_aptx_t));
+ if (ret != 0) {
+ ALOGE("%s: Failed to set APTX HD encoder config", __func__);
+ is_configured = false;
+ goto fail;
+ }
+ is_configured = true;
+fail:
+ return is_configured;
+}
+
+/* API to configure AAC DSP encoder */
+bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg)
+{
+ struct mixer_ctl *ctl_enc_data;
+ struct aac_enc_cfg_t aac_dsp_cfg;
+ bool is_configured = false;
+ int ret = 0;
+
+ if(aac_bt_cfg == NULL)
+ return false;
+
+ ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
+ if (!ctl_enc_data) {
+ ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
+ is_configured = false;
+ goto fail;
+ }
+ a2dp.bt_encoder_format = AUDIO_FORMAT_AAC;
+ memset(&aac_dsp_cfg, 0x0, sizeof(struct aac_enc_cfg_t));
+ aac_dsp_cfg.enc_format = ENC_MEDIA_FMT_AAC;
+ aac_dsp_cfg.bit_rate = aac_bt_cfg->bitrate;
+ switch(aac_bt_cfg->enc_mode) {
+ case 0:
+ aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC;
+ break;
+ case 2:
+ aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS;
+ break;
+ case 1:
+ default:
+ aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR;
+ break;
+ }
+ if (aac_bt_cfg->format_flag)
+ aac_dsp_cfg.aac_fmt_flag = MEDIA_FMT_AAC_FORMAT_FLAG_RAW;
+ else
+ aac_dsp_cfg.aac_fmt_flag = MEDIA_FMT_AAC_FORMAT_FLAG_ADTS;
+ aac_dsp_cfg.channel_cfg = aac_bt_cfg->channels;
+ ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aac_dsp_cfg,
+ sizeof(struct aac_enc_cfg_t));
+ if (ret != 0) {
+ ALOGE("%s: failed to set SBC encoder config", __func__);
+ is_configured = false;
+ } else
+ is_configured = true;
+fail:
+ return is_configured;
+}
+
+bool configure_a2dp_encoder_format()
+{
+ void *codec_info = NULL;
+ uint8_t multi_cast = 0, num_dev = 1;
+ audio_format_t codec_type = AUDIO_FORMAT_INVALID;
+ bool is_configured = false;
+
+ if (!a2dp.audio_get_codec_config) {
+ ALOGE(" a2dp handle is not identified, ignoring a2dp encoder config");
+ return false;
+ }
+ ALOGD("configure_a2dp_encoder_format start");
+ codec_info = a2dp.audio_get_codec_config(&multi_cast, &num_dev,
+ &codec_type);
+
+ switch(codec_type) {
+ case AUDIO_FORMAT_SBC:
+ ALOGD(" Received SBC encoder supported BT device");
+ is_configured =
+ configure_sbc_enc_format((audio_sbc_encoder_config *)codec_info);
+ break;
+ case AUDIO_FORMAT_APTX:
+ ALOGD(" Received APTX encoder supported BT device");
+ is_configured =
+ configure_aptx_enc_format((audio_aptx_encoder_config *)codec_info);
+ break;
+ case AUDIO_FORMAT_APTX_HD:
+ ALOGD(" Received APTX HD encoder supported BT device");
+ is_configured =
+ configure_aptx_hd_enc_format((audio_aptx_encoder_config *)codec_info);
+ break;
+ case AUDIO_FORMAT_AAC:
+ ALOGD(" Received AAC encoder supported BT device");
+ is_configured =
+ configure_aac_enc_format((audio_aac_encoder_config *)codec_info);
+ break;
+ default:
+ ALOGD(" Received Unsupported encoder formar");
+ is_configured = false;
+ break;
+ }
+ return is_configured;
+}
+
+int audio_extn_a2dp_start_playback()
+{
+ int ret = 0;
+
+ ALOGD("audio_extn_a2dp_start_playback start");
+
+ if(!(a2dp.bt_lib_handle && a2dp.audio_start_stream
+ && a2dp.audio_get_codec_config)) {
+ ALOGE("a2dp handle is not identified, Ignoring start request");
+ return -ENOSYS;
+ }
+
+ if(a2dp.a2dp_suspended == true) {
+ //session will be restarted after suspend completion
+ ALOGD("a2dp start requested during suspend state");
+ a2dp.a2dp_total_active_session_request++;
+ return 0;
+ }
+
+ if (!a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
+ ALOGD("calling BT module stream start");
+ /* This call indicates BT IPC lib to start playback */
+ ret = a2dp.audio_start_stream();
+ ALOGE("BT controller start return = %d",ret);
+ if (ret != 0 ) {
+ ALOGE("BT controller start failed");
+ a2dp.a2dp_started = false;
+ ret = -ETIMEDOUT;
+ } else {
+ if(configure_a2dp_encoder_format() == true) {
+ a2dp.a2dp_started = true;
+ ret = 0;
+ ALOGD("Start playback successful to BT library");
+ } else {
+ ALOGD(" unable to configure DSP encoder");
+ a2dp.a2dp_started = false;
+ ret = -ETIMEDOUT;
+ }
+ }
+ }
+
+ if (a2dp.a2dp_started)
+ a2dp.a2dp_total_active_session_request++;
+
+ ALOGD("start A2DP playback total active sessions :%d",
+ a2dp.a2dp_total_active_session_request);
+ return ret;
+}
+
+int audio_extn_a2dp_stop_playback()
+{
+ int ret =0;
+
+ ALOGV("audio_extn_a2dp_stop_playback start");
+ if(!(a2dp.bt_lib_handle && a2dp.audio_stop_stream)) {
+ ALOGE("a2dp handle is not identified, Ignoring start request");
+ return -ENOSYS;
+ }
+
+ if(a2dp.a2dp_suspended == true) {
+ ALOGD("STOP playback is called during suspend state");
+
+ // sessions are already closed during suspend, just update active sessions counts
+ if(a2dp.a2dp_total_active_session_request > 0)
+ a2dp.a2dp_total_active_session_request--;
+ return 0;
+ }
+ if (a2dp.a2dp_started && (a2dp.a2dp_total_active_session_request > 0))
+ a2dp.a2dp_total_active_session_request--;
+
+ if ( a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
+ struct mixer_ctl *ctl_enc_config;
+ struct sbc_enc_cfg_t dummy_reset_config;
+
+ ALOGV("calling BT module stream stop");
+ ret = a2dp.audio_stop_stream();
+ if (ret < 0)
+ ALOGE("stop stream to BT IPC lib failed");
+ else
+ ALOGV("stop steam to BT IPC lib successful");
+ a2dp.is_handoff_in_progress = false;
+
+ memset(&dummy_reset_config, 0x0, sizeof(struct sbc_enc_cfg_t));
+ ctl_enc_config = mixer_get_ctl_by_name(a2dp.adev->mixer,
+ MIXER_ENC_CONFIG_BLOCK);
+ if (!ctl_enc_config) {
+ ALOGE(" ERROR a2dp encoder format mixer control not identifed");
+ } else {
+ ret = mixer_ctl_set_array(ctl_enc_config, (void *)&dummy_reset_config,
+ sizeof(struct sbc_enc_cfg_t));
+ a2dp.bt_encoder_format = ENC_MEDIA_FMT_NONE;
+ }
+ }
+ if(!a2dp.a2dp_total_active_session_request)
+ a2dp.a2dp_started = false;
+ ALOGD("Stop A2DP playback total active sessions :%d",
+ a2dp.a2dp_total_active_session_request);
+ return 0;
+}
+
+void audio_extn_a2dp_set_parameters(struct str_parms *parms)
+{
+ int ret, val;
+ char value[32]={0};
+
+ if(a2dp.is_a2dp_offload_supported == false) {
+ ALOGV("no supported encoders identified,ignoring a2dp setparam");
+ return;
+ }
+
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
+ sizeof(value));
+ if( ret >= 0) {
+ val = atoi(value);
+ if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ ALOGV("Received device connect request for A2DP");
+ open_a2dp_output();
+ }
+ goto param_handled;
+ }
+
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value,
+ sizeof(value));
+
+ if( ret >= 0) {
+ val = atoi(value);
+ if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ ALOGV("Received device dis- connect request");
+ close_a2dp_output();
+ }
+ goto param_handled;
+ }
+
+ ret = str_parms_get_str(parms, "A2dpSuspended", value, sizeof(value));
+ if (ret >= 0) {
+ if (a2dp.bt_lib_handle && (a2dp.bt_state != A2DP_STATE_DISCONNECTED) ) {
+ if ((!strncmp(value,"true",sizeof(value)))) {
+ ALOGD("Setting a2dp to suspend state");
+ int active_sessions = a2dp.a2dp_total_active_session_request, count = 0;
+ //Force close all active sessions on suspend (if any)
+ for(count = 0; count< active_sessions; count ++)
+ audio_extn_a2dp_stop_playback();
+ a2dp.a2dp_total_active_session_request = active_sessions;
+ a2dp.a2dp_suspended = true;
+
+ if(a2dp.audio_suspend_stream)
+ a2dp.audio_suspend_stream();
+ } else if (a2dp.a2dp_suspended == true) {
+ ALOGD("Resetting a2dp suspend state");
+ if(a2dp.clear_a2dpsuspend_flag)
+ a2dp.clear_a2dpsuspend_flag();
+
+ a2dp.a2dp_suspended = false;
+ //Force restart all active sessions post suspend (if any)
+ if(a2dp.a2dp_total_active_session_request > 0){
+ int active_sessions = a2dp.a2dp_total_active_session_request;
+ a2dp.a2dp_total_active_session_request = 0;
+ audio_extn_a2dp_start_playback();
+ a2dp.a2dp_total_active_session_request = active_sessions;
+ }
+ }
+ }
+ goto param_handled;
+ }
+ ret = str_parms_get_str(parms,"reconfigA2dp", value, sizeof(value));
+ if (ret >= 0) {
+ if (a2dp.bt_lib_handle && (a2dp.bt_state != A2DP_STATE_DISCONNECTED)) {
+ if (!strncmp(value,"true",sizeof(value)))
+ a2dp.is_handoff_in_progress = true;
+ }
+ goto param_handled;
+ }
+param_handled:
+ ALOGV("end of a2dp setparam");
+}
+
+bool audio_extn_a2dp_is_force_device_switch()
+{
+ //During encoder reconfiguration mode, force a2dp device switch
+ return a2dp.is_handoff_in_progress;
+}
+
+void audio_extn_a2dp_init (void *adev)
+{
+ a2dp.adev = (struct audio_device*)adev;
+ a2dp.bt_lib_handle = NULL;
+ a2dp.a2dp_started = false;
+ a2dp.bt_state = A2DP_STATE_DISCONNECTED;
+ a2dp.a2dp_total_active_session_request = 0;
+ a2dp.a2dp_suspended = false;
+ a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
+ a2dp.enc_config_data = NULL;
+ a2dp.is_a2dp_offload_supported = false;
+ a2dp.is_handoff_in_progress = false;
+ update_offload_codec_capabilities();
+}
+#endif // SPLIT_A2DP_ENABLED
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 49e649c..b316473 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -755,6 +755,7 @@
audio_extn_ssr_set_parameters(adev, parms);
audio_extn_hfp_set_parameters(adev, parms);
audio_extn_dts_eagle_set_parameters(adev, parms);
+ audio_extn_a2dp_set_parameters(parms);
audio_extn_ddp_set_parameters(adev, parms);
audio_extn_ds2_set_parameters(adev, parms);
audio_extn_customstereo_set_parameters(adev, parms);
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index fe3fe95..d186a5f 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -171,6 +171,20 @@
char *value, int len);
#endif
+#ifndef SPLIT_A2DP_ENABLED
+#define audio_extn_a2dp_init(adev) (0)
+#define audio_extn_a2dp_start_playback() (0)
+#define audio_extn_a2dp_stop_playback() (0)
+#define audio_extn_a2dp_set_parameters(parms) (0)
+#define audio_extn_a2dp_is_force_device_switch() (0)
+#else
+void audio_extn_a2dp_init(void *adev);
+int audio_extn_a2dp_start_playback();
+void audio_extn_a2dp_stop_playback();
+void audio_extn_a2dp_set_parameters(struct str_parms *parms);
+bool audio_extn_a2dp_is_force_device_switch();
+#endif
+
#ifndef SSR_ENABLED
#define audio_extn_ssr_check_and_set_usecase(in) (0)
#define audio_extn_ssr_init(in, num_out_chan) (0)
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 24a2be8..db1e399 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -716,6 +716,13 @@
audio_extn_spkr_prot_calib_cancel(adev);
+ if (((SND_DEVICE_OUT_BT_A2DP == snd_device) ||
+ (SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device))
+ && (audio_extn_a2dp_start_playback() < 0)) {
+ ALOGE(" fail to configure A2dp control path ");
+ return -EINVAL;
+ }
+
if (platform_can_enable_spkr_prot_on_device(snd_device) &&
audio_extn_spkr_prot_is_enabled()) {
if (platform_get_spkr_prot_acdb_id(snd_device) < 0) {
@@ -791,6 +798,11 @@
if (adev->snd_dev_ref_cnt[snd_device] == 0) {
ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, device_name);
+
+ if ((SND_DEVICE_OUT_BT_A2DP == snd_device) ||
+ (SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device))
+ audio_extn_a2dp_stop_playback();
+
if (platform_can_enable_spkr_prot_on_device(snd_device) &&
audio_extn_spkr_prot_is_enabled()) {
audio_extn_spkr_prot_stop_processing(snd_device);
@@ -832,7 +844,7 @@
struct audio_usecase *usecase;
bool switch_device[AUDIO_USECASE_MAX];
int i, num_uc_to_switch = 0;
-
+ bool force_restart_session = false;
/*
* This function is to make sure that all the usecases that are active on
* the hardware codec backend are always routed to any one device that is
@@ -852,7 +864,15 @@
*/
bool force_routing = platform_check_and_set_codec_backend_cfg(adev, uc_info,
snd_device);
-
+ /* For a2dp device reconfigure all active sessions
+ * with new AFE encoder format based on a2dp state
+ */
+ if ((SND_DEVICE_OUT_BT_A2DP == snd_device ||
+ SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device) &&
+ audio_extn_a2dp_is_force_device_switch()) {
+ force_routing = true;
+ force_restart_session = true;
+ }
ALOGD("%s:becf: force routing %d", __func__, force_routing);
/* Disable all the usecases on the shared backend other than the
@@ -871,8 +891,9 @@
platform_check_backends_match(snd_device, usecase->out_snd_device));
if (usecase->type != PCM_CAPTURE &&
usecase != uc_info &&
- (usecase->out_snd_device != snd_device || force_routing) &&
- usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND &&
+ (usecase->out_snd_device != snd_device || force_routing) &&
+ (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND ||
+ force_restart_session) &&
platform_check_backends_match(snd_device, usecase->out_snd_device)) {
ALOGD("%s:becf: check_usecases (%s) is active on (%s) - disabling ..",
__func__, use_case_table[usecase->id],
@@ -1163,6 +1184,14 @@
}
}
+ // Force all a2dp output devices to reconfigure for proper AFE encode format
+ if((usecase->stream.out) &&
+ (usecase->stream.out->devices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) &&
+ audio_extn_a2dp_is_force_device_switch()) {
+ ALOGD("Force a2dp device switch to update new encoder config");
+ ret = true;
+ }
+
return ret;
}
@@ -1214,7 +1243,8 @@
} else if (voice_extn_compress_voip_is_active(adev)) {
voip_usecase = get_usecase_from_list(adev, USECASE_COMPRESS_VOIP_CALL);
if ((voip_usecase) && ((voip_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
- (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
+ ((usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
+ ((usecase->devices & ~AUDIO_DEVICE_BIT_IN) & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND)) &&
(voip_usecase->stream.out != adev->primary_output))) {
in_snd_device = voip_usecase->in_snd_device;
out_snd_device = voip_usecase->out_snd_device;
@@ -2340,13 +2370,6 @@
ALOGD("%s: enter: stream (%p) usecase(%d: %s)", __func__,
stream, out->usecase, use_case_table[out->usecase]);
- if (out->usecase == USECASE_COMPRESS_VOIP_CALL) {
- /* Ignore standby in case of voip call because the voip output
- * stream is closed in adev_close_output_stream()
- */
- ALOGD("%s: Ignore Standby in VOIP call", __func__);
- return 0;
- }
lock_output_stream(out);
if (!out->standby) {
@@ -2358,7 +2381,13 @@
pthread_mutex_lock(&adev->lock);
out->standby = true;
- if (!is_offload_usecase(out->usecase)) {
+ if (out->usecase == USECASE_COMPRESS_VOIP_CALL) {
+ voice_extn_compress_voip_close_output_stream(stream);
+ pthread_mutex_unlock(&adev->lock);
+ pthread_mutex_unlock(&out->lock);
+ ALOGD("VOIP output entered standby");
+ return 0;
+ } else if (!is_offload_usecase(out->usecase)) {
if (out->pcm) {
pcm_close(out->pcm);
out->pcm = NULL;
@@ -2452,6 +2481,17 @@
(platform_get_edid_info(adev->platform) != 0) /* HDMI disconnected */) {
val = AUDIO_DEVICE_OUT_SPEAKER;
}
+ /*
+ * When A2DP is disconnected the
+ * music playback is paused and the policy manager sends routing=0
+ * But the audioflingercontinues to write data until standby time
+ * (3sec). As BT is turned off, the write gets blocked.
+ * Avoid this by routing audio to speaker until standby.
+ */
+ if ((out->devices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) &&
+ (val == AUDIO_DEVICE_NONE)) {
+ val = AUDIO_DEVICE_OUT_SPEAKER;
+ }
/*
* select_devices() call below switches all the usecases on the same
@@ -3230,14 +3270,6 @@
ALOGD("%s: enter: stream (%p) usecase(%d: %s)", __func__,
stream, in->usecase, use_case_table[in->usecase]);
- if (in->usecase == USECASE_COMPRESS_VOIP_CALL) {
- /* Ignore standby in case of voip call because the voip input
- * stream is closed in adev_close_input_stream()
- */
- ALOGV("%s: Ignore Standby in VOIP call", __func__);
- return status;
- }
-
lock_input_stream(in);
if (!in->standby && in->is_st_session) {
ALOGD("%s: sound trigger pcm stop lab", __func__);
@@ -3251,11 +3283,16 @@
pthread_mutex_lock(&adev->lock);
in->standby = true;
- if (in->pcm) {
- pcm_close(in->pcm);
- in->pcm = NULL;
+ if (in->usecase == USECASE_COMPRESS_VOIP_CALL) {
+ voice_extn_compress_voip_close_input_stream(stream);
+ ALOGD("VOIP input entered standby");
+ } else {
+ if (in->pcm) {
+ pcm_close(in->pcm);
+ in->pcm = NULL;
+ }
+ status = stop_input_stream(in);
}
- status = stop_input_stream(in);
pthread_mutex_unlock(&adev->lock);
}
pthread_mutex_unlock(&in->lock);
@@ -4177,6 +4214,22 @@
}
audio_extn_set_parameters(adev, parms);
+ // reconfigure should be done only after updating a2dpstate in audio extn
+ ret = str_parms_get_str(parms,"reconfigA2dp", value, sizeof(value));
+ if (ret >= 0) {
+ 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) &&
+ (usecase->devices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP)){
+ ALOGD("reconfigure a2dp... forcing device switch");
+ //force device switch to re configure encoder
+ select_devices(adev, usecase->id);
+ break;
+ }
+ }
+ }
done:
str_parms_destroy(parms);
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 9a87c0f..9b7616e 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -346,6 +346,8 @@
[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
[SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
[SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
+ [SND_DEVICE_OUT_BT_A2DP] = "bt-a2dp",
+ [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = "speaker-and-bt-a2dp",
[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
@@ -465,6 +467,8 @@
[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
[SND_DEVICE_OUT_BT_SCO] = 22,
[SND_DEVICE_OUT_BT_SCO_WB] = 39,
+ [SND_DEVICE_OUT_BT_A2DP] = 20,
+ [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = 14,
[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
@@ -586,6 +590,8 @@
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
{TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
{TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_BT_A2DP)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
@@ -1206,6 +1212,8 @@
backend_tag_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
backend_tag_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("headphones-44.1");
backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = strdup("vbat-voice-speaker");
+ backend_tag_table[SND_DEVICE_OUT_BT_A2DP] = strdup("bt-a2dp");
+ backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("speaker-and-bt-a2dp");
hw_interface_table[SND_DEVICE_OUT_HDMI] = strdup("HDMI_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
@@ -1848,6 +1856,9 @@
/* init usb */
audio_extn_usb_init(adev);
+ /*init a2dp*/
+ audio_extn_a2dp_init(adev);
+
/* Read one time ssr property */
audio_extn_ssr_update_enabled();
audio_extn_spkr_prot_init(adev);
@@ -2421,6 +2432,17 @@
return ret;
}
+int check_44100_support_device(audio_devices_t out_device)
+{
+ int ret = true;
+
+ if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+ out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+ out_device & AUDIO_DEVICE_OUT_LINE)
+ ret = false;
+
+ return ret;
+}
static int platform_get_backend_index(snd_device_t snd_device)
{
@@ -2876,6 +2898,9 @@
} else if (devices == (AUDIO_DEVICE_OUT_USB_DEVICE |
AUDIO_DEVICE_OUT_SPEAKER)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
+ } else if ((devices & AUDIO_DEVICE_OUT_SPEAKER) &&
+ (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP;
} else {
ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
goto exit;
@@ -2926,6 +2951,8 @@
snd_device = SND_DEVICE_OUT_BT_SCO_WB;
else
snd_device = SND_DEVICE_OUT_BT_SCO;
+ } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ snd_device = SND_DEVICE_OUT_BT_A2DP;
} else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
if (my_data->is_vbat_speaker)
snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_VBAT;
@@ -3009,6 +3036,8 @@
snd_device = SND_DEVICE_OUT_BT_SCO;
} else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
snd_device = SND_DEVICE_OUT_HDMI ;
+ } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ snd_device = SND_DEVICE_OUT_BT_A2DP;
} else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
ALOGD("%s: setting USB hadset channel capability(2) for Proxy", __func__);
@@ -4218,14 +4247,12 @@
}
/*
- * hifi playback not supported on spkr devices, limit the Sample Rate
+ * hifi playback not supported on non-44.1-support devices, limit the Sample Rate
* to 48 khz.
*/
- if (SND_DEVICE_OUT_SPEAKER == snd_device ||
- SND_DEVICE_OUT_SPEAKER_WSA == snd_device ||
- SND_DEVICE_OUT_SPEAKER_VBAT == snd_device) {
+ if (check_44100_support_device(usecase->devices)) {
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- ALOGD("%s:becf: afe: playback on speaker device Configure afe to "
+ ALOGD("%s:becf: afe: playback on non-44.1-support device Configure afe to "
"default Sample Rate(48k)", __func__);
}
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 756c749..cd5aeb7 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -98,6 +98,8 @@
SND_DEVICE_OUT_SPEAKER_AND_HDMI,
SND_DEVICE_OUT_BT_SCO,
SND_DEVICE_OUT_BT_SCO_WB,
+ SND_DEVICE_OUT_BT_A2DP,
+ SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP,
SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
diff --git a/hal/msm8960/platform.h b/hal/msm8960/platform.h
index aab5436..e42af8c 100644
--- a/hal/msm8960/platform.h
+++ b/hal/msm8960/platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016 The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -64,6 +64,8 @@
SND_DEVICE_OUT_HDMI,
SND_DEVICE_OUT_SPEAKER_AND_HDMI,
SND_DEVICE_OUT_BT_SCO,
+ SND_DEVICE_OUT_BT_A2DP,
+ SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP,
SND_DEVICE_OUT_BT_SCO_WB,
SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 1987e94..7d8d5c7 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -347,6 +347,8 @@
[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
[SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
[SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
+ [SND_DEVICE_OUT_BT_A2DP] = "bt-a2dp",
+ [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = "speaker-and-bt-a2dp",
[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
@@ -423,6 +425,7 @@
[SND_DEVICE_IN_SPEAKER_QMIC_AEC] = "quad-mic",
[SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
+ [SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE] = "quad-mic",
[SND_DEVICE_IN_THREE_MIC] = "three-mic",
[SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
[SND_DEVICE_IN_UNPROCESSED_MIC] = "unprocessed-mic",
@@ -460,6 +463,8 @@
[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
[SND_DEVICE_OUT_BT_SCO] = 22,
[SND_DEVICE_OUT_BT_SCO_WB] = 39,
+ [SND_DEVICE_OUT_BT_A2DP] = 20,
+ [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = 14,
[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
@@ -535,6 +540,7 @@
[SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 126,
[SND_DEVICE_IN_SPEAKER_QMIC_NS] = 127,
[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
+ [SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE] = 125,
[SND_DEVICE_IN_THREE_MIC] = 46, /* for APSS Surround Sound Recording */
[SND_DEVICE_IN_HANDSET_TMIC] = 125, /* for 3mic recording with fluence */
[SND_DEVICE_IN_UNPROCESSED_MIC] = 143,
@@ -575,6 +581,8 @@
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
{TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
{TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_BT_A2DP)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
@@ -646,6 +654,7 @@
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC)},
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE)},
{TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_MIC)},
@@ -1052,7 +1061,8 @@
sizeof("apq8084-taiko-i2s-cdp-snd-card"))) {
plat_data->is_i2s_ext_modem = true;
}
- ALOGV("%s, is_i2s_ext_modem:%d",__func__, plat_data->is_i2s_ext_modem);
+ ALOGV("%s, is_i2s_ext_modem:%d soundcard name is %s",__func__,
+ plat_data->is_i2s_ext_modem, snd_card_name);
return plat_data->is_i2s_ext_modem;
}
@@ -1092,6 +1102,8 @@
backend_tag_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
backend_tag_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("headphones-44.1");
backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = strdup("voice-speaker-vbat");
+ backend_tag_table[SND_DEVICE_OUT_BT_A2DP] = strdup("bt-a2dp");
+ backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("speaker-and-bt-a2dp");
hw_interface_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("SLIMBUS_5_RX");
hw_interface_table[SND_DEVICE_OUT_HDMI] = strdup("HDMI_RX");
@@ -1673,6 +1685,9 @@
/* init usb */
audio_extn_usb_init(adev);
+ /*init a2dp*/
+ audio_extn_a2dp_init(adev);
+
/* init dap hal */
audio_extn_dap_hal_init(adev->snd_card);
@@ -2206,6 +2221,19 @@
return ret;
}
+
+int check_44100_support_device(audio_devices_t out_device)
+{
+ int ret = true;
+
+ if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+ out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+ out_device & AUDIO_DEVICE_OUT_LINE)
+ ret = false;
+
+ return ret;
+}
+
static int platform_get_backend_index(snd_device_t snd_device)
{
int32_t port = DEFAULT_CODEC_BACKEND;
@@ -2643,6 +2671,9 @@
} else if (devices == (AUDIO_DEVICE_OUT_USB_DEVICE |
AUDIO_DEVICE_OUT_SPEAKER)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
+ } else if ((devices & AUDIO_DEVICE_OUT_SPEAKER) &&
+ (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP;
} else {
ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
goto exit;
@@ -2698,6 +2729,8 @@
snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_VBAT;
else
snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
+ } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ snd_device = SND_DEVICE_OUT_BT_A2DP;
} else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
snd_device = SND_DEVICE_OUT_USB_HEADSET;
@@ -2747,6 +2780,8 @@
snd_device = SND_DEVICE_OUT_BT_SCO_WB;
else
snd_device = SND_DEVICE_OUT_BT_SCO;
+ } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ snd_device = SND_DEVICE_OUT_BT_A2DP;
} else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
snd_device = SND_DEVICE_OUT_HDMI ;
} else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
@@ -2897,7 +2932,7 @@
if (my_data->fluence_in_voice_rec && channel_count == 1) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
- snd_device = SND_DEVICE_IN_HANDSET_QMIC;
+ snd_device = SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE;
} else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_TMIC;
@@ -4181,14 +4216,12 @@
}
/*
- * hifi playback not supported on spkr devices, limit the Sample Rate
+ * hifi playback not supported on non-44.1-support devices, limit the Sample Rate
* to 48 khz.
*/
- if (SND_DEVICE_OUT_SPEAKER == snd_device ||
- SND_DEVICE_OUT_SPEAKER_WSA == snd_device ||
- SND_DEVICE_OUT_SPEAKER_VBAT == snd_device) {
+ if (check_44100_support_device(usecase->devices)) {
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- ALOGD("%s:becf: afe: playback on speaker device Configure afe to "
+ ALOGD("%s:becf: afe: playback on non-44.1-support device Configure afe to "
"default Sample Rate(48k)", __func__);
}
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 019678a..ec307b8 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -94,6 +94,8 @@
SND_DEVICE_OUT_SPEAKER_AND_HDMI,
SND_DEVICE_OUT_BT_SCO,
SND_DEVICE_OUT_BT_SCO_WB,
+ SND_DEVICE_OUT_BT_A2DP,
+ SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP,
SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
@@ -177,6 +179,7 @@
SND_DEVICE_IN_SPEAKER_QMIC_AEC,
SND_DEVICE_IN_SPEAKER_QMIC_NS,
SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS,
+ SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE,
SND_DEVICE_IN_THREE_MIC,
SND_DEVICE_IN_HANDSET_TMIC,
SND_DEVICE_IN_UNPROCESSED_MIC,
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index 7293485..3222e0b 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -244,6 +244,7 @@
{
int ret = 0;
struct audio_usecase *uc_info;
+ struct listnode *node;
ALOGD("%s: enter, out_stream_count=%d, in_stream_count=%d",
__func__, voip_data.out_stream_count, voip_data.in_stream_count);
@@ -277,6 +278,12 @@
list_remove(&uc_info->list);
free(uc_info);
+
+ // restore device for other active usecases
+ list_for_each(node, &adev->usecase_list) {
+ uc_info = node_to_item(node, struct audio_usecase, list);
+ select_devices(adev, uc_info->id);
+ }
} else
ALOGV("%s: NO-OP because out_stream_count=%d, in_stream_count=%d",
__func__, voip_data.out_stream_count, voip_data.in_stream_count);