blob: 786d637c4ff2b1c32cb7a882bfc48c5f0f64dace [file] [log] [blame]
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301/*
Naresh Tannirued694c82017-02-07 17:01:28 +05302* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
Naresh Tanniru9d027a62015-03-13 01:32:10 +05303*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are
6* met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above
10* copyright notice, this list of conditions and the following
11* disclaimer in the documentation and/or other materials provided
12* with the distribution.
13* * Neither the name of The Linux Foundation nor the names of its
14* contributors may be used to endorse or promote products derived
15* from this software without specific prior written permission.
16*
17* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29#define LOG_TAG "split_a2dp"
30/*#define LOG_NDEBUG 0*/
31#define LOG_NDDEBUG 0
32#include <errno.h>
33#include <cutils/log.h>
34#include <dlfcn.h>
35#include "audio_hw.h"
36#include "platform.h"
37#include "platform_api.h"
38#include <stdlib.h>
39#include <cutils/str_parms.h>
40#include <hardware/audio.h>
41#include <hardware/hardware.h>
42#include <cutils/properties.h>
43
Revathi Uddaraju1eac8b02017-05-18 17:13:33 +053044#ifdef DYNAMIC_LOG_ENABLED
45#include <log_xml_parser.h>
46#define LOG_MASK HAL_MOD_FILE_A2DP
47#include <log_utils.h>
48#endif
49
Naresh Tanniru9d027a62015-03-13 01:32:10 +053050#ifdef SPLIT_A2DP_ENABLED
51#define AUDIO_PARAMETER_A2DP_STARTED "A2dpStarted"
52#define BT_IPC_LIB_NAME "libbthost_if.so"
53#define ENC_MEDIA_FMT_NONE 0
54#define ENC_MEDIA_FMT_AAC 0x00010DA6
55#define ENC_MEDIA_FMT_APTX 0x000131ff
56#define ENC_MEDIA_FMT_APTX_HD 0x00013200
57#define ENC_MEDIA_FMT_SBC 0x00010BF2
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +053058#define ENC_MEDIA_FMT_CELT 0x00013221
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +053059#define ENC_MEDIA_FMT_LDAC 0x00013224
Naresh Tanniru9d027a62015-03-13 01:32:10 +053060#define MEDIA_FMT_AAC_AOT_LC 2
61#define MEDIA_FMT_AAC_AOT_SBR 5
62#define MEDIA_FMT_AAC_AOT_PS 29
Naresh Tanniru9d027a62015-03-13 01:32:10 +053063#define PCM_CHANNEL_L 1
64#define PCM_CHANNEL_R 2
65#define PCM_CHANNEL_C 3
66#define MEDIA_FMT_SBC_CHANNEL_MODE_MONO 1
67#define MEDIA_FMT_SBC_CHANNEL_MODE_STEREO 2
68#define MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO 8
69#define MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO 9
70#define MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS 0
71#define MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR 1
72#define MIXER_ENC_CONFIG_BLOCK "SLIM_7_RX Encoder Config"
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +053073#define MIXER_ENC_BIT_FORMAT "AFE Input Bit Format"
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +053074#define MIXER_SCRAMBLER_MODE "AFE Scrambler Mode"
75#define MIXER_SAMPLE_RATE "BT SampleRate"
76#define MIXER_AFE_IN_CHANNELS "AFE Input Channels"
Naresh Tanniru9d027a62015-03-13 01:32:10 +053077#define MIXER_ENC_FMT_SBC "SBC"
78#define MIXER_ENC_FMT_AAC "AAC"
79#define MIXER_ENC_FMT_APTX "APTX"
80#define MIXER_ENC_FMT_APTXHD "APTXHD"
81#define MIXER_ENC_FMT_NONE "NONE"
yidongh0515e042017-07-06 15:00:34 +080082#define ENCODER_LATENCY_SBC 10
83#define ENCODER_LATENCY_APTX 40
84#define ENCODER_LATENCY_APTX_HD 20
85#define ENCODER_LATENCY_AAC 70
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +053086//To Do: Fine Tune Encoder CELT/LDAC latency.
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +053087#define ENCODER_LATENCY_CELT 40
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +053088#define ENCODER_LATENCY_LDAC 40
yidongh0515e042017-07-06 15:00:34 +080089#define DEFAULT_SINK_LATENCY_SBC 140
90#define DEFAULT_SINK_LATENCY_APTX 160
91#define DEFAULT_SINK_LATENCY_APTX_HD 180
92#define DEFAULT_SINK_LATENCY_AAC 180
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +053093//To Do: Fine Tune Default CELT/LDAC Latency.
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +053094#define DEFAULT_SINK_LATENCY_CELT 180
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +053095#define DEFAULT_SINK_LATENCY_LDAC 180
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +053096
97/*
98 * Below enum values are extended from audio_base.h to
99 * to keep encoder codec type local to bthost_ipc
100 * and audio_hal as these are intended only for handshake
101 * between IPC lib and Audio HAL.
102 */
103typedef enum {
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530104 ENC_CODEC_TYPE_INVALID = AUDIO_FORMAT_INVALID, // 0xFFFFFFFFUL
105 ENC_CODEC_TYPE_AAC = AUDIO_FORMAT_AAC, // 0x04000000UL
106 ENC_CODEC_TYPE_SBC = AUDIO_FORMAT_SBC, // 0x1F000000UL
107 ENC_CODEC_TYPE_APTX = AUDIO_FORMAT_APTX, // 0x20000000UL
108 ENC_CODEC_TYPE_APTX_HD = AUDIO_FORMAT_APTX_HD, // 0x21000000UL
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700109 ENC_CODEC_TYPE_APTX_DUAL_MONO = 570425344u, // 0x22000000UL
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530110 ENC_CODEC_TYPE_LDAC = AUDIO_FORMAT_LDAC, // 0x23000000UL
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530111 ENC_CODEC_TYPE_CELT = 603979776u, // 0x24000000UL
112}enc_codec_t;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530113
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530114typedef int (*audio_stream_open_t)(void);
115typedef int (*audio_stream_close_t)(void);
116typedef int (*audio_start_stream_t)(void);
117typedef int (*audio_stop_stream_t)(void);
118typedef int (*audio_suspend_stream_t)(void);
119typedef void (*audio_handoff_triggered_t)(void);
120typedef void (*clear_a2dpsuspend_flag_t)(void);
121typedef void * (*audio_get_codec_config_t)(uint8_t *multicast_status,uint8_t *num_dev,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530122 enc_codec_t *codec_type);
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530123typedef int (*audio_check_a2dp_ready_t)(void);
yidongh0515e042017-07-06 15:00:34 +0800124typedef uint16_t (*audio_get_a2dp_sink_latency_t)(void);
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530125typedef int (*audio_is_scrambling_enabled_t)(void);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530126
127enum A2DP_STATE {
128 A2DP_STATE_CONNECTED,
129 A2DP_STATE_STARTED,
130 A2DP_STATE_STOPPED,
131 A2DP_STATE_DISCONNECTED,
132};
133
134/* structure used to update a2dp state machine
135 * to communicate IPC library
136 * to store DSP encoder configuration information
137 */
138struct a2dp_data {
139 struct audio_device *adev;
140 void *bt_lib_handle;
141 audio_stream_open_t audio_stream_open;
142 audio_stream_close_t audio_stream_close;
143 audio_start_stream_t audio_start_stream;
144 audio_stop_stream_t audio_stop_stream;
145 audio_suspend_stream_t audio_suspend_stream;
146 audio_handoff_triggered_t audio_handoff_triggered;
147 clear_a2dpsuspend_flag_t clear_a2dpsuspend_flag;
148 audio_get_codec_config_t audio_get_codec_config;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530149 audio_check_a2dp_ready_t audio_check_a2dp_ready;
yidongh0515e042017-07-06 15:00:34 +0800150 audio_get_a2dp_sink_latency_t audio_get_a2dp_sink_latency;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530151 audio_is_scrambling_enabled_t audio_is_scrambling_enabled;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530152 enum A2DP_STATE bt_state;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530153 enc_codec_t bt_encoder_format;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530154 uint32_t enc_sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530155 uint32_t enc_channels;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530156 bool a2dp_started;
157 bool a2dp_suspended;
158 int a2dp_total_active_session_request;
159 bool is_a2dp_offload_supported;
160 bool is_handoff_in_progress;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700161 bool is_aptx_dual_mono_supported;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530162};
163
164struct a2dp_data a2dp;
165
166/* START of DSP configurable structures
167 * These values should match with DSP interface defintion
168 */
169
170/* AAC encoder configuration structure. */
171typedef struct aac_enc_cfg_t aac_enc_cfg_t;
172
173/* supported enc_mode are AAC_LC, AAC_SBR, AAC_PS
174 * supported aac_fmt_flag are ADTS/RAW
175 * supported channel_cfg are Native mode, Mono , Stereo
176 */
177struct aac_enc_cfg_t {
178 uint32_t enc_format;
179 uint32_t bit_rate;
180 uint32_t enc_mode;
181 uint16_t aac_fmt_flag;
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530182 uint16_t channel_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530183 uint32_t sample_rate;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700184} __packed;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530185
186/* SBC encoder configuration structure. */
187typedef struct sbc_enc_cfg_t sbc_enc_cfg_t;
188
189/* supported num_subbands are 4/8
190 * supported blk_len are 4, 8, 12, 16
191 * supported channel_mode are MONO, STEREO, DUAL_MONO, JOINT_STEREO
192 * supported alloc_method are LOUNDNESS/SNR
193 * supported bit_rate for mono channel is max 320kbps
194 * supported bit rate for stereo channel is max 512 kbps
195 */
196struct sbc_enc_cfg_t{
197 uint32_t enc_format;
198 uint32_t num_subbands;
199 uint32_t blk_len;
200 uint32_t channel_mode;
201 uint32_t alloc_method;
202 uint32_t bit_rate;
203 uint32_t sample_rate;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700204} __packed;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530205
206
207/* supported num_channels are Mono/Stereo
208 * supported channel_mapping for mono is CHANNEL_C
209 * supported channel mapping for stereo is CHANNEL_L and CHANNEL_R
210 * custom size and reserved are not used(for future enhancement)
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700211 */
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530212struct custom_enc_cfg_t
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530213{
214 uint32_t enc_format;
215 uint32_t sample_rate;
216 uint16_t num_channels;
217 uint16_t reserved;
218 uint8_t channel_mapping[8];
219 uint32_t custom_size;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700220} __packed;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530221
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530222struct celt_specific_enc_cfg_t
223{
224 uint32_t bit_rate;
225 uint16_t frame_size;
226 uint16_t complexity;
227 uint16_t prediction_mode;
228 uint16_t vbr_flag;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700229} __packed;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530230
231struct celt_enc_cfg_t
232{
233 struct custom_enc_cfg_t custom_cfg;
234 struct celt_specific_enc_cfg_t celt_cfg;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700235} __packed;
236
237/* sync_mode introduced with APTX V2 libraries
238 * sync mode: 0x0 = stereo sync mode
239 * 0x01 = dual mono sync mode
240 * 0x02 = dual mono with no sync on either L or R codewords
241 */
242struct aptx_v2_enc_cfg_ext_t
243{
244 uint32_t sync_mode;
245} __packed;
246
247/* APTX struct for combining custom enc and V2 fields */
248struct aptx_enc_cfg_t
249{
250 struct custom_enc_cfg_t custom_cfg;
251 struct aptx_v2_enc_cfg_ext_t aptx_v2_cfg;
252} __packed;
253
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530254struct ldac_specific_enc_cfg_t
255{
256 uint32_t bit_rate;
257 uint16_t channel_mode;
258 uint16_t mtu;
259} __packed;
260
261struct ldac_enc_cfg_t
262{
263 struct custom_enc_cfg_t custom_cfg;
264 struct ldac_specific_enc_cfg_t ldac_cfg;
265} __packed;
266
Sachin Mohan Gadag1657c052017-09-13 16:00:27 +0530267/* In LE BT source code uses system/audio.h for below
268 * structure definition. To avoid multiple definition
269 * compilation error for audiohal in LE , masking structure
270 * definition under "LINUX_ENABLED" which is defined only
271 * in LE
272 */
273#ifndef LINUX_ENABLED
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530274/* TODO: Define the following structures only for O using PLATFORM_VERSION */
275/* Information about BT SBC encoder configuration
276 * This data is used between audio HAL module and
277 * BT IPC library to configure DSP encoder
278 */
279typedef struct {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530280 uint32_t subband; /* 4, 8 */
281 uint32_t blk_len; /* 4, 8, 12, 16 */
282 uint16_t sampling_rate; /*44.1khz,48khz*/
283 uint8_t channels; /*0(Mono),1(Dual_mono),2(Stereo),3(JS)*/
284 uint8_t alloc; /*0(Loudness),1(SNR)*/
285 uint8_t min_bitpool; /* 2 */
286 uint8_t max_bitpool; /*53(44.1khz),51 (48khz) */
287 uint32_t bitrate; /* 320kbps to 512kbps */
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530288} audio_sbc_encoder_config;
289
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530290/* Information about BT APTX encoder configuration
291 * This data is used between audio HAL module and
292 * BT IPC library to configure DSP encoder
293 */
294typedef struct {
295 uint16_t sampling_rate;
296 uint8_t channels;
297 uint32_t bitrate;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700298} audio_aptx_default_config;
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530299
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700300typedef struct {
301 uint16_t sampling_rate;
302 uint8_t channels;
303 uint32_t bitrate;
304 uint32_t sync_mode;
305} audio_aptx_dual_mono_config;
306
307typedef union {
308 audio_aptx_default_config *default_cfg;
309 audio_aptx_dual_mono_config *dual_mono_cfg;
310} audio_aptx_encoder_config;
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530311
312/* Information about BT AAC encoder configuration
313 * This data is used between audio HAL module and
314 * BT IPC library to configure DSP encoder
315 */
316typedef struct {
317 uint32_t enc_mode; /* LC, SBR, PS */
318 uint16_t format_flag; /* RAW, ADTS */
319 uint16_t channels; /* 1-Mono, 2-Stereo */
320 uint32_t sampling_rate;
321 uint32_t bitrate;
322} audio_aac_encoder_config;
Sachin Mohan Gadag1657c052017-09-13 16:00:27 +0530323#endif
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530324
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530325/* Information about BT CELT encoder configuration
326 * This data is used between audio HAL module and
327 * BT IPC library to configure DSP encoder
328 */
329typedef struct {
330 uint32_t sampling_rate; /* 32000 - 48000, 48000 */
331 uint16_t channels; /* 1-Mono, 2-Stereo, 2*/
332 uint16_t frame_size; /* 64-128-256-512, 512 */
333 uint16_t complexity; /* 0-10, 1 */
334 uint16_t prediction_mode; /* 0-1-2, 0 */
335 uint16_t vbr_flag; /* 0-1, 0*/
336 uint32_t bitrate; /*32000 - 1536000, 139500*/
337} audio_celt_encoder_config;
338
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530339/* Information about BT LDAC encoder configuration
340 * This data is used between audio HAL module and
341 * BT IPC library to configure DSP encoder
342 */
343typedef struct {
344 uint32_t sampling_rate; /*44100,48000,88200,96000*/
345 uint32_t bit_rate; /*303000,606000,909000(in bits per second)*/
346 uint16_t channel_mode; /* 0, 4, 2, 1*/
347 uint16_t mtu; /*679*/
348} audio_ldac_encoder_config;
349
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530350/*********** END of DSP configurable structures ********************/
351
352/* API to identify DSP encoder captabilities */
353static void a2dp_offload_codec_cap_parser(char *value)
354{
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530355 char *tok = NULL,*saveptr;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530356
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530357 tok = strtok_r(value, "-", &saveptr);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530358 while (tok != NULL) {
359 if (strcmp(tok, "sbc") == 0) {
360 ALOGD("%s: SBC offload supported\n",__func__);
361 a2dp.is_a2dp_offload_supported = true;
362 break;
363 } else if (strcmp(tok, "aptx") == 0) {
364 ALOGD("%s: aptx offload supported\n",__func__);
365 a2dp.is_a2dp_offload_supported = true;
366 break;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700367 } else if (strcmp(tok, "aptxtws") == 0) {
368 ALOGD("%s: aptx dual mono offload supported\n",__func__);
369 a2dp.is_a2dp_offload_supported = true;
370 break;
Naresh Tannirued694c82017-02-07 17:01:28 +0530371 } else if (strcmp(tok, "aptxhd") == 0) {
372 ALOGD("%s: aptx HD offload supported\n",__func__);
373 a2dp.is_a2dp_offload_supported = true;
374 break;
375 } else if (strcmp(tok, "aac") == 0) {
376 ALOGD("%s: aac offload supported\n",__func__);
377 a2dp.is_a2dp_offload_supported = true;
378 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530379 } else if (strcmp(tok, "celt") == 0) {
380 ALOGD("%s: celt offload supported\n",__func__);
381 a2dp.is_a2dp_offload_supported = true;
382 break;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530383 } else if (strcmp(tok, "ldac") == 0) {
384 ALOGD("%s: ldac offload supported\n",__func__);
385 a2dp.is_a2dp_offload_supported = true;
386 break;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530387 }
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530388 tok = strtok_r(NULL, "-", &saveptr);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530389 };
390}
391
392static void update_offload_codec_capabilities()
393{
394 char value[PROPERTY_VALUE_MAX] = {'\0'};
395
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -0700396 property_get("persist.vendor.bt.a2dp_offload_cap", value, "false");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530397 ALOGD("get_offload_codec_capabilities = %s",value);
398 a2dp.is_a2dp_offload_supported =
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -0700399 property_get_bool("persist.vendor.bt.a2dp_offload_cap", false);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530400 if (strcmp(value, "false") != 0)
401 a2dp_offload_codec_cap_parser(value);
402 ALOGD("%s: codec cap = %s",__func__,value);
403}
404
405/* API to open BT IPC library to start IPC communication */
406static void open_a2dp_output()
407{
408 int ret = 0;
409
410 ALOGD(" Open A2DP output start ");
411 if (a2dp.bt_lib_handle == NULL){
412 ALOGD(" Requesting for BT lib handle");
413 a2dp.bt_lib_handle = dlopen(BT_IPC_LIB_NAME, RTLD_NOW);
414
415 if (a2dp.bt_lib_handle == NULL) {
416 ALOGE("%s: DLOPEN failed for %s", __func__, BT_IPC_LIB_NAME);
417 ret = -ENOSYS;
418 goto init_fail;
419 } else {
420 a2dp.audio_stream_open = (audio_stream_open_t)
421 dlsym(a2dp.bt_lib_handle, "audio_stream_open");
422 a2dp.audio_start_stream = (audio_start_stream_t)
423 dlsym(a2dp.bt_lib_handle, "audio_start_stream");
424 a2dp.audio_get_codec_config = (audio_get_codec_config_t)
425 dlsym(a2dp.bt_lib_handle, "audio_get_codec_config");
426 a2dp.audio_suspend_stream = (audio_suspend_stream_t)
427 dlsym(a2dp.bt_lib_handle, "audio_suspend_stream");
428 a2dp.audio_handoff_triggered = (audio_handoff_triggered_t)
429 dlsym(a2dp.bt_lib_handle, "audio_handoff_triggered");
430 a2dp.clear_a2dpsuspend_flag = (clear_a2dpsuspend_flag_t)
431 dlsym(a2dp.bt_lib_handle, "clear_a2dpsuspend_flag");
432 a2dp.audio_stop_stream = (audio_stop_stream_t)
433 dlsym(a2dp.bt_lib_handle, "audio_stop_stream");
434 a2dp.audio_stream_close = (audio_stream_close_t)
435 dlsym(a2dp.bt_lib_handle, "audio_stream_close");
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530436 a2dp.audio_check_a2dp_ready = (audio_check_a2dp_ready_t)
437 dlsym(a2dp.bt_lib_handle,"audio_check_a2dp_ready");
yidongh0515e042017-07-06 15:00:34 +0800438 a2dp.audio_get_a2dp_sink_latency = (audio_get_a2dp_sink_latency_t)
439 dlsym(a2dp.bt_lib_handle,"audio_get_a2dp_sink_latency");
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530440 a2dp.audio_is_scrambling_enabled = (audio_is_scrambling_enabled_t)
441 dlsym(a2dp.bt_lib_handle,"audio_is_scrambling_enabled");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530442 }
443 }
444
445 if (a2dp.bt_lib_handle && a2dp.audio_stream_open) {
446 if (a2dp.bt_state == A2DP_STATE_DISCONNECTED) {
447 ALOGD("calling BT stream open");
448 ret = a2dp.audio_stream_open();
449 if(ret != 0) {
450 ALOGE("Failed to open output stream for a2dp: status %d", ret);
451 goto init_fail;
452 }
453 a2dp.bt_state = A2DP_STATE_CONNECTED;
454 } else {
455 ALOGD("Called a2dp open with improper state, Ignoring request state %d", a2dp.bt_state);
456 }
457 } else {
458 ALOGE("a2dp handle is not identified, Ignoring open request");
459 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
460 goto init_fail;
461 }
462
463init_fail:
464 if(ret != 0 && (a2dp.bt_lib_handle != NULL)) {
465 dlclose(a2dp.bt_lib_handle);
466 a2dp.bt_lib_handle = NULL;
467 }
468}
469
470static int close_a2dp_output()
471{
472 ALOGV("%s\n",__func__);
473 if (!(a2dp.bt_lib_handle && a2dp.audio_stream_close)) {
474 ALOGE("a2dp handle is not identified, Ignoring close request");
475 return -ENOSYS;
476 }
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530477 if (a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530478 ALOGD("calling BT stream close");
479 if(a2dp.audio_stream_close() == false)
480 ALOGE("failed close a2dp control path from BT library");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530481 }
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530482 a2dp.a2dp_started = false;
483 a2dp.a2dp_total_active_session_request = 0;
484 a2dp.a2dp_suspended = false;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530485 a2dp.bt_encoder_format = ENC_CODEC_TYPE_INVALID;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530486 a2dp.enc_sampling_rate = 48000;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530487 a2dp.enc_channels = 2;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530488 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530489
490 return 0;
491}
492
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530493static void a2dp_check_and_set_scrambler()
494{
495 bool scrambler_mode = false;
496 struct mixer_ctl *ctrl_scrambler_mode = NULL;
497 if (a2dp.audio_is_scrambling_enabled && (a2dp.bt_state != A2DP_STATE_DISCONNECTED))
498 scrambler_mode = a2dp.audio_is_scrambling_enabled();
499
500 if (scrambler_mode) {
501 //enable scrambler in dsp
502 ctrl_scrambler_mode = mixer_get_ctl_by_name(a2dp.adev->mixer,
503 MIXER_SCRAMBLER_MODE);
504 if (!ctrl_scrambler_mode) {
505 ALOGE(" ERROR scrambler mode mixer control not identifed");
506 return;
507 } else {
508 if (mixer_ctl_set_value(ctrl_scrambler_mode, 0, true) != 0) {
509 ALOGE("%s: Could not set scrambler mode", __func__);
510 return;
511 }
512 }
513 }
514}
515
516static void a2dp_set_backend_cfg()
517{
518 char *rate_str = NULL, *in_channels = NULL;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530519 uint32_t sampling_rate = a2dp.enc_sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530520 struct mixer_ctl *ctl_sample_rate = NULL, *ctrl_in_channels = NULL;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530521
522 //For LDAC encoder open slimbus port at 96Khz for 48Khz input
523 //and 88.2Khz for 44.1Khz input.
524 if ((a2dp.bt_encoder_format == ENC_CODEC_TYPE_LDAC) &&
525 (sampling_rate == 48000 || sampling_rate == 44100 )) {
526 sampling_rate = sampling_rate *2;
527 }
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530528 //Configure backend sampling rate
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530529 switch (sampling_rate) {
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530530 case 44100:
531 rate_str = "KHZ_44P1";
532 break;
533 case 48000:
534 rate_str = "KHZ_48";
535 break;
536 case 88200:
537 rate_str = "KHZ_88P2";
538 break;
539 case 96000:
540 rate_str = "KHZ_96";
541 break;
542 default:
543 rate_str = "KHZ_48";
544 break;
545 }
546
547 ALOGD("%s: set backend sample rate =%s", __func__, rate_str);
548 ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
549 MIXER_SAMPLE_RATE);
550 if (!ctl_sample_rate) {
551 ALOGE(" ERROR backend sample rate mixer control not identifed");
552 return;
553 } else {
554 if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
555 ALOGE("%s: Failed to set backend sample rate =%s", __func__, rate_str);
556 return;
557 }
558 }
559
560 //Configure AFE input channels
561 switch (a2dp.enc_channels) {
562 case 1:
563 in_channels = "One";
564 break;
565 case 2:
566 default:
567 in_channels = "Two";
568 break;
569 }
570
571 ALOGD("%s: set afe input channels =%d", __func__, a2dp.enc_channels);
572 ctrl_in_channels = mixer_get_ctl_by_name(a2dp.adev->mixer,
573 MIXER_AFE_IN_CHANNELS);
574 if (!ctrl_in_channels) {
575 ALOGE(" ERROR AFE input channels mixer control not identifed");
576 return;
577 } else {
578 if (mixer_ctl_set_enum_by_string(ctrl_in_channels, in_channels) != 0) {
579 ALOGE("%s: Failed to set AFE in channels =%d", __func__, a2dp.enc_channels);
580 return;
581 }
582 }
583}
584
585static void a2dp_reset_backend_cfg()
586{
587 char *rate_str = "KHZ_8", *in_channels = "Zero";
588 struct mixer_ctl *ctl_sample_rate = NULL, *ctrl_in_channels = NULL;
589
590 //reset backend sampling rate
591 ALOGD("%s: reset backend sample rate =%s", __func__, rate_str);
592 ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
593 MIXER_SAMPLE_RATE);
594 if (!ctl_sample_rate) {
595 ALOGE(" ERROR backend sample rate mixer control not identifed");
596 return;
597 } else {
598 if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
599 ALOGE("%s: Failed to reset backend sample rate =%s", __func__, rate_str);
600 return;
601 }
602 }
603
604 //reset AFE input channels
605 ALOGD("%s: reset afe input channels =%s", __func__, in_channels);
606 ctrl_in_channels = mixer_get_ctl_by_name(a2dp.adev->mixer,
607 MIXER_AFE_IN_CHANNELS);
608 if (!ctrl_in_channels) {
609 ALOGE(" ERROR AFE input channels mixer control not identifed");
610 return;
611 } else {
612 if (mixer_ctl_set_enum_by_string(ctrl_in_channels, in_channels) != 0) {
613 ALOGE("%s: Failed to reset AFE in channels =%d", __func__, a2dp.enc_channels);
614 return;
615 }
616 }
617}
618
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530619/* API to configure SBC DSP encoder */
620bool configure_sbc_enc_format(audio_sbc_encoder_config *sbc_bt_cfg)
621{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530622 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530623 struct sbc_enc_cfg_t sbc_dsp_cfg;
624 bool is_configured = false;
625 int ret = 0;
626
627 if(sbc_bt_cfg == NULL)
628 return false;
629
630 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
631 if (!ctl_enc_data) {
632 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
633 is_configured = false;
634 goto fail;
635 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530636 memset(&sbc_dsp_cfg, 0x0, sizeof(struct sbc_enc_cfg_t));
637 sbc_dsp_cfg.enc_format = ENC_MEDIA_FMT_SBC;
638 sbc_dsp_cfg.num_subbands = sbc_bt_cfg->subband;
639 sbc_dsp_cfg.blk_len = sbc_bt_cfg->blk_len;
640 switch(sbc_bt_cfg->channels) {
641 case 0:
642 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_MONO;
643 break;
644 case 1:
645 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO;
646 break;
647 case 3:
648 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO;
649 break;
650 case 2:
651 default:
652 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_STEREO;
653 break;
654 }
655 if (sbc_bt_cfg->alloc)
656 sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS;
657 else
658 sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR;
659 sbc_dsp_cfg.bit_rate = sbc_bt_cfg->bitrate;
660 sbc_dsp_cfg.sample_rate = sbc_bt_cfg->sampling_rate;
661 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&sbc_dsp_cfg,
662 sizeof(struct sbc_enc_cfg_t));
663 if (ret != 0) {
664 ALOGE("%s: failed to set SBC encoder config", __func__);
665 is_configured = false;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530666 goto fail;
667 }
668 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
669 MIXER_ENC_BIT_FORMAT);
670 if (!ctrl_bit_format) {
671 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
672 is_configured = false;
673 goto fail;
674 }
675 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
676 if (ret != 0) {
677 ALOGE("%s: Failed to set bit format to encoder", __func__);
678 is_configured = false;
679 goto fail;
680 }
681 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530682 a2dp.bt_encoder_format = ENC_CODEC_TYPE_SBC;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530683 a2dp.enc_sampling_rate = sbc_bt_cfg->sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530684
685 if (sbc_dsp_cfg.channel_mode == MEDIA_FMT_SBC_CHANNEL_MODE_MONO)
686 a2dp.enc_channels = 1;
687 else
688 a2dp.enc_channels = 2;
689
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530690 ALOGV("Successfully updated SBC enc format with samplingrate: %d channelmode:%d",
691 sbc_dsp_cfg.sample_rate, sbc_dsp_cfg.channel_mode);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530692fail:
693 return is_configured;
694}
695
696/* API to configure APTX DSP encoder */
697bool configure_aptx_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
698{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530699 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700700 struct aptx_enc_cfg_t aptx_dsp_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530701 bool is_configured = false;
702 int ret = 0;
703
704 if(aptx_bt_cfg == NULL)
705 return false;
706
707 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
708 if (!ctl_enc_data) {
709 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
710 is_configured = false;
711 goto fail;
712 }
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700713
714 memset(&aptx_dsp_cfg, 0x0, sizeof(struct aptx_enc_cfg_t));
715 aptx_dsp_cfg.custom_cfg.enc_format = ENC_MEDIA_FMT_APTX;
716
717 if (!a2dp.is_aptx_dual_mono_supported) {
718 aptx_dsp_cfg.custom_cfg.sample_rate = aptx_bt_cfg->default_cfg->sampling_rate;
719 aptx_dsp_cfg.custom_cfg.num_channels = aptx_bt_cfg->default_cfg->channels;
720 } else {
721 aptx_dsp_cfg.custom_cfg.sample_rate = aptx_bt_cfg->dual_mono_cfg->sampling_rate;
722 aptx_dsp_cfg.custom_cfg.num_channels = aptx_bt_cfg->dual_mono_cfg->channels;
723 aptx_dsp_cfg.aptx_v2_cfg.sync_mode = aptx_bt_cfg->dual_mono_cfg->sync_mode;
724 }
725
726 switch(aptx_dsp_cfg.custom_cfg.num_channels) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530727 case 1:
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700728 aptx_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_C;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530729 break;
730 case 2:
731 default:
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700732 aptx_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
733 aptx_dsp_cfg.custom_cfg.channel_mapping[1] = PCM_CHANNEL_R;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530734 break;
735 }
736 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700737 sizeof(struct aptx_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530738 if (ret != 0) {
739 ALOGE("%s: Failed to set APTX encoder config", __func__);
740 is_configured = false;
741 goto fail;
742 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530743 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
744 MIXER_ENC_BIT_FORMAT);
745 if (!ctrl_bit_format) {
746 ALOGE("ERROR bit format CONFIG data mixer control not identifed");
747 is_configured = false;
748 goto fail;
749 } else {
750 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
751 if (ret != 0) {
752 ALOGE("%s: Failed to set bit format to encoder", __func__);
753 is_configured = false;
754 goto fail;
755 }
756 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530757 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530758 a2dp.bt_encoder_format = ENC_CODEC_TYPE_APTX;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530759 a2dp.enc_channels = aptx_dsp_cfg.custom_cfg.num_channels;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700760 if (!a2dp.is_aptx_dual_mono_supported) {
761 a2dp.enc_sampling_rate = aptx_bt_cfg->default_cfg->sampling_rate;
762 ALOGV("Successfully updated APTX enc format with samplingrate: %d \
763 channels:%d", aptx_dsp_cfg.custom_cfg.sample_rate,
764 aptx_dsp_cfg.custom_cfg.num_channels);
765 } else {
766 a2dp.enc_sampling_rate = aptx_bt_cfg->dual_mono_cfg->sampling_rate;
767 ALOGV("Successfully updated APTX dual mono enc format with \
768 samplingrate: %d channels:%d syncmode %d",
769 aptx_dsp_cfg.custom_cfg.sample_rate,
770 aptx_dsp_cfg.custom_cfg.num_channels,
771 aptx_dsp_cfg.aptx_v2_cfg.sync_mode);
772 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530773fail:
774 return is_configured;
775}
776
777/* API to configure APTX HD DSP encoder
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530778 */
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700779bool configure_aptx_hd_enc_format(audio_aptx_default_config *aptx_bt_cfg)
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530780{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530781 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530782 struct custom_enc_cfg_t aptx_dsp_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530783 bool is_configured = false;
784 int ret = 0;
785
786 if(aptx_bt_cfg == NULL)
787 return false;
788
789 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
790 if (!ctl_enc_data) {
791 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
792 is_configured = false;
793 goto fail;
794 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530795
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530796 memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530797 aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX_HD;
798 aptx_dsp_cfg.sample_rate = aptx_bt_cfg->sampling_rate;
799 aptx_dsp_cfg.num_channels = aptx_bt_cfg->channels;
800 switch(aptx_dsp_cfg.num_channels) {
801 case 1:
802 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_C;
803 break;
804 case 2:
805 default:
806 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_L;
807 aptx_dsp_cfg.channel_mapping[1] = PCM_CHANNEL_R;
808 break;
809 }
810 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530811 sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530812 if (ret != 0) {
813 ALOGE("%s: Failed to set APTX HD encoder config", __func__);
814 is_configured = false;
815 goto fail;
816 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530817 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
818 if (!ctrl_bit_format) {
819 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
820 is_configured = false;
821 goto fail;
822 }
823 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S24_LE");
824 if (ret != 0) {
825 ALOGE("%s: Failed to set APTX HD encoder config", __func__);
826 is_configured = false;
827 goto fail;
828 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530829 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530830 a2dp.bt_encoder_format = ENC_CODEC_TYPE_APTX_HD;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530831 a2dp.enc_sampling_rate = aptx_bt_cfg->sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530832 a2dp.enc_channels = aptx_bt_cfg->channels;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530833 ALOGV("Successfully updated APTX HD encformat with samplingrate: %d channels:%d",
834 aptx_dsp_cfg.sample_rate, aptx_dsp_cfg.num_channels);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530835fail:
836 return is_configured;
837}
838
839/* API to configure AAC DSP encoder */
840bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg)
841{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530842 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530843 struct aac_enc_cfg_t aac_dsp_cfg;
844 bool is_configured = false;
845 int ret = 0;
846
847 if(aac_bt_cfg == NULL)
848 return false;
849
850 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
851 if (!ctl_enc_data) {
852 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
853 is_configured = false;
854 goto fail;
855 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530856 memset(&aac_dsp_cfg, 0x0, sizeof(struct aac_enc_cfg_t));
857 aac_dsp_cfg.enc_format = ENC_MEDIA_FMT_AAC;
858 aac_dsp_cfg.bit_rate = aac_bt_cfg->bitrate;
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530859 aac_dsp_cfg.sample_rate = aac_bt_cfg->sampling_rate;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530860 switch(aac_bt_cfg->enc_mode) {
861 case 0:
862 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC;
863 break;
864 case 2:
865 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS;
866 break;
867 case 1:
868 default:
869 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR;
870 break;
871 }
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530872 aac_dsp_cfg.aac_fmt_flag = aac_bt_cfg->format_flag;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530873 aac_dsp_cfg.channel_cfg = aac_bt_cfg->channels;
874 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aac_dsp_cfg,
875 sizeof(struct aac_enc_cfg_t));
876 if (ret != 0) {
877 ALOGE("%s: failed to set SBC encoder config", __func__);
878 is_configured = false;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530879 goto fail;
880 }
881 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
882 MIXER_ENC_BIT_FORMAT);
883 if (!ctrl_bit_format) {
884 is_configured = false;
885 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
886 goto fail;
887 }
888 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
889 if (ret != 0) {
890 ALOGE("%s: Failed to set bit format to encoder", __func__);
891 is_configured = false;
892 goto fail;
893 }
894 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530895 a2dp.bt_encoder_format = ENC_CODEC_TYPE_AAC;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530896 a2dp.enc_sampling_rate = aac_bt_cfg->sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530897 a2dp.enc_channels = aac_bt_cfg->channels;;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530898 ALOGV("Successfully updated AAC enc format with samplingrate: %d channels:%d",
899 aac_dsp_cfg.sample_rate, aac_dsp_cfg.channel_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530900fail:
901 return is_configured;
902}
903
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530904bool configure_celt_enc_format(audio_celt_encoder_config *celt_bt_cfg)
905{
906 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
907 struct celt_enc_cfg_t celt_dsp_cfg;
908 bool is_configured = false;
909 int ret = 0;
910 if(celt_bt_cfg == NULL)
911 return false;
912
913 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
914 if (!ctl_enc_data) {
915 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
916 is_configured = false;
917 goto fail;
918 }
919 memset(&celt_dsp_cfg, 0x0, sizeof(struct celt_enc_cfg_t));
920
921 celt_dsp_cfg.custom_cfg.enc_format = ENC_MEDIA_FMT_CELT;
922 celt_dsp_cfg.custom_cfg.sample_rate = celt_bt_cfg->sampling_rate;
923 celt_dsp_cfg.custom_cfg.num_channels = celt_bt_cfg->channels;
924 switch(celt_dsp_cfg.custom_cfg.num_channels) {
925 case 1:
926 celt_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_C;
927 break;
928 case 2:
929 default:
930 celt_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
931 celt_dsp_cfg.custom_cfg.channel_mapping[1] = PCM_CHANNEL_R;
932 break;
933 }
934
935 celt_dsp_cfg.custom_cfg.custom_size = sizeof(struct celt_enc_cfg_t);
936
937 celt_dsp_cfg.celt_cfg.frame_size = celt_bt_cfg->frame_size;
938 celt_dsp_cfg.celt_cfg.complexity = celt_bt_cfg->complexity;
939 celt_dsp_cfg.celt_cfg.prediction_mode = celt_bt_cfg->prediction_mode;
940 celt_dsp_cfg.celt_cfg.vbr_flag = celt_bt_cfg->vbr_flag;
941 celt_dsp_cfg.celt_cfg.bit_rate = celt_bt_cfg->bitrate;
942
943 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&celt_dsp_cfg,
944 sizeof(struct celt_enc_cfg_t));
945 if (ret != 0) {
946 ALOGE("%s: Failed to set CELT encoder config", __func__);
947 is_configured = false;
948 goto fail;
949 }
950 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
951 if (!ctrl_bit_format) {
952 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
953 is_configured = false;
954 goto fail;
955 }
956 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
957 if (ret != 0) {
958 ALOGE("%s: Failed to set bit format to encoder", __func__);
959 is_configured = false;
960 goto fail;
961 }
962 is_configured = true;
963 a2dp.bt_encoder_format = ENC_CODEC_TYPE_CELT;
964 a2dp.enc_sampling_rate = celt_bt_cfg->sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530965 a2dp.enc_channels = celt_bt_cfg->channels;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530966 ALOGV("Successfully updated CELT encformat with samplingrate: %d channels:%d",
967 celt_dsp_cfg.custom_cfg.sample_rate, celt_dsp_cfg.custom_cfg.num_channels);
968fail:
969 return is_configured;
970}
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530971
972bool configure_ldac_enc_format(audio_ldac_encoder_config *ldac_bt_cfg)
973{
974 struct mixer_ctl *ldac_enc_data = NULL, *ctrl_bit_format = NULL;
975 struct ldac_enc_cfg_t ldac_dsp_cfg;
976 bool is_configured = false;
977 int ret = 0;
978 if(ldac_bt_cfg == NULL)
979 return false;
980
981 ldac_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
982 if (!ldac_enc_data) {
983 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
984 is_configured = false;
985 goto fail;
986 }
987 memset(&ldac_dsp_cfg, 0x0, sizeof(struct ldac_enc_cfg_t));
988
989 ldac_dsp_cfg.custom_cfg.enc_format = ENC_MEDIA_FMT_LDAC;
990 ldac_dsp_cfg.custom_cfg.sample_rate = ldac_bt_cfg->sampling_rate;
991 ldac_dsp_cfg.ldac_cfg.channel_mode = ldac_bt_cfg->channel_mode;
992 switch(ldac_dsp_cfg.ldac_cfg.channel_mode) {
993 case 4:
994 ldac_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_C;
995 ldac_dsp_cfg.custom_cfg.num_channels = 1;
996 break;
997 case 2:
998 case 1:
999 default:
1000 ldac_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
1001 ldac_dsp_cfg.custom_cfg.channel_mapping[1] = PCM_CHANNEL_R;
1002 ldac_dsp_cfg.custom_cfg.num_channels = 2;
1003 break;
1004 }
1005
1006 ldac_dsp_cfg.custom_cfg.custom_size = sizeof(struct ldac_enc_cfg_t);
1007 ldac_dsp_cfg.ldac_cfg.mtu = ldac_bt_cfg->mtu;
1008 ldac_dsp_cfg.ldac_cfg.bit_rate = ldac_bt_cfg->bit_rate;
1009 ret = mixer_ctl_set_array(ldac_enc_data, (void *)&ldac_dsp_cfg,
1010 sizeof(struct ldac_enc_cfg_t));
1011 if (ret != 0) {
1012 ALOGE("%s: Failed to set LDAC encoder config", __func__);
1013 is_configured = false;
1014 goto fail;
1015 }
1016 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
1017 if (!ctrl_bit_format) {
1018 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
1019 is_configured = false;
1020 goto fail;
1021 }
1022 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
1023 if (ret != 0) {
1024 ALOGE("%s: Failed to set bit format to encoder", __func__);
1025 is_configured = false;
1026 goto fail;
1027 }
1028 is_configured = true;
1029 a2dp.bt_encoder_format = ENC_CODEC_TYPE_LDAC;
1030 a2dp.enc_sampling_rate = ldac_bt_cfg->sampling_rate;
1031 a2dp.enc_channels = ldac_dsp_cfg.custom_cfg.num_channels;
1032 ALOGV("Successfully updated LDAC encformat with samplingrate: %d channels:%d",
1033 ldac_dsp_cfg.custom_cfg.sample_rate, ldac_dsp_cfg.custom_cfg.num_channels);
1034fail:
1035 return is_configured;
1036}
1037
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301038bool configure_a2dp_encoder_format()
1039{
1040 void *codec_info = NULL;
1041 uint8_t multi_cast = 0, num_dev = 1;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301042 enc_codec_t codec_type = ENC_CODEC_TYPE_INVALID;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301043 bool is_configured = false;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001044 audio_aptx_encoder_config aptx_encoder_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301045
1046 if (!a2dp.audio_get_codec_config) {
1047 ALOGE(" a2dp handle is not identified, ignoring a2dp encoder config");
1048 return false;
1049 }
1050 ALOGD("configure_a2dp_encoder_format start");
1051 codec_info = a2dp.audio_get_codec_config(&multi_cast, &num_dev,
1052 &codec_type);
1053
1054 switch(codec_type) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301055 case ENC_CODEC_TYPE_SBC:
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301056 ALOGD(" Received SBC encoder supported BT device");
1057 is_configured =
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001058 configure_sbc_enc_format((audio_sbc_encoder_config *)codec_info);
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301059 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301060 case ENC_CODEC_TYPE_APTX:
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301061 ALOGD(" Received APTX encoder supported BT device");
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001062 a2dp.is_aptx_dual_mono_supported = false;
1063 aptx_encoder_cfg.default_cfg = (audio_aptx_default_config *)codec_info;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301064 is_configured =
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001065 configure_aptx_enc_format(&aptx_encoder_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301066 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301067 case ENC_CODEC_TYPE_APTX_HD:
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301068 ALOGD(" Received APTX HD encoder supported BT device");
1069 is_configured =
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001070 configure_aptx_hd_enc_format((audio_aptx_default_config *)codec_info);
1071 break;
1072 case ENC_CODEC_TYPE_APTX_DUAL_MONO:
1073 ALOGD(" Received APTX dual mono encoder supported BT device");
1074 a2dp.is_aptx_dual_mono_supported = true;
1075 aptx_encoder_cfg.dual_mono_cfg = (audio_aptx_dual_mono_config *)codec_info;
1076 is_configured =
1077 configure_aptx_enc_format(&aptx_encoder_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301078 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301079 case ENC_CODEC_TYPE_AAC:
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301080 ALOGD(" Received AAC encoder supported BT device");
1081 is_configured =
1082 configure_aac_enc_format((audio_aac_encoder_config *)codec_info);
1083 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301084 case ENC_CODEC_TYPE_CELT:
1085 ALOGD(" Received CELT encoder supported BT device");
1086 is_configured =
1087 configure_celt_enc_format((audio_celt_encoder_config *)codec_info);
1088 break;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +05301089 case ENC_CODEC_TYPE_LDAC:
1090 ALOGD(" Received LDAC encoder supported BT device");
1091 is_configured =
1092 configure_ldac_enc_format((audio_ldac_encoder_config *)codec_info);
1093 break;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301094 default:
1095 ALOGD(" Received Unsupported encoder formar");
1096 is_configured = false;
1097 break;
1098 }
1099 return is_configured;
1100}
1101
1102int audio_extn_a2dp_start_playback()
1103{
1104 int ret = 0;
1105
1106 ALOGD("audio_extn_a2dp_start_playback start");
1107
1108 if(!(a2dp.bt_lib_handle && a2dp.audio_start_stream
1109 && a2dp.audio_get_codec_config)) {
1110 ALOGE("a2dp handle is not identified, Ignoring start request");
1111 return -ENOSYS;
1112 }
1113
1114 if(a2dp.a2dp_suspended == true) {
1115 //session will be restarted after suspend completion
1116 ALOGD("a2dp start requested during suspend state");
Naresh Tannirucd2353e2016-08-19 00:37:25 +05301117 return -ENOSYS;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301118 }
1119
1120 if (!a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
1121 ALOGD("calling BT module stream start");
1122 /* This call indicates BT IPC lib to start playback */
1123 ret = a2dp.audio_start_stream();
1124 ALOGE("BT controller start return = %d",ret);
1125 if (ret != 0 ) {
1126 ALOGE("BT controller start failed");
1127 a2dp.a2dp_started = false;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301128 } else {
1129 if(configure_a2dp_encoder_format() == true) {
1130 a2dp.a2dp_started = true;
1131 ret = 0;
1132 ALOGD("Start playback successful to BT library");
1133 } else {
1134 ALOGD(" unable to configure DSP encoder");
1135 a2dp.a2dp_started = false;
1136 ret = -ETIMEDOUT;
1137 }
1138 }
1139 }
1140
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +05301141 if (a2dp.a2dp_started) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301142 a2dp.a2dp_total_active_session_request++;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +05301143 a2dp_check_and_set_scrambler();
1144 a2dp_set_backend_cfg();
1145 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301146
1147 ALOGD("start A2DP playback total active sessions :%d",
1148 a2dp.a2dp_total_active_session_request);
1149 return ret;
1150}
1151
Naresh Tanniru03f9dd52016-10-19 18:46:22 +05301152static void reset_a2dp_enc_config_params()
1153{
1154 int ret =0;
1155
1156 struct mixer_ctl *ctl_enc_config, *ctrl_bit_format;
1157 struct sbc_enc_cfg_t dummy_reset_config;
1158
1159 memset(&dummy_reset_config, 0x0, sizeof(struct sbc_enc_cfg_t));
1160 ctl_enc_config = mixer_get_ctl_by_name(a2dp.adev->mixer,
1161 MIXER_ENC_CONFIG_BLOCK);
1162 if (!ctl_enc_config) {
1163 ALOGE(" ERROR a2dp encoder format mixer control not identifed");
1164 } else {
1165 ret = mixer_ctl_set_array(ctl_enc_config, (void *)&dummy_reset_config,
1166 sizeof(struct sbc_enc_cfg_t));
1167 a2dp.bt_encoder_format = ENC_MEDIA_FMT_NONE;
1168 }
1169 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
1170 MIXER_ENC_BIT_FORMAT);
1171 if (!ctrl_bit_format) {
1172 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
1173 } else {
1174 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
1175 if (ret != 0) {
1176 ALOGE("%s: Failed to set bit format to encoder", __func__);
1177 }
1178 }
1179}
1180
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301181int audio_extn_a2dp_stop_playback()
1182{
1183 int ret =0;
1184
1185 ALOGV("audio_extn_a2dp_stop_playback start");
1186 if(!(a2dp.bt_lib_handle && a2dp.audio_stop_stream)) {
1187 ALOGE("a2dp handle is not identified, Ignoring start request");
1188 return -ENOSYS;
1189 }
1190
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301191 if (a2dp.a2dp_total_active_session_request > 0)
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301192 a2dp.a2dp_total_active_session_request--;
1193
1194 if ( a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301195 ALOGV("calling BT module stream stop");
1196 ret = a2dp.audio_stop_stream();
1197 if (ret < 0)
1198 ALOGE("stop stream to BT IPC lib failed");
1199 else
1200 ALOGV("stop steam to BT IPC lib successful");
Naresh Tanniru03f9dd52016-10-19 18:46:22 +05301201 reset_a2dp_enc_config_params();
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +05301202 a2dp_reset_backend_cfg();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301203 }
1204 if(!a2dp.a2dp_total_active_session_request)
1205 a2dp.a2dp_started = false;
1206 ALOGD("Stop A2DP playback total active sessions :%d",
1207 a2dp.a2dp_total_active_session_request);
1208 return 0;
1209}
1210
1211void audio_extn_a2dp_set_parameters(struct str_parms *parms)
1212{
1213 int ret, val;
1214 char value[32]={0};
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301215 struct audio_usecase *uc_info;
1216 struct listnode *node;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301217
1218 if(a2dp.is_a2dp_offload_supported == false) {
1219 ALOGV("no supported encoders identified,ignoring a2dp setparam");
1220 return;
1221 }
1222
1223 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
1224 sizeof(value));
1225 if( ret >= 0) {
1226 val = atoi(value);
1227 if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
1228 ALOGV("Received device connect request for A2DP");
1229 open_a2dp_output();
1230 }
1231 goto param_handled;
1232 }
1233
1234 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value,
1235 sizeof(value));
1236
1237 if( ret >= 0) {
1238 val = atoi(value);
1239 if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
1240 ALOGV("Received device dis- connect request");
Naresh Tanniru03f9dd52016-10-19 18:46:22 +05301241 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301242 close_a2dp_output();
1243 }
1244 goto param_handled;
1245 }
1246
1247 ret = str_parms_get_str(parms, "A2dpSuspended", value, sizeof(value));
1248 if (ret >= 0) {
1249 if (a2dp.bt_lib_handle && (a2dp.bt_state != A2DP_STATE_DISCONNECTED) ) {
1250 if ((!strncmp(value,"true",sizeof(value)))) {
1251 ALOGD("Setting a2dp to suspend state");
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301252 a2dp.a2dp_suspended = true;
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301253 list_for_each(node, &a2dp.adev->usecase_list) {
1254 uc_info = node_to_item(node, struct audio_usecase, list);
Zhou Songc66eb7e2017-08-08 18:29:07 +08001255 if (uc_info->type == PCM_PLAYBACK &&
1256 (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301257 pthread_mutex_unlock(&a2dp.adev->lock);
1258 check_a2dp_restore(a2dp.adev, uc_info->stream.out, false);
1259 pthread_mutex_lock(&a2dp.adev->lock);
1260 }
1261 }
Naresh Tanniru03f9dd52016-10-19 18:46:22 +05301262 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301263 if(a2dp.audio_suspend_stream)
1264 a2dp.audio_suspend_stream();
1265 } else if (a2dp.a2dp_suspended == true) {
1266 ALOGD("Resetting a2dp suspend state");
Zhou Song10617ed2017-05-26 13:28:48 +08001267 struct audio_usecase *uc_info;
1268 struct listnode *node;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301269 if(a2dp.clear_a2dpsuspend_flag)
1270 a2dp.clear_a2dpsuspend_flag();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301271 a2dp.a2dp_suspended = false;
Naresh Tanniru649871a2016-11-04 18:08:32 +05301272 /*
1273 * It is possible that before suspend,a2dp sessions can be active
1274 * for example during music + voice activation concurrency
1275 * a2dp suspend will be called & BT will change to sco mode
1276 * though music is paused as a part of voice activation
1277 * compress session close happens only after pause timeout(10secs)
1278 * so if resume request comes before pause timeout as a2dp session
1279 * is already active IPC start will not be called from APM/audio_hw
1280 * Fix is to call a2dp start for IPC library post suspend
1281 * based on number of active session count
1282 */
1283 if (a2dp.a2dp_total_active_session_request > 0) {
1284 ALOGD(" Calling IPC lib start post suspend state");
1285 if(a2dp.audio_start_stream) {
1286 ret = a2dp.audio_start_stream();
1287 if (ret != 0) {
1288 ALOGE("BT controller start failed");
1289 a2dp.a2dp_started = false;
1290 }
1291 }
1292 }
Zhou Song10617ed2017-05-26 13:28:48 +08001293 list_for_each(node, &a2dp.adev->usecase_list) {
1294 uc_info = node_to_item(node, struct audio_usecase, list);
Zhou Songc66eb7e2017-08-08 18:29:07 +08001295 if (uc_info->type == PCM_PLAYBACK &&
1296 (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301297 pthread_mutex_unlock(&a2dp.adev->lock);
1298 check_a2dp_restore(a2dp.adev, uc_info->stream.out, true);
1299 pthread_mutex_lock(&a2dp.adev->lock);
1300 }
Zhou Song10617ed2017-05-26 13:28:48 +08001301 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301302 }
1303 }
1304 goto param_handled;
1305 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301306param_handled:
1307 ALOGV("end of a2dp setparam");
1308}
1309
Naresh Tannirucd2353e2016-08-19 00:37:25 +05301310void audio_extn_a2dp_set_handoff_mode(bool is_on)
1311{
1312 a2dp.is_handoff_in_progress = is_on;
1313}
1314
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301315bool audio_extn_a2dp_is_force_device_switch()
1316{
1317 //During encoder reconfiguration mode, force a2dp device switch
Ashish Jainc597d102016-12-12 10:31:34 +05301318 // Or if a2dp device is selected but earlier start failed ( as a2dp
1319 // was suspended, force retry.
1320 return a2dp.is_handoff_in_progress || !a2dp.a2dp_started;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301321}
1322
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301323void audio_extn_a2dp_get_apptype_params(uint32_t *sample_rate,
1324 uint32_t *bit_width)
1325{
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301326 if(a2dp.bt_encoder_format == ENC_CODEC_TYPE_APTX_HD)
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301327 *bit_width = 24;
1328 else
1329 *bit_width = 16;
1330 *sample_rate = a2dp.enc_sampling_rate;
1331}
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301332
1333bool audio_extn_a2dp_is_ready()
1334{
1335 bool ret = false;
1336
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301337 if (a2dp.a2dp_suspended)
1338 return ret;
1339
Aniket Kumar Lata901bcb82017-03-10 15:42:46 -08001340 if ((a2dp.bt_state != A2DP_STATE_DISCONNECTED) &&
1341 (a2dp.is_a2dp_offload_supported) &&
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301342 (a2dp.audio_check_a2dp_ready))
1343 ret = a2dp.audio_check_a2dp_ready();
1344 return ret;
1345}
1346
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301347bool audio_extn_a2dp_is_suspended()
1348{
1349 return a2dp.a2dp_suspended;
1350}
1351
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301352void audio_extn_a2dp_init (void *adev)
1353{
1354 a2dp.adev = (struct audio_device*)adev;
1355 a2dp.bt_lib_handle = NULL;
1356 a2dp.a2dp_started = false;
1357 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
1358 a2dp.a2dp_total_active_session_request = 0;
1359 a2dp.a2dp_suspended = false;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301360 a2dp.bt_encoder_format = ENC_CODEC_TYPE_INVALID;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301361 a2dp.enc_sampling_rate = 48000;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301362 a2dp.is_a2dp_offload_supported = false;
1363 a2dp.is_handoff_in_progress = false;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001364 a2dp.is_aptx_dual_mono_supported = false;
kunleiz5a127262017-09-08 14:47:48 +08001365 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301366 update_offload_codec_capabilities();
1367}
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001368
1369uint32_t audio_extn_a2dp_get_encoder_latency()
1370{
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001371 uint32_t latency = 0;
1372 int avsync_runtime_prop = 0;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +05301373 int sbc_offset = 0, aptx_offset = 0, aptxhd_offset = 0,
1374 aac_offset = 0, celt_offset = 0, ldac_offset = 0;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001375 char value[PROPERTY_VALUE_MAX];
1376
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001377 memset(value, '\0', sizeof(char)*PROPERTY_VALUE_MAX);
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -07001378 avsync_runtime_prop = property_get("vendor.audio.a2dp.codec.latency", value, NULL);
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001379 if (avsync_runtime_prop > 0) {
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +05301380 if (sscanf(value, "%d/%d/%d/%d/%d%d",
1381 &sbc_offset, &aptx_offset, &aptxhd_offset, &aac_offset, &celt_offset, &ldac_offset) != 6) {
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001382 ALOGI("Failed to parse avsync offset params from '%s'.", value);
1383 avsync_runtime_prop = 0;
1384 }
1385 }
1386
yidongh0515e042017-07-06 15:00:34 +08001387 uint32_t slatency = 0;
1388 if (a2dp.audio_get_a2dp_sink_latency && a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
1389 slatency = a2dp.audio_get_a2dp_sink_latency();
1390 }
1391
Aniket Kumar Latafaaffde2017-03-22 19:18:15 -07001392 switch(a2dp.bt_encoder_format) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301393 case ENC_CODEC_TYPE_SBC:
yidongh0515e042017-07-06 15:00:34 +08001394 latency = (avsync_runtime_prop > 0) ? sbc_offset : ENCODER_LATENCY_SBC;
1395 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_SBC : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001396 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301397 case ENC_CODEC_TYPE_APTX:
yidongh0515e042017-07-06 15:00:34 +08001398 latency = (avsync_runtime_prop > 0) ? aptx_offset : ENCODER_LATENCY_APTX;
1399 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001400 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301401 case ENC_CODEC_TYPE_APTX_HD:
yidongh0515e042017-07-06 15:00:34 +08001402 latency = (avsync_runtime_prop > 0) ? aptxhd_offset : ENCODER_LATENCY_APTX_HD;
1403 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX_HD : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001404 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301405 case ENC_CODEC_TYPE_AAC:
yidongh0515e042017-07-06 15:00:34 +08001406 latency = (avsync_runtime_prop > 0) ? aac_offset : ENCODER_LATENCY_AAC;
1407 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_AAC : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001408 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301409 case ENC_CODEC_TYPE_CELT:
1410 latency = (avsync_runtime_prop > 0) ? celt_offset : ENCODER_LATENCY_CELT;
1411 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_CELT : slatency;
1412 break;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +05301413 case ENC_CODEC_TYPE_LDAC:
1414 latency = (avsync_runtime_prop > 0) ? ldac_offset : ENCODER_LATENCY_LDAC;
1415 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_LDAC : slatency;
1416 break;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001417 default:
1418 latency = 200;
1419 break;
1420 }
1421 return latency;
1422}
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301423#endif // SPLIT_A2DP_ENABLED