blob: 2c0c53b6e41a11c428198d37338acc3b67d1439a [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
Naresh Tanniru9d027a62015-03-13 01:32:10 +053059#define MEDIA_FMT_AAC_AOT_LC 2
60#define MEDIA_FMT_AAC_AOT_SBR 5
61#define MEDIA_FMT_AAC_AOT_PS 29
Naresh Tanniru9d027a62015-03-13 01:32:10 +053062#define PCM_CHANNEL_L 1
63#define PCM_CHANNEL_R 2
64#define PCM_CHANNEL_C 3
65#define MEDIA_FMT_SBC_CHANNEL_MODE_MONO 1
66#define MEDIA_FMT_SBC_CHANNEL_MODE_STEREO 2
67#define MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO 8
68#define MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO 9
69#define MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS 0
70#define MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR 1
71#define MIXER_ENC_CONFIG_BLOCK "SLIM_7_RX Encoder Config"
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +053072#define MIXER_ENC_BIT_FORMAT "AFE Input Bit Format"
Naresh Tanniru9d027a62015-03-13 01:32:10 +053073#define MIXER_ENC_FMT_SBC "SBC"
74#define MIXER_ENC_FMT_AAC "AAC"
75#define MIXER_ENC_FMT_APTX "APTX"
76#define MIXER_ENC_FMT_APTXHD "APTXHD"
77#define MIXER_ENC_FMT_NONE "NONE"
yidongh0515e042017-07-06 15:00:34 +080078#define ENCODER_LATENCY_SBC 10
79#define ENCODER_LATENCY_APTX 40
80#define ENCODER_LATENCY_APTX_HD 20
81#define ENCODER_LATENCY_AAC 70
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +053082//To Do: Fine Tune Encoder CELT latency.
83#define ENCODER_LATENCY_CELT 40
yidongh0515e042017-07-06 15:00:34 +080084#define DEFAULT_SINK_LATENCY_SBC 140
85#define DEFAULT_SINK_LATENCY_APTX 160
86#define DEFAULT_SINK_LATENCY_APTX_HD 180
87#define DEFAULT_SINK_LATENCY_AAC 180
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +053088//To Do: Fine Tune Default CELT Latency.
89#define DEFAULT_SINK_LATENCY_CELT 180
90
91/*
92 * Below enum values are extended from audio_base.h to
93 * to keep encoder codec type local to bthost_ipc
94 * and audio_hal as these are intended only for handshake
95 * between IPC lib and Audio HAL.
96 */
97typedef enum {
98 ENC_CODEC_TYPE_INVALID = 4294967295u, // 0xFFFFFFFFUL
99 ENC_CODEC_TYPE_AAC = 67108864u, // 0x04000000UL
100 ENC_CODEC_TYPE_SBC = 520093696u, // 0x1F000000UL
101 ENC_CODEC_TYPE_APTX = 536870912u, // 0x20000000UL
102 ENC_CODEC_TYPE_APTX_HD = 553648128u, // 0x21000000UL
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700103 ENC_CODEC_TYPE_APTX_DUAL_MONO = 570425344u, // 0x22000000UL
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530104 ENC_CODEC_TYPE_CELT = 603979776u, // 0x24000000UL
105}enc_codec_t;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530106
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530107typedef int (*audio_stream_open_t)(void);
108typedef int (*audio_stream_close_t)(void);
109typedef int (*audio_start_stream_t)(void);
110typedef int (*audio_stop_stream_t)(void);
111typedef int (*audio_suspend_stream_t)(void);
112typedef void (*audio_handoff_triggered_t)(void);
113typedef void (*clear_a2dpsuspend_flag_t)(void);
114typedef void * (*audio_get_codec_config_t)(uint8_t *multicast_status,uint8_t *num_dev,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530115 enc_codec_t *codec_type);
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530116typedef int (*audio_check_a2dp_ready_t)(void);
yidongh0515e042017-07-06 15:00:34 +0800117typedef uint16_t (*audio_get_a2dp_sink_latency_t)(void);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530118
119enum A2DP_STATE {
120 A2DP_STATE_CONNECTED,
121 A2DP_STATE_STARTED,
122 A2DP_STATE_STOPPED,
123 A2DP_STATE_DISCONNECTED,
124};
125
126/* structure used to update a2dp state machine
127 * to communicate IPC library
128 * to store DSP encoder configuration information
129 */
130struct a2dp_data {
131 struct audio_device *adev;
132 void *bt_lib_handle;
133 audio_stream_open_t audio_stream_open;
134 audio_stream_close_t audio_stream_close;
135 audio_start_stream_t audio_start_stream;
136 audio_stop_stream_t audio_stop_stream;
137 audio_suspend_stream_t audio_suspend_stream;
138 audio_handoff_triggered_t audio_handoff_triggered;
139 clear_a2dpsuspend_flag_t clear_a2dpsuspend_flag;
140 audio_get_codec_config_t audio_get_codec_config;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530141 audio_check_a2dp_ready_t audio_check_a2dp_ready;
yidongh0515e042017-07-06 15:00:34 +0800142 audio_get_a2dp_sink_latency_t audio_get_a2dp_sink_latency;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530143 enum A2DP_STATE bt_state;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530144 enc_codec_t bt_encoder_format;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530145 uint32_t enc_sampling_rate;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530146 bool a2dp_started;
147 bool a2dp_suspended;
148 int a2dp_total_active_session_request;
149 bool is_a2dp_offload_supported;
150 bool is_handoff_in_progress;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700151 bool is_aptx_dual_mono_supported;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530152};
153
154struct a2dp_data a2dp;
155
156/* START of DSP configurable structures
157 * These values should match with DSP interface defintion
158 */
159
160/* AAC encoder configuration structure. */
161typedef struct aac_enc_cfg_t aac_enc_cfg_t;
162
163/* supported enc_mode are AAC_LC, AAC_SBR, AAC_PS
164 * supported aac_fmt_flag are ADTS/RAW
165 * supported channel_cfg are Native mode, Mono , Stereo
166 */
167struct aac_enc_cfg_t {
168 uint32_t enc_format;
169 uint32_t bit_rate;
170 uint32_t enc_mode;
171 uint16_t aac_fmt_flag;
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530172 uint16_t channel_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530173 uint32_t sample_rate;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700174} __packed;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530175
176/* SBC encoder configuration structure. */
177typedef struct sbc_enc_cfg_t sbc_enc_cfg_t;
178
179/* supported num_subbands are 4/8
180 * supported blk_len are 4, 8, 12, 16
181 * supported channel_mode are MONO, STEREO, DUAL_MONO, JOINT_STEREO
182 * supported alloc_method are LOUNDNESS/SNR
183 * supported bit_rate for mono channel is max 320kbps
184 * supported bit rate for stereo channel is max 512 kbps
185 */
186struct sbc_enc_cfg_t{
187 uint32_t enc_format;
188 uint32_t num_subbands;
189 uint32_t blk_len;
190 uint32_t channel_mode;
191 uint32_t alloc_method;
192 uint32_t bit_rate;
193 uint32_t sample_rate;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700194} __packed;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530195
196
197/* supported num_channels are Mono/Stereo
198 * supported channel_mapping for mono is CHANNEL_C
199 * supported channel mapping for stereo is CHANNEL_L and CHANNEL_R
200 * custom size and reserved are not used(for future enhancement)
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700201 */
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530202struct custom_enc_cfg_t
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530203{
204 uint32_t enc_format;
205 uint32_t sample_rate;
206 uint16_t num_channels;
207 uint16_t reserved;
208 uint8_t channel_mapping[8];
209 uint32_t custom_size;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700210} __packed;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530211
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530212struct celt_specific_enc_cfg_t
213{
214 uint32_t bit_rate;
215 uint16_t frame_size;
216 uint16_t complexity;
217 uint16_t prediction_mode;
218 uint16_t vbr_flag;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700219} __packed;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530220
221struct celt_enc_cfg_t
222{
223 struct custom_enc_cfg_t custom_cfg;
224 struct celt_specific_enc_cfg_t celt_cfg;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700225} __packed;
226
227/* sync_mode introduced with APTX V2 libraries
228 * sync mode: 0x0 = stereo sync mode
229 * 0x01 = dual mono sync mode
230 * 0x02 = dual mono with no sync on either L or R codewords
231 */
232struct aptx_v2_enc_cfg_ext_t
233{
234 uint32_t sync_mode;
235} __packed;
236
237/* APTX struct for combining custom enc and V2 fields */
238struct aptx_enc_cfg_t
239{
240 struct custom_enc_cfg_t custom_cfg;
241 struct aptx_v2_enc_cfg_ext_t aptx_v2_cfg;
242} __packed;
243
Sachin Mohan Gadag1657c052017-09-13 16:00:27 +0530244/* In LE BT source code uses system/audio.h for below
245 * structure definition. To avoid multiple definition
246 * compilation error for audiohal in LE , masking structure
247 * definition under "LINUX_ENABLED" which is defined only
248 * in LE
249 */
250#ifndef LINUX_ENABLED
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530251/* TODO: Define the following structures only for O using PLATFORM_VERSION */
252/* Information about BT SBC encoder configuration
253 * This data is used between audio HAL module and
254 * BT IPC library to configure DSP encoder
255 */
256typedef struct {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530257 uint32_t subband; /* 4, 8 */
258 uint32_t blk_len; /* 4, 8, 12, 16 */
259 uint16_t sampling_rate; /*44.1khz,48khz*/
260 uint8_t channels; /*0(Mono),1(Dual_mono),2(Stereo),3(JS)*/
261 uint8_t alloc; /*0(Loudness),1(SNR)*/
262 uint8_t min_bitpool; /* 2 */
263 uint8_t max_bitpool; /*53(44.1khz),51 (48khz) */
264 uint32_t bitrate; /* 320kbps to 512kbps */
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530265} audio_sbc_encoder_config;
266
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530267/* Information about BT APTX encoder configuration
268 * This data is used between audio HAL module and
269 * BT IPC library to configure DSP encoder
270 */
271typedef struct {
272 uint16_t sampling_rate;
273 uint8_t channels;
274 uint32_t bitrate;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700275} audio_aptx_default_config;
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530276
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700277typedef struct {
278 uint16_t sampling_rate;
279 uint8_t channels;
280 uint32_t bitrate;
281 uint32_t sync_mode;
282} audio_aptx_dual_mono_config;
283
284typedef union {
285 audio_aptx_default_config *default_cfg;
286 audio_aptx_dual_mono_config *dual_mono_cfg;
287} audio_aptx_encoder_config;
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530288
289/* Information about BT AAC encoder configuration
290 * This data is used between audio HAL module and
291 * BT IPC library to configure DSP encoder
292 */
293typedef struct {
294 uint32_t enc_mode; /* LC, SBR, PS */
295 uint16_t format_flag; /* RAW, ADTS */
296 uint16_t channels; /* 1-Mono, 2-Stereo */
297 uint32_t sampling_rate;
298 uint32_t bitrate;
299} audio_aac_encoder_config;
Sachin Mohan Gadag1657c052017-09-13 16:00:27 +0530300#endif
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530301
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530302/* Information about BT CELT encoder configuration
303 * This data is used between audio HAL module and
304 * BT IPC library to configure DSP encoder
305 */
306typedef struct {
307 uint32_t sampling_rate; /* 32000 - 48000, 48000 */
308 uint16_t channels; /* 1-Mono, 2-Stereo, 2*/
309 uint16_t frame_size; /* 64-128-256-512, 512 */
310 uint16_t complexity; /* 0-10, 1 */
311 uint16_t prediction_mode; /* 0-1-2, 0 */
312 uint16_t vbr_flag; /* 0-1, 0*/
313 uint32_t bitrate; /*32000 - 1536000, 139500*/
314} audio_celt_encoder_config;
315
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530316/*********** END of DSP configurable structures ********************/
317
318/* API to identify DSP encoder captabilities */
319static void a2dp_offload_codec_cap_parser(char *value)
320{
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530321 char *tok = NULL,*saveptr;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530322
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530323 tok = strtok_r(value, "-", &saveptr);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530324 while (tok != NULL) {
325 if (strcmp(tok, "sbc") == 0) {
326 ALOGD("%s: SBC offload supported\n",__func__);
327 a2dp.is_a2dp_offload_supported = true;
328 break;
329 } else if (strcmp(tok, "aptx") == 0) {
330 ALOGD("%s: aptx offload supported\n",__func__);
331 a2dp.is_a2dp_offload_supported = true;
332 break;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700333 } else if (strcmp(tok, "aptxtws") == 0) {
334 ALOGD("%s: aptx dual mono offload supported\n",__func__);
335 a2dp.is_a2dp_offload_supported = true;
336 break;
Naresh Tannirued694c82017-02-07 17:01:28 +0530337 } else if (strcmp(tok, "aptxhd") == 0) {
338 ALOGD("%s: aptx HD offload supported\n",__func__);
339 a2dp.is_a2dp_offload_supported = true;
340 break;
341 } else if (strcmp(tok, "aac") == 0) {
342 ALOGD("%s: aac offload supported\n",__func__);
343 a2dp.is_a2dp_offload_supported = true;
344 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530345 } else if (strcmp(tok, "celt") == 0) {
346 ALOGD("%s: celt offload supported\n",__func__);
347 a2dp.is_a2dp_offload_supported = true;
348 break;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530349 }
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530350 tok = strtok_r(NULL, "-", &saveptr);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530351 };
352}
353
354static void update_offload_codec_capabilities()
355{
356 char value[PROPERTY_VALUE_MAX] = {'\0'};
357
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -0700358 property_get("persist.vendor.bt.a2dp_offload_cap", value, "false");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530359 ALOGD("get_offload_codec_capabilities = %s",value);
360 a2dp.is_a2dp_offload_supported =
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -0700361 property_get_bool("persist.vendor.bt.a2dp_offload_cap", false);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530362 if (strcmp(value, "false") != 0)
363 a2dp_offload_codec_cap_parser(value);
364 ALOGD("%s: codec cap = %s",__func__,value);
365}
366
367/* API to open BT IPC library to start IPC communication */
368static void open_a2dp_output()
369{
370 int ret = 0;
371
372 ALOGD(" Open A2DP output start ");
373 if (a2dp.bt_lib_handle == NULL){
374 ALOGD(" Requesting for BT lib handle");
375 a2dp.bt_lib_handle = dlopen(BT_IPC_LIB_NAME, RTLD_NOW);
376
377 if (a2dp.bt_lib_handle == NULL) {
378 ALOGE("%s: DLOPEN failed for %s", __func__, BT_IPC_LIB_NAME);
379 ret = -ENOSYS;
380 goto init_fail;
381 } else {
382 a2dp.audio_stream_open = (audio_stream_open_t)
383 dlsym(a2dp.bt_lib_handle, "audio_stream_open");
384 a2dp.audio_start_stream = (audio_start_stream_t)
385 dlsym(a2dp.bt_lib_handle, "audio_start_stream");
386 a2dp.audio_get_codec_config = (audio_get_codec_config_t)
387 dlsym(a2dp.bt_lib_handle, "audio_get_codec_config");
388 a2dp.audio_suspend_stream = (audio_suspend_stream_t)
389 dlsym(a2dp.bt_lib_handle, "audio_suspend_stream");
390 a2dp.audio_handoff_triggered = (audio_handoff_triggered_t)
391 dlsym(a2dp.bt_lib_handle, "audio_handoff_triggered");
392 a2dp.clear_a2dpsuspend_flag = (clear_a2dpsuspend_flag_t)
393 dlsym(a2dp.bt_lib_handle, "clear_a2dpsuspend_flag");
394 a2dp.audio_stop_stream = (audio_stop_stream_t)
395 dlsym(a2dp.bt_lib_handle, "audio_stop_stream");
396 a2dp.audio_stream_close = (audio_stream_close_t)
397 dlsym(a2dp.bt_lib_handle, "audio_stream_close");
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530398 a2dp.audio_check_a2dp_ready = (audio_check_a2dp_ready_t)
399 dlsym(a2dp.bt_lib_handle,"audio_check_a2dp_ready");
yidongh0515e042017-07-06 15:00:34 +0800400 a2dp.audio_get_a2dp_sink_latency = (audio_get_a2dp_sink_latency_t)
401 dlsym(a2dp.bt_lib_handle,"audio_get_a2dp_sink_latency");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530402 }
403 }
404
405 if (a2dp.bt_lib_handle && a2dp.audio_stream_open) {
406 if (a2dp.bt_state == A2DP_STATE_DISCONNECTED) {
407 ALOGD("calling BT stream open");
408 ret = a2dp.audio_stream_open();
409 if(ret != 0) {
410 ALOGE("Failed to open output stream for a2dp: status %d", ret);
411 goto init_fail;
412 }
413 a2dp.bt_state = A2DP_STATE_CONNECTED;
414 } else {
415 ALOGD("Called a2dp open with improper state, Ignoring request state %d", a2dp.bt_state);
416 }
417 } else {
418 ALOGE("a2dp handle is not identified, Ignoring open request");
419 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
420 goto init_fail;
421 }
422
423init_fail:
424 if(ret != 0 && (a2dp.bt_lib_handle != NULL)) {
425 dlclose(a2dp.bt_lib_handle);
426 a2dp.bt_lib_handle = NULL;
427 }
428}
429
430static int close_a2dp_output()
431{
432 ALOGV("%s\n",__func__);
433 if (!(a2dp.bt_lib_handle && a2dp.audio_stream_close)) {
434 ALOGE("a2dp handle is not identified, Ignoring close request");
435 return -ENOSYS;
436 }
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530437 if (a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530438 ALOGD("calling BT stream close");
439 if(a2dp.audio_stream_close() == false)
440 ALOGE("failed close a2dp control path from BT library");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530441 }
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530442 a2dp.a2dp_started = false;
443 a2dp.a2dp_total_active_session_request = 0;
444 a2dp.a2dp_suspended = false;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530445 a2dp.bt_encoder_format = ENC_CODEC_TYPE_INVALID;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530446 a2dp.enc_sampling_rate = 48000;
447 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530448
449 return 0;
450}
451
452/* API to configure SBC DSP encoder */
453bool configure_sbc_enc_format(audio_sbc_encoder_config *sbc_bt_cfg)
454{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530455 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530456 struct sbc_enc_cfg_t sbc_dsp_cfg;
457 bool is_configured = false;
458 int ret = 0;
459
460 if(sbc_bt_cfg == NULL)
461 return false;
462
463 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
464 if (!ctl_enc_data) {
465 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
466 is_configured = false;
467 goto fail;
468 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530469 memset(&sbc_dsp_cfg, 0x0, sizeof(struct sbc_enc_cfg_t));
470 sbc_dsp_cfg.enc_format = ENC_MEDIA_FMT_SBC;
471 sbc_dsp_cfg.num_subbands = sbc_bt_cfg->subband;
472 sbc_dsp_cfg.blk_len = sbc_bt_cfg->blk_len;
473 switch(sbc_bt_cfg->channels) {
474 case 0:
475 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_MONO;
476 break;
477 case 1:
478 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO;
479 break;
480 case 3:
481 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO;
482 break;
483 case 2:
484 default:
485 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_STEREO;
486 break;
487 }
488 if (sbc_bt_cfg->alloc)
489 sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS;
490 else
491 sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR;
492 sbc_dsp_cfg.bit_rate = sbc_bt_cfg->bitrate;
493 sbc_dsp_cfg.sample_rate = sbc_bt_cfg->sampling_rate;
494 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&sbc_dsp_cfg,
495 sizeof(struct sbc_enc_cfg_t));
496 if (ret != 0) {
497 ALOGE("%s: failed to set SBC encoder config", __func__);
498 is_configured = false;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530499 goto fail;
500 }
501 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
502 MIXER_ENC_BIT_FORMAT);
503 if (!ctrl_bit_format) {
504 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
505 is_configured = false;
506 goto fail;
507 }
508 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
509 if (ret != 0) {
510 ALOGE("%s: Failed to set bit format to encoder", __func__);
511 is_configured = false;
512 goto fail;
513 }
514 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530515 a2dp.bt_encoder_format = ENC_CODEC_TYPE_SBC;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530516 a2dp.enc_sampling_rate = sbc_bt_cfg->sampling_rate;
517 ALOGV("Successfully updated SBC enc format with samplingrate: %d channelmode:%d",
518 sbc_dsp_cfg.sample_rate, sbc_dsp_cfg.channel_mode);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530519fail:
520 return is_configured;
521}
522
523/* API to configure APTX DSP encoder */
524bool configure_aptx_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
525{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530526 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700527 struct aptx_enc_cfg_t aptx_dsp_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530528 bool is_configured = false;
529 int ret = 0;
530
531 if(aptx_bt_cfg == NULL)
532 return false;
533
534 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
535 if (!ctl_enc_data) {
536 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
537 is_configured = false;
538 goto fail;
539 }
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700540
541 memset(&aptx_dsp_cfg, 0x0, sizeof(struct aptx_enc_cfg_t));
542 aptx_dsp_cfg.custom_cfg.enc_format = ENC_MEDIA_FMT_APTX;
543
544 if (!a2dp.is_aptx_dual_mono_supported) {
545 aptx_dsp_cfg.custom_cfg.sample_rate = aptx_bt_cfg->default_cfg->sampling_rate;
546 aptx_dsp_cfg.custom_cfg.num_channels = aptx_bt_cfg->default_cfg->channels;
547 } else {
548 aptx_dsp_cfg.custom_cfg.sample_rate = aptx_bt_cfg->dual_mono_cfg->sampling_rate;
549 aptx_dsp_cfg.custom_cfg.num_channels = aptx_bt_cfg->dual_mono_cfg->channels;
550 aptx_dsp_cfg.aptx_v2_cfg.sync_mode = aptx_bt_cfg->dual_mono_cfg->sync_mode;
551 }
552
553 switch(aptx_dsp_cfg.custom_cfg.num_channels) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530554 case 1:
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700555 aptx_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_C;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530556 break;
557 case 2:
558 default:
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700559 aptx_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
560 aptx_dsp_cfg.custom_cfg.channel_mapping[1] = PCM_CHANNEL_R;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530561 break;
562 }
563 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700564 sizeof(struct aptx_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530565 if (ret != 0) {
566 ALOGE("%s: Failed to set APTX encoder config", __func__);
567 is_configured = false;
568 goto fail;
569 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530570 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
571 MIXER_ENC_BIT_FORMAT);
572 if (!ctrl_bit_format) {
573 ALOGE("ERROR bit format CONFIG data mixer control not identifed");
574 is_configured = false;
575 goto fail;
576 } else {
577 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
578 if (ret != 0) {
579 ALOGE("%s: Failed to set bit format to encoder", __func__);
580 is_configured = false;
581 goto fail;
582 }
583 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530584 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530585 a2dp.bt_encoder_format = ENC_CODEC_TYPE_APTX;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700586 if (!a2dp.is_aptx_dual_mono_supported) {
587 a2dp.enc_sampling_rate = aptx_bt_cfg->default_cfg->sampling_rate;
588 ALOGV("Successfully updated APTX enc format with samplingrate: %d \
589 channels:%d", aptx_dsp_cfg.custom_cfg.sample_rate,
590 aptx_dsp_cfg.custom_cfg.num_channels);
591 } else {
592 a2dp.enc_sampling_rate = aptx_bt_cfg->dual_mono_cfg->sampling_rate;
593 ALOGV("Successfully updated APTX dual mono enc format with \
594 samplingrate: %d channels:%d syncmode %d",
595 aptx_dsp_cfg.custom_cfg.sample_rate,
596 aptx_dsp_cfg.custom_cfg.num_channels,
597 aptx_dsp_cfg.aptx_v2_cfg.sync_mode);
598 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530599fail:
600 return is_configured;
601}
602
603/* API to configure APTX HD DSP encoder
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530604 */
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700605bool configure_aptx_hd_enc_format(audio_aptx_default_config *aptx_bt_cfg)
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530606{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530607 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530608 struct custom_enc_cfg_t aptx_dsp_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530609 bool is_configured = false;
610 int ret = 0;
611
612 if(aptx_bt_cfg == NULL)
613 return false;
614
615 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
616 if (!ctl_enc_data) {
617 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
618 is_configured = false;
619 goto fail;
620 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530621
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530622 memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530623 aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX_HD;
624 aptx_dsp_cfg.sample_rate = aptx_bt_cfg->sampling_rate;
625 aptx_dsp_cfg.num_channels = aptx_bt_cfg->channels;
626 switch(aptx_dsp_cfg.num_channels) {
627 case 1:
628 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_C;
629 break;
630 case 2:
631 default:
632 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_L;
633 aptx_dsp_cfg.channel_mapping[1] = PCM_CHANNEL_R;
634 break;
635 }
636 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530637 sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530638 if (ret != 0) {
639 ALOGE("%s: Failed to set APTX HD encoder config", __func__);
640 is_configured = false;
641 goto fail;
642 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530643 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
644 if (!ctrl_bit_format) {
645 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
646 is_configured = false;
647 goto fail;
648 }
649 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S24_LE");
650 if (ret != 0) {
651 ALOGE("%s: Failed to set APTX HD encoder config", __func__);
652 is_configured = false;
653 goto fail;
654 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530655 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530656 a2dp.bt_encoder_format = ENC_CODEC_TYPE_APTX_HD;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530657 a2dp.enc_sampling_rate = aptx_bt_cfg->sampling_rate;
658 ALOGV("Successfully updated APTX HD encformat with samplingrate: %d channels:%d",
659 aptx_dsp_cfg.sample_rate, aptx_dsp_cfg.num_channels);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530660fail:
661 return is_configured;
662}
663
664/* API to configure AAC DSP encoder */
665bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg)
666{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530667 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530668 struct aac_enc_cfg_t aac_dsp_cfg;
669 bool is_configured = false;
670 int ret = 0;
671
672 if(aac_bt_cfg == NULL)
673 return false;
674
675 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
676 if (!ctl_enc_data) {
677 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
678 is_configured = false;
679 goto fail;
680 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530681 memset(&aac_dsp_cfg, 0x0, sizeof(struct aac_enc_cfg_t));
682 aac_dsp_cfg.enc_format = ENC_MEDIA_FMT_AAC;
683 aac_dsp_cfg.bit_rate = aac_bt_cfg->bitrate;
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530684 aac_dsp_cfg.sample_rate = aac_bt_cfg->sampling_rate;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530685 switch(aac_bt_cfg->enc_mode) {
686 case 0:
687 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC;
688 break;
689 case 2:
690 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS;
691 break;
692 case 1:
693 default:
694 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR;
695 break;
696 }
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530697 aac_dsp_cfg.aac_fmt_flag = aac_bt_cfg->format_flag;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530698 aac_dsp_cfg.channel_cfg = aac_bt_cfg->channels;
699 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aac_dsp_cfg,
700 sizeof(struct aac_enc_cfg_t));
701 if (ret != 0) {
702 ALOGE("%s: failed to set SBC encoder config", __func__);
703 is_configured = false;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530704 goto fail;
705 }
706 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
707 MIXER_ENC_BIT_FORMAT);
708 if (!ctrl_bit_format) {
709 is_configured = false;
710 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
711 goto fail;
712 }
713 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
714 if (ret != 0) {
715 ALOGE("%s: Failed to set bit format to encoder", __func__);
716 is_configured = false;
717 goto fail;
718 }
719 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530720 a2dp.bt_encoder_format = ENC_CODEC_TYPE_AAC;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530721 a2dp.enc_sampling_rate = aac_bt_cfg->sampling_rate;
722 ALOGV("Successfully updated AAC enc format with samplingrate: %d channels:%d",
723 aac_dsp_cfg.sample_rate, aac_dsp_cfg.channel_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530724fail:
725 return is_configured;
726}
727
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530728bool configure_celt_enc_format(audio_celt_encoder_config *celt_bt_cfg)
729{
730 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
731 struct celt_enc_cfg_t celt_dsp_cfg;
732 bool is_configured = false;
733 int ret = 0;
734 if(celt_bt_cfg == NULL)
735 return false;
736
737 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
738 if (!ctl_enc_data) {
739 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
740 is_configured = false;
741 goto fail;
742 }
743 memset(&celt_dsp_cfg, 0x0, sizeof(struct celt_enc_cfg_t));
744
745 celt_dsp_cfg.custom_cfg.enc_format = ENC_MEDIA_FMT_CELT;
746 celt_dsp_cfg.custom_cfg.sample_rate = celt_bt_cfg->sampling_rate;
747 celt_dsp_cfg.custom_cfg.num_channels = celt_bt_cfg->channels;
748 switch(celt_dsp_cfg.custom_cfg.num_channels) {
749 case 1:
750 celt_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_C;
751 break;
752 case 2:
753 default:
754 celt_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
755 celt_dsp_cfg.custom_cfg.channel_mapping[1] = PCM_CHANNEL_R;
756 break;
757 }
758
759 celt_dsp_cfg.custom_cfg.custom_size = sizeof(struct celt_enc_cfg_t);
760
761 celt_dsp_cfg.celt_cfg.frame_size = celt_bt_cfg->frame_size;
762 celt_dsp_cfg.celt_cfg.complexity = celt_bt_cfg->complexity;
763 celt_dsp_cfg.celt_cfg.prediction_mode = celt_bt_cfg->prediction_mode;
764 celt_dsp_cfg.celt_cfg.vbr_flag = celt_bt_cfg->vbr_flag;
765 celt_dsp_cfg.celt_cfg.bit_rate = celt_bt_cfg->bitrate;
766
767 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&celt_dsp_cfg,
768 sizeof(struct celt_enc_cfg_t));
769 if (ret != 0) {
770 ALOGE("%s: Failed to set CELT encoder config", __func__);
771 is_configured = false;
772 goto fail;
773 }
774 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
775 if (!ctrl_bit_format) {
776 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
777 is_configured = false;
778 goto fail;
779 }
780 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
781 if (ret != 0) {
782 ALOGE("%s: Failed to set bit format to encoder", __func__);
783 is_configured = false;
784 goto fail;
785 }
786 is_configured = true;
787 a2dp.bt_encoder_format = ENC_CODEC_TYPE_CELT;
788 a2dp.enc_sampling_rate = celt_bt_cfg->sampling_rate;
789 ALOGV("Successfully updated CELT encformat with samplingrate: %d channels:%d",
790 celt_dsp_cfg.custom_cfg.sample_rate, celt_dsp_cfg.custom_cfg.num_channels);
791fail:
792 return is_configured;
793}
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530794bool configure_a2dp_encoder_format()
795{
796 void *codec_info = NULL;
797 uint8_t multi_cast = 0, num_dev = 1;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530798 enc_codec_t codec_type = ENC_CODEC_TYPE_INVALID;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530799 bool is_configured = false;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700800 audio_aptx_encoder_config aptx_encoder_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530801
802 if (!a2dp.audio_get_codec_config) {
803 ALOGE(" a2dp handle is not identified, ignoring a2dp encoder config");
804 return false;
805 }
806 ALOGD("configure_a2dp_encoder_format start");
807 codec_info = a2dp.audio_get_codec_config(&multi_cast, &num_dev,
808 &codec_type);
809
810 switch(codec_type) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530811 case ENC_CODEC_TYPE_SBC:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530812 ALOGD(" Received SBC encoder supported BT device");
813 is_configured =
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700814 configure_sbc_enc_format((audio_sbc_encoder_config *)codec_info);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530815 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530816 case ENC_CODEC_TYPE_APTX:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530817 ALOGD(" Received APTX encoder supported BT device");
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700818 a2dp.is_aptx_dual_mono_supported = false;
819 aptx_encoder_cfg.default_cfg = (audio_aptx_default_config *)codec_info;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530820 is_configured =
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700821 configure_aptx_enc_format(&aptx_encoder_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530822 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530823 case ENC_CODEC_TYPE_APTX_HD:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530824 ALOGD(" Received APTX HD encoder supported BT device");
825 is_configured =
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700826 configure_aptx_hd_enc_format((audio_aptx_default_config *)codec_info);
827 break;
828 case ENC_CODEC_TYPE_APTX_DUAL_MONO:
829 ALOGD(" Received APTX dual mono encoder supported BT device");
830 a2dp.is_aptx_dual_mono_supported = true;
831 aptx_encoder_cfg.dual_mono_cfg = (audio_aptx_dual_mono_config *)codec_info;
832 is_configured =
833 configure_aptx_enc_format(&aptx_encoder_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530834 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530835 case ENC_CODEC_TYPE_AAC:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530836 ALOGD(" Received AAC encoder supported BT device");
837 is_configured =
838 configure_aac_enc_format((audio_aac_encoder_config *)codec_info);
839 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530840 case ENC_CODEC_TYPE_CELT:
841 ALOGD(" Received CELT encoder supported BT device");
842 is_configured =
843 configure_celt_enc_format((audio_celt_encoder_config *)codec_info);
844 break;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530845 default:
846 ALOGD(" Received Unsupported encoder formar");
847 is_configured = false;
848 break;
849 }
850 return is_configured;
851}
852
853int audio_extn_a2dp_start_playback()
854{
855 int ret = 0;
856
857 ALOGD("audio_extn_a2dp_start_playback start");
858
859 if(!(a2dp.bt_lib_handle && a2dp.audio_start_stream
860 && a2dp.audio_get_codec_config)) {
861 ALOGE("a2dp handle is not identified, Ignoring start request");
862 return -ENOSYS;
863 }
864
865 if(a2dp.a2dp_suspended == true) {
866 //session will be restarted after suspend completion
867 ALOGD("a2dp start requested during suspend state");
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530868 return -ENOSYS;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530869 }
870
871 if (!a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
872 ALOGD("calling BT module stream start");
873 /* This call indicates BT IPC lib to start playback */
874 ret = a2dp.audio_start_stream();
875 ALOGE("BT controller start return = %d",ret);
876 if (ret != 0 ) {
877 ALOGE("BT controller start failed");
878 a2dp.a2dp_started = false;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530879 } else {
880 if(configure_a2dp_encoder_format() == true) {
881 a2dp.a2dp_started = true;
882 ret = 0;
883 ALOGD("Start playback successful to BT library");
884 } else {
885 ALOGD(" unable to configure DSP encoder");
886 a2dp.a2dp_started = false;
887 ret = -ETIMEDOUT;
888 }
889 }
890 }
891
892 if (a2dp.a2dp_started)
893 a2dp.a2dp_total_active_session_request++;
894
895 ALOGD("start A2DP playback total active sessions :%d",
896 a2dp.a2dp_total_active_session_request);
897 return ret;
898}
899
Naresh Tanniru03f9dd52016-10-19 18:46:22 +0530900static void reset_a2dp_enc_config_params()
901{
902 int ret =0;
903
904 struct mixer_ctl *ctl_enc_config, *ctrl_bit_format;
905 struct sbc_enc_cfg_t dummy_reset_config;
906
907 memset(&dummy_reset_config, 0x0, sizeof(struct sbc_enc_cfg_t));
908 ctl_enc_config = mixer_get_ctl_by_name(a2dp.adev->mixer,
909 MIXER_ENC_CONFIG_BLOCK);
910 if (!ctl_enc_config) {
911 ALOGE(" ERROR a2dp encoder format mixer control not identifed");
912 } else {
913 ret = mixer_ctl_set_array(ctl_enc_config, (void *)&dummy_reset_config,
914 sizeof(struct sbc_enc_cfg_t));
915 a2dp.bt_encoder_format = ENC_MEDIA_FMT_NONE;
916 }
917 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
918 MIXER_ENC_BIT_FORMAT);
919 if (!ctrl_bit_format) {
920 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
921 } else {
922 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
923 if (ret != 0) {
924 ALOGE("%s: Failed to set bit format to encoder", __func__);
925 }
926 }
927}
928
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530929int audio_extn_a2dp_stop_playback()
930{
931 int ret =0;
932
933 ALOGV("audio_extn_a2dp_stop_playback start");
934 if(!(a2dp.bt_lib_handle && a2dp.audio_stop_stream)) {
935 ALOGE("a2dp handle is not identified, Ignoring start request");
936 return -ENOSYS;
937 }
938
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530939 if (a2dp.a2dp_total_active_session_request > 0)
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530940 a2dp.a2dp_total_active_session_request--;
941
942 if ( a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530943 ALOGV("calling BT module stream stop");
944 ret = a2dp.audio_stop_stream();
945 if (ret < 0)
946 ALOGE("stop stream to BT IPC lib failed");
947 else
948 ALOGV("stop steam to BT IPC lib successful");
Naresh Tanniru03f9dd52016-10-19 18:46:22 +0530949 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530950 }
951 if(!a2dp.a2dp_total_active_session_request)
952 a2dp.a2dp_started = false;
953 ALOGD("Stop A2DP playback total active sessions :%d",
954 a2dp.a2dp_total_active_session_request);
955 return 0;
956}
957
958void audio_extn_a2dp_set_parameters(struct str_parms *parms)
959{
960 int ret, val;
961 char value[32]={0};
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +0530962 struct audio_usecase *uc_info;
963 struct listnode *node;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530964
965 if(a2dp.is_a2dp_offload_supported == false) {
966 ALOGV("no supported encoders identified,ignoring a2dp setparam");
967 return;
968 }
969
970 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
971 sizeof(value));
972 if( ret >= 0) {
973 val = atoi(value);
974 if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
975 ALOGV("Received device connect request for A2DP");
976 open_a2dp_output();
977 }
978 goto param_handled;
979 }
980
981 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value,
982 sizeof(value));
983
984 if( ret >= 0) {
985 val = atoi(value);
986 if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
987 ALOGV("Received device dis- connect request");
Naresh Tanniru03f9dd52016-10-19 18:46:22 +0530988 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530989 close_a2dp_output();
990 }
991 goto param_handled;
992 }
993
994 ret = str_parms_get_str(parms, "A2dpSuspended", value, sizeof(value));
995 if (ret >= 0) {
996 if (a2dp.bt_lib_handle && (a2dp.bt_state != A2DP_STATE_DISCONNECTED) ) {
997 if ((!strncmp(value,"true",sizeof(value)))) {
998 ALOGD("Setting a2dp to suspend state");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530999 a2dp.a2dp_suspended = true;
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301000 list_for_each(node, &a2dp.adev->usecase_list) {
1001 uc_info = node_to_item(node, struct audio_usecase, list);
Zhou Songc66eb7e2017-08-08 18:29:07 +08001002 if (uc_info->type == PCM_PLAYBACK &&
1003 (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301004 pthread_mutex_unlock(&a2dp.adev->lock);
1005 check_a2dp_restore(a2dp.adev, uc_info->stream.out, false);
1006 pthread_mutex_lock(&a2dp.adev->lock);
1007 }
1008 }
Naresh Tanniru03f9dd52016-10-19 18:46:22 +05301009 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301010 if(a2dp.audio_suspend_stream)
1011 a2dp.audio_suspend_stream();
1012 } else if (a2dp.a2dp_suspended == true) {
1013 ALOGD("Resetting a2dp suspend state");
Zhou Song10617ed2017-05-26 13:28:48 +08001014 struct audio_usecase *uc_info;
1015 struct listnode *node;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301016 if(a2dp.clear_a2dpsuspend_flag)
1017 a2dp.clear_a2dpsuspend_flag();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301018 a2dp.a2dp_suspended = false;
Naresh Tanniru649871a2016-11-04 18:08:32 +05301019 /*
1020 * It is possible that before suspend,a2dp sessions can be active
1021 * for example during music + voice activation concurrency
1022 * a2dp suspend will be called & BT will change to sco mode
1023 * though music is paused as a part of voice activation
1024 * compress session close happens only after pause timeout(10secs)
1025 * so if resume request comes before pause timeout as a2dp session
1026 * is already active IPC start will not be called from APM/audio_hw
1027 * Fix is to call a2dp start for IPC library post suspend
1028 * based on number of active session count
1029 */
1030 if (a2dp.a2dp_total_active_session_request > 0) {
1031 ALOGD(" Calling IPC lib start post suspend state");
1032 if(a2dp.audio_start_stream) {
1033 ret = a2dp.audio_start_stream();
1034 if (ret != 0) {
1035 ALOGE("BT controller start failed");
1036 a2dp.a2dp_started = false;
1037 }
1038 }
1039 }
Zhou Song10617ed2017-05-26 13:28:48 +08001040 list_for_each(node, &a2dp.adev->usecase_list) {
1041 uc_info = node_to_item(node, struct audio_usecase, list);
Zhou Songc66eb7e2017-08-08 18:29:07 +08001042 if (uc_info->type == PCM_PLAYBACK &&
1043 (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301044 pthread_mutex_unlock(&a2dp.adev->lock);
1045 check_a2dp_restore(a2dp.adev, uc_info->stream.out, true);
1046 pthread_mutex_lock(&a2dp.adev->lock);
1047 }
Zhou Song10617ed2017-05-26 13:28:48 +08001048 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301049 }
1050 }
1051 goto param_handled;
1052 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301053param_handled:
1054 ALOGV("end of a2dp setparam");
1055}
1056
Naresh Tannirucd2353e2016-08-19 00:37:25 +05301057void audio_extn_a2dp_set_handoff_mode(bool is_on)
1058{
1059 a2dp.is_handoff_in_progress = is_on;
1060}
1061
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301062bool audio_extn_a2dp_is_force_device_switch()
1063{
1064 //During encoder reconfiguration mode, force a2dp device switch
Ashish Jainc597d102016-12-12 10:31:34 +05301065 // Or if a2dp device is selected but earlier start failed ( as a2dp
1066 // was suspended, force retry.
1067 return a2dp.is_handoff_in_progress || !a2dp.a2dp_started;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301068}
1069
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301070void audio_extn_a2dp_get_apptype_params(uint32_t *sample_rate,
1071 uint32_t *bit_width)
1072{
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301073 if(a2dp.bt_encoder_format == ENC_CODEC_TYPE_APTX_HD)
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301074 *bit_width = 24;
1075 else
1076 *bit_width = 16;
1077 *sample_rate = a2dp.enc_sampling_rate;
1078}
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301079
1080bool audio_extn_a2dp_is_ready()
1081{
1082 bool ret = false;
1083
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301084 if (a2dp.a2dp_suspended)
1085 return ret;
1086
Aniket Kumar Lata901bcb82017-03-10 15:42:46 -08001087 if ((a2dp.bt_state != A2DP_STATE_DISCONNECTED) &&
1088 (a2dp.is_a2dp_offload_supported) &&
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301089 (a2dp.audio_check_a2dp_ready))
1090 ret = a2dp.audio_check_a2dp_ready();
1091 return ret;
1092}
1093
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301094bool audio_extn_a2dp_is_suspended()
1095{
1096 return a2dp.a2dp_suspended;
1097}
1098
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301099void audio_extn_a2dp_init (void *adev)
1100{
1101 a2dp.adev = (struct audio_device*)adev;
1102 a2dp.bt_lib_handle = NULL;
1103 a2dp.a2dp_started = false;
1104 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
1105 a2dp.a2dp_total_active_session_request = 0;
1106 a2dp.a2dp_suspended = false;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301107 a2dp.bt_encoder_format = ENC_CODEC_TYPE_INVALID;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301108 a2dp.enc_sampling_rate = 48000;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301109 a2dp.is_a2dp_offload_supported = false;
1110 a2dp.is_handoff_in_progress = false;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001111 a2dp.is_aptx_dual_mono_supported = false;
kunleiz5a127262017-09-08 14:47:48 +08001112 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301113 update_offload_codec_capabilities();
1114}
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001115
1116uint32_t audio_extn_a2dp_get_encoder_latency()
1117{
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001118 uint32_t latency = 0;
1119 int avsync_runtime_prop = 0;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301120 int sbc_offset = 0, aptx_offset = 0, aptxhd_offset = 0, aac_offset = 0, celt_offset = 0;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001121 char value[PROPERTY_VALUE_MAX];
1122
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001123 memset(value, '\0', sizeof(char)*PROPERTY_VALUE_MAX);
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -07001124 avsync_runtime_prop = property_get("vendor.audio.a2dp.codec.latency", value, NULL);
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001125 if (avsync_runtime_prop > 0) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301126 if (sscanf(value, "%d/%d/%d/%d/%d",
1127 &sbc_offset, &aptx_offset, &aptxhd_offset, &aac_offset, &celt_offset) != 5) {
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001128 ALOGI("Failed to parse avsync offset params from '%s'.", value);
1129 avsync_runtime_prop = 0;
1130 }
1131 }
1132
yidongh0515e042017-07-06 15:00:34 +08001133 uint32_t slatency = 0;
1134 if (a2dp.audio_get_a2dp_sink_latency && a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
1135 slatency = a2dp.audio_get_a2dp_sink_latency();
1136 }
1137
Aniket Kumar Latafaaffde2017-03-22 19:18:15 -07001138 switch(a2dp.bt_encoder_format) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301139 case ENC_CODEC_TYPE_SBC:
yidongh0515e042017-07-06 15:00:34 +08001140 latency = (avsync_runtime_prop > 0) ? sbc_offset : ENCODER_LATENCY_SBC;
1141 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_SBC : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001142 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301143 case ENC_CODEC_TYPE_APTX:
yidongh0515e042017-07-06 15:00:34 +08001144 latency = (avsync_runtime_prop > 0) ? aptx_offset : ENCODER_LATENCY_APTX;
1145 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001146 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301147 case ENC_CODEC_TYPE_APTX_HD:
yidongh0515e042017-07-06 15:00:34 +08001148 latency = (avsync_runtime_prop > 0) ? aptxhd_offset : ENCODER_LATENCY_APTX_HD;
1149 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX_HD : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001150 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301151 case ENC_CODEC_TYPE_AAC:
yidongh0515e042017-07-06 15:00:34 +08001152 latency = (avsync_runtime_prop > 0) ? aac_offset : ENCODER_LATENCY_AAC;
1153 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_AAC : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001154 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301155 case ENC_CODEC_TYPE_CELT:
1156 latency = (avsync_runtime_prop > 0) ? celt_offset : ENCODER_LATENCY_CELT;
1157 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_CELT : slatency;
1158 break;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001159 default:
1160 latency = 200;
1161 break;
1162 }
1163 return latency;
1164}
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301165#endif // SPLIT_A2DP_ENABLED