blob: 4aad5f0d6b75bb4372454f0546c61c437539f3a1 [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
103 ENC_CODEC_TYPE_CELT = 603979776u, // 0x24000000UL
104}enc_codec_t;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530105
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530106typedef int (*audio_stream_open_t)(void);
107typedef int (*audio_stream_close_t)(void);
108typedef int (*audio_start_stream_t)(void);
109typedef int (*audio_stop_stream_t)(void);
110typedef int (*audio_suspend_stream_t)(void);
111typedef void (*audio_handoff_triggered_t)(void);
112typedef void (*clear_a2dpsuspend_flag_t)(void);
113typedef void * (*audio_get_codec_config_t)(uint8_t *multicast_status,uint8_t *num_dev,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530114 enc_codec_t *codec_type);
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530115typedef int (*audio_check_a2dp_ready_t)(void);
yidongh0515e042017-07-06 15:00:34 +0800116typedef uint16_t (*audio_get_a2dp_sink_latency_t)(void);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530117
118enum A2DP_STATE {
119 A2DP_STATE_CONNECTED,
120 A2DP_STATE_STARTED,
121 A2DP_STATE_STOPPED,
122 A2DP_STATE_DISCONNECTED,
123};
124
125/* structure used to update a2dp state machine
126 * to communicate IPC library
127 * to store DSP encoder configuration information
128 */
129struct a2dp_data {
130 struct audio_device *adev;
131 void *bt_lib_handle;
132 audio_stream_open_t audio_stream_open;
133 audio_stream_close_t audio_stream_close;
134 audio_start_stream_t audio_start_stream;
135 audio_stop_stream_t audio_stop_stream;
136 audio_suspend_stream_t audio_suspend_stream;
137 audio_handoff_triggered_t audio_handoff_triggered;
138 clear_a2dpsuspend_flag_t clear_a2dpsuspend_flag;
139 audio_get_codec_config_t audio_get_codec_config;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530140 audio_check_a2dp_ready_t audio_check_a2dp_ready;
yidongh0515e042017-07-06 15:00:34 +0800141 audio_get_a2dp_sink_latency_t audio_get_a2dp_sink_latency;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530142 enum A2DP_STATE bt_state;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530143 enc_codec_t bt_encoder_format;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530144 uint32_t enc_sampling_rate;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530145 bool a2dp_started;
146 bool a2dp_suspended;
147 int a2dp_total_active_session_request;
148 bool is_a2dp_offload_supported;
149 bool is_handoff_in_progress;
150};
151
152struct a2dp_data a2dp;
153
154/* START of DSP configurable structures
155 * These values should match with DSP interface defintion
156 */
157
158/* AAC encoder configuration structure. */
159typedef struct aac_enc_cfg_t aac_enc_cfg_t;
160
161/* supported enc_mode are AAC_LC, AAC_SBR, AAC_PS
162 * supported aac_fmt_flag are ADTS/RAW
163 * supported channel_cfg are Native mode, Mono , Stereo
164 */
165struct aac_enc_cfg_t {
166 uint32_t enc_format;
167 uint32_t bit_rate;
168 uint32_t enc_mode;
169 uint16_t aac_fmt_flag;
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530170 uint16_t channel_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530171 uint32_t sample_rate;
172} ;
173
174/* SBC encoder configuration structure. */
175typedef struct sbc_enc_cfg_t sbc_enc_cfg_t;
176
177/* supported num_subbands are 4/8
178 * supported blk_len are 4, 8, 12, 16
179 * supported channel_mode are MONO, STEREO, DUAL_MONO, JOINT_STEREO
180 * supported alloc_method are LOUNDNESS/SNR
181 * supported bit_rate for mono channel is max 320kbps
182 * supported bit rate for stereo channel is max 512 kbps
183 */
184struct sbc_enc_cfg_t{
185 uint32_t enc_format;
186 uint32_t num_subbands;
187 uint32_t blk_len;
188 uint32_t channel_mode;
189 uint32_t alloc_method;
190 uint32_t bit_rate;
191 uint32_t sample_rate;
192};
193
194
195/* supported num_channels are Mono/Stereo
196 * supported channel_mapping for mono is CHANNEL_C
197 * supported channel mapping for stereo is CHANNEL_L and CHANNEL_R
198 * custom size and reserved are not used(for future enhancement)
199 */
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530200struct custom_enc_cfg_t
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530201{
202 uint32_t enc_format;
203 uint32_t sample_rate;
204 uint16_t num_channels;
205 uint16_t reserved;
206 uint8_t channel_mapping[8];
207 uint32_t custom_size;
208};
209
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530210struct celt_specific_enc_cfg_t
211{
212 uint32_t bit_rate;
213 uint16_t frame_size;
214 uint16_t complexity;
215 uint16_t prediction_mode;
216 uint16_t vbr_flag;
217};
218
219struct celt_enc_cfg_t
220{
221 struct custom_enc_cfg_t custom_cfg;
222 struct celt_specific_enc_cfg_t celt_cfg;
223};
224
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530225/* TODO: Define the following structures only for O using PLATFORM_VERSION */
226/* Information about BT SBC encoder configuration
227 * This data is used between audio HAL module and
228 * BT IPC library to configure DSP encoder
229 */
230typedef struct {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530231 uint32_t subband; /* 4, 8 */
232 uint32_t blk_len; /* 4, 8, 12, 16 */
233 uint16_t sampling_rate; /*44.1khz,48khz*/
234 uint8_t channels; /*0(Mono),1(Dual_mono),2(Stereo),3(JS)*/
235 uint8_t alloc; /*0(Loudness),1(SNR)*/
236 uint8_t min_bitpool; /* 2 */
237 uint8_t max_bitpool; /*53(44.1khz),51 (48khz) */
238 uint32_t bitrate; /* 320kbps to 512kbps */
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530239} audio_sbc_encoder_config;
240
241
242/* Information about BT APTX encoder configuration
243 * This data is used between audio HAL module and
244 * BT IPC library to configure DSP encoder
245 */
246typedef struct {
247 uint16_t sampling_rate;
248 uint8_t channels;
249 uint32_t bitrate;
250} audio_aptx_encoder_config;
251
252
253/* Information about BT AAC encoder configuration
254 * This data is used between audio HAL module and
255 * BT IPC library to configure DSP encoder
256 */
257typedef struct {
258 uint32_t enc_mode; /* LC, SBR, PS */
259 uint16_t format_flag; /* RAW, ADTS */
260 uint16_t channels; /* 1-Mono, 2-Stereo */
261 uint32_t sampling_rate;
262 uint32_t bitrate;
263} audio_aac_encoder_config;
264
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530265/* Information about BT CELT encoder configuration
266 * This data is used between audio HAL module and
267 * BT IPC library to configure DSP encoder
268 */
269typedef struct {
270 uint32_t sampling_rate; /* 32000 - 48000, 48000 */
271 uint16_t channels; /* 1-Mono, 2-Stereo, 2*/
272 uint16_t frame_size; /* 64-128-256-512, 512 */
273 uint16_t complexity; /* 0-10, 1 */
274 uint16_t prediction_mode; /* 0-1-2, 0 */
275 uint16_t vbr_flag; /* 0-1, 0*/
276 uint32_t bitrate; /*32000 - 1536000, 139500*/
277} audio_celt_encoder_config;
278
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530279/*********** END of DSP configurable structures ********************/
280
281/* API to identify DSP encoder captabilities */
282static void a2dp_offload_codec_cap_parser(char *value)
283{
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530284 char *tok = NULL,*saveptr;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530285
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530286 tok = strtok_r(value, "-", &saveptr);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530287 while (tok != NULL) {
288 if (strcmp(tok, "sbc") == 0) {
289 ALOGD("%s: SBC offload supported\n",__func__);
290 a2dp.is_a2dp_offload_supported = true;
291 break;
292 } else if (strcmp(tok, "aptx") == 0) {
293 ALOGD("%s: aptx offload supported\n",__func__);
294 a2dp.is_a2dp_offload_supported = true;
295 break;
Naresh Tannirued694c82017-02-07 17:01:28 +0530296 } else if (strcmp(tok, "aptxhd") == 0) {
297 ALOGD("%s: aptx HD offload supported\n",__func__);
298 a2dp.is_a2dp_offload_supported = true;
299 break;
300 } else if (strcmp(tok, "aac") == 0) {
301 ALOGD("%s: aac offload supported\n",__func__);
302 a2dp.is_a2dp_offload_supported = true;
303 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530304 } else if (strcmp(tok, "celt") == 0) {
305 ALOGD("%s: celt offload supported\n",__func__);
306 a2dp.is_a2dp_offload_supported = true;
307 break;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530308 }
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530309 tok = strtok_r(NULL, "-", &saveptr);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530310 };
311}
312
313static void update_offload_codec_capabilities()
314{
315 char value[PROPERTY_VALUE_MAX] = {'\0'};
316
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -0700317 property_get("persist.vendor.bt.a2dp_offload_cap", value, "false");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530318 ALOGD("get_offload_codec_capabilities = %s",value);
319 a2dp.is_a2dp_offload_supported =
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -0700320 property_get_bool("persist.vendor.bt.a2dp_offload_cap", false);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530321 if (strcmp(value, "false") != 0)
322 a2dp_offload_codec_cap_parser(value);
323 ALOGD("%s: codec cap = %s",__func__,value);
324}
325
326/* API to open BT IPC library to start IPC communication */
327static void open_a2dp_output()
328{
329 int ret = 0;
330
331 ALOGD(" Open A2DP output start ");
332 if (a2dp.bt_lib_handle == NULL){
333 ALOGD(" Requesting for BT lib handle");
334 a2dp.bt_lib_handle = dlopen(BT_IPC_LIB_NAME, RTLD_NOW);
335
336 if (a2dp.bt_lib_handle == NULL) {
337 ALOGE("%s: DLOPEN failed for %s", __func__, BT_IPC_LIB_NAME);
338 ret = -ENOSYS;
339 goto init_fail;
340 } else {
341 a2dp.audio_stream_open = (audio_stream_open_t)
342 dlsym(a2dp.bt_lib_handle, "audio_stream_open");
343 a2dp.audio_start_stream = (audio_start_stream_t)
344 dlsym(a2dp.bt_lib_handle, "audio_start_stream");
345 a2dp.audio_get_codec_config = (audio_get_codec_config_t)
346 dlsym(a2dp.bt_lib_handle, "audio_get_codec_config");
347 a2dp.audio_suspend_stream = (audio_suspend_stream_t)
348 dlsym(a2dp.bt_lib_handle, "audio_suspend_stream");
349 a2dp.audio_handoff_triggered = (audio_handoff_triggered_t)
350 dlsym(a2dp.bt_lib_handle, "audio_handoff_triggered");
351 a2dp.clear_a2dpsuspend_flag = (clear_a2dpsuspend_flag_t)
352 dlsym(a2dp.bt_lib_handle, "clear_a2dpsuspend_flag");
353 a2dp.audio_stop_stream = (audio_stop_stream_t)
354 dlsym(a2dp.bt_lib_handle, "audio_stop_stream");
355 a2dp.audio_stream_close = (audio_stream_close_t)
356 dlsym(a2dp.bt_lib_handle, "audio_stream_close");
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530357 a2dp.audio_check_a2dp_ready = (audio_check_a2dp_ready_t)
358 dlsym(a2dp.bt_lib_handle,"audio_check_a2dp_ready");
yidongh0515e042017-07-06 15:00:34 +0800359 a2dp.audio_get_a2dp_sink_latency = (audio_get_a2dp_sink_latency_t)
360 dlsym(a2dp.bt_lib_handle,"audio_get_a2dp_sink_latency");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530361 }
362 }
363
364 if (a2dp.bt_lib_handle && a2dp.audio_stream_open) {
365 if (a2dp.bt_state == A2DP_STATE_DISCONNECTED) {
366 ALOGD("calling BT stream open");
367 ret = a2dp.audio_stream_open();
368 if(ret != 0) {
369 ALOGE("Failed to open output stream for a2dp: status %d", ret);
370 goto init_fail;
371 }
372 a2dp.bt_state = A2DP_STATE_CONNECTED;
373 } else {
374 ALOGD("Called a2dp open with improper state, Ignoring request state %d", a2dp.bt_state);
375 }
376 } else {
377 ALOGE("a2dp handle is not identified, Ignoring open request");
378 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
379 goto init_fail;
380 }
381
382init_fail:
383 if(ret != 0 && (a2dp.bt_lib_handle != NULL)) {
384 dlclose(a2dp.bt_lib_handle);
385 a2dp.bt_lib_handle = NULL;
386 }
387}
388
389static int close_a2dp_output()
390{
391 ALOGV("%s\n",__func__);
392 if (!(a2dp.bt_lib_handle && a2dp.audio_stream_close)) {
393 ALOGE("a2dp handle is not identified, Ignoring close request");
394 return -ENOSYS;
395 }
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530396 if (a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530397 ALOGD("calling BT stream close");
398 if(a2dp.audio_stream_close() == false)
399 ALOGE("failed close a2dp control path from BT library");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530400 }
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530401 a2dp.a2dp_started = false;
402 a2dp.a2dp_total_active_session_request = 0;
403 a2dp.a2dp_suspended = false;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530404 a2dp.bt_encoder_format = ENC_CODEC_TYPE_INVALID;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530405 a2dp.enc_sampling_rate = 48000;
406 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530407
408 return 0;
409}
410
411/* API to configure SBC DSP encoder */
412bool configure_sbc_enc_format(audio_sbc_encoder_config *sbc_bt_cfg)
413{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530414 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530415 struct sbc_enc_cfg_t sbc_dsp_cfg;
416 bool is_configured = false;
417 int ret = 0;
418
419 if(sbc_bt_cfg == NULL)
420 return false;
421
422 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
423 if (!ctl_enc_data) {
424 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
425 is_configured = false;
426 goto fail;
427 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530428 memset(&sbc_dsp_cfg, 0x0, sizeof(struct sbc_enc_cfg_t));
429 sbc_dsp_cfg.enc_format = ENC_MEDIA_FMT_SBC;
430 sbc_dsp_cfg.num_subbands = sbc_bt_cfg->subband;
431 sbc_dsp_cfg.blk_len = sbc_bt_cfg->blk_len;
432 switch(sbc_bt_cfg->channels) {
433 case 0:
434 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_MONO;
435 break;
436 case 1:
437 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO;
438 break;
439 case 3:
440 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO;
441 break;
442 case 2:
443 default:
444 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_STEREO;
445 break;
446 }
447 if (sbc_bt_cfg->alloc)
448 sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS;
449 else
450 sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR;
451 sbc_dsp_cfg.bit_rate = sbc_bt_cfg->bitrate;
452 sbc_dsp_cfg.sample_rate = sbc_bt_cfg->sampling_rate;
453 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&sbc_dsp_cfg,
454 sizeof(struct sbc_enc_cfg_t));
455 if (ret != 0) {
456 ALOGE("%s: failed to set SBC encoder config", __func__);
457 is_configured = false;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530458 goto fail;
459 }
460 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
461 MIXER_ENC_BIT_FORMAT);
462 if (!ctrl_bit_format) {
463 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
464 is_configured = false;
465 goto fail;
466 }
467 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
468 if (ret != 0) {
469 ALOGE("%s: Failed to set bit format to encoder", __func__);
470 is_configured = false;
471 goto fail;
472 }
473 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530474 a2dp.bt_encoder_format = ENC_CODEC_TYPE_SBC;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530475 a2dp.enc_sampling_rate = sbc_bt_cfg->sampling_rate;
476 ALOGV("Successfully updated SBC enc format with samplingrate: %d channelmode:%d",
477 sbc_dsp_cfg.sample_rate, sbc_dsp_cfg.channel_mode);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530478fail:
479 return is_configured;
480}
481
482/* API to configure APTX DSP encoder */
483bool configure_aptx_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
484{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530485 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530486 struct custom_enc_cfg_t aptx_dsp_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530487 bool is_configured = false;
488 int ret = 0;
489
490 if(aptx_bt_cfg == NULL)
491 return false;
492
493 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
494 if (!ctl_enc_data) {
495 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
496 is_configured = false;
497 goto fail;
498 }
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530499 memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530500 aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX;
501 aptx_dsp_cfg.sample_rate = aptx_bt_cfg->sampling_rate;
502 aptx_dsp_cfg.num_channels = aptx_bt_cfg->channels;
503 switch(aptx_dsp_cfg.num_channels) {
504 case 1:
505 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_C;
506 break;
507 case 2:
508 default:
509 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_L;
510 aptx_dsp_cfg.channel_mapping[1] = PCM_CHANNEL_R;
511 break;
512 }
513 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530514 sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530515 if (ret != 0) {
516 ALOGE("%s: Failed to set APTX encoder config", __func__);
517 is_configured = false;
518 goto fail;
519 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530520 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
521 MIXER_ENC_BIT_FORMAT);
522 if (!ctrl_bit_format) {
523 ALOGE("ERROR bit format CONFIG data mixer control not identifed");
524 is_configured = false;
525 goto fail;
526 } else {
527 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
528 if (ret != 0) {
529 ALOGE("%s: Failed to set bit format to encoder", __func__);
530 is_configured = false;
531 goto fail;
532 }
533 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530534 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530535 a2dp.bt_encoder_format = ENC_CODEC_TYPE_APTX;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530536 a2dp.enc_sampling_rate = aptx_bt_cfg->sampling_rate;
537 ALOGV("Successfully updated APTX enc format with samplingrate: %d channels:%d",
538 aptx_dsp_cfg.sample_rate, aptx_dsp_cfg.num_channels);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530539fail:
540 return is_configured;
541}
542
543/* API to configure APTX HD DSP encoder
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530544 */
545bool configure_aptx_hd_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
546{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530547 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530548 struct custom_enc_cfg_t aptx_dsp_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530549 bool is_configured = false;
550 int ret = 0;
551
552 if(aptx_bt_cfg == NULL)
553 return false;
554
555 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
556 if (!ctl_enc_data) {
557 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
558 is_configured = false;
559 goto fail;
560 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530561
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530562 memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530563 aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX_HD;
564 aptx_dsp_cfg.sample_rate = aptx_bt_cfg->sampling_rate;
565 aptx_dsp_cfg.num_channels = aptx_bt_cfg->channels;
566 switch(aptx_dsp_cfg.num_channels) {
567 case 1:
568 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_C;
569 break;
570 case 2:
571 default:
572 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_L;
573 aptx_dsp_cfg.channel_mapping[1] = PCM_CHANNEL_R;
574 break;
575 }
576 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530577 sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530578 if (ret != 0) {
579 ALOGE("%s: Failed to set APTX HD encoder config", __func__);
580 is_configured = false;
581 goto fail;
582 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530583 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
584 if (!ctrl_bit_format) {
585 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
586 is_configured = false;
587 goto fail;
588 }
589 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S24_LE");
590 if (ret != 0) {
591 ALOGE("%s: Failed to set APTX HD encoder config", __func__);
592 is_configured = false;
593 goto fail;
594 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530595 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530596 a2dp.bt_encoder_format = ENC_CODEC_TYPE_APTX_HD;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530597 a2dp.enc_sampling_rate = aptx_bt_cfg->sampling_rate;
598 ALOGV("Successfully updated APTX HD encformat with samplingrate: %d channels:%d",
599 aptx_dsp_cfg.sample_rate, aptx_dsp_cfg.num_channels);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530600fail:
601 return is_configured;
602}
603
604/* API to configure AAC DSP encoder */
605bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg)
606{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530607 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530608 struct aac_enc_cfg_t aac_dsp_cfg;
609 bool is_configured = false;
610 int ret = 0;
611
612 if(aac_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 Tanniru9d027a62015-03-13 01:32:10 +0530621 memset(&aac_dsp_cfg, 0x0, sizeof(struct aac_enc_cfg_t));
622 aac_dsp_cfg.enc_format = ENC_MEDIA_FMT_AAC;
623 aac_dsp_cfg.bit_rate = aac_bt_cfg->bitrate;
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530624 aac_dsp_cfg.sample_rate = aac_bt_cfg->sampling_rate;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530625 switch(aac_bt_cfg->enc_mode) {
626 case 0:
627 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC;
628 break;
629 case 2:
630 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS;
631 break;
632 case 1:
633 default:
634 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR;
635 break;
636 }
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530637 aac_dsp_cfg.aac_fmt_flag = aac_bt_cfg->format_flag;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530638 aac_dsp_cfg.channel_cfg = aac_bt_cfg->channels;
639 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aac_dsp_cfg,
640 sizeof(struct aac_enc_cfg_t));
641 if (ret != 0) {
642 ALOGE("%s: failed to set SBC encoder config", __func__);
643 is_configured = false;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530644 goto fail;
645 }
646 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
647 MIXER_ENC_BIT_FORMAT);
648 if (!ctrl_bit_format) {
649 is_configured = false;
650 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
651 goto fail;
652 }
653 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
654 if (ret != 0) {
655 ALOGE("%s: Failed to set bit format to encoder", __func__);
656 is_configured = false;
657 goto fail;
658 }
659 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530660 a2dp.bt_encoder_format = ENC_CODEC_TYPE_AAC;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530661 a2dp.enc_sampling_rate = aac_bt_cfg->sampling_rate;
662 ALOGV("Successfully updated AAC enc format with samplingrate: %d channels:%d",
663 aac_dsp_cfg.sample_rate, aac_dsp_cfg.channel_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530664fail:
665 return is_configured;
666}
667
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530668bool configure_celt_enc_format(audio_celt_encoder_config *celt_bt_cfg)
669{
670 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
671 struct celt_enc_cfg_t celt_dsp_cfg;
672 bool is_configured = false;
673 int ret = 0;
674 if(celt_bt_cfg == NULL)
675 return false;
676
677 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
678 if (!ctl_enc_data) {
679 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
680 is_configured = false;
681 goto fail;
682 }
683 memset(&celt_dsp_cfg, 0x0, sizeof(struct celt_enc_cfg_t));
684
685 celt_dsp_cfg.custom_cfg.enc_format = ENC_MEDIA_FMT_CELT;
686 celt_dsp_cfg.custom_cfg.sample_rate = celt_bt_cfg->sampling_rate;
687 celt_dsp_cfg.custom_cfg.num_channels = celt_bt_cfg->channels;
688 switch(celt_dsp_cfg.custom_cfg.num_channels) {
689 case 1:
690 celt_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_C;
691 break;
692 case 2:
693 default:
694 celt_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
695 celt_dsp_cfg.custom_cfg.channel_mapping[1] = PCM_CHANNEL_R;
696 break;
697 }
698
699 celt_dsp_cfg.custom_cfg.custom_size = sizeof(struct celt_enc_cfg_t);
700
701 celt_dsp_cfg.celt_cfg.frame_size = celt_bt_cfg->frame_size;
702 celt_dsp_cfg.celt_cfg.complexity = celt_bt_cfg->complexity;
703 celt_dsp_cfg.celt_cfg.prediction_mode = celt_bt_cfg->prediction_mode;
704 celt_dsp_cfg.celt_cfg.vbr_flag = celt_bt_cfg->vbr_flag;
705 celt_dsp_cfg.celt_cfg.bit_rate = celt_bt_cfg->bitrate;
706
707 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&celt_dsp_cfg,
708 sizeof(struct celt_enc_cfg_t));
709 if (ret != 0) {
710 ALOGE("%s: Failed to set CELT encoder config", __func__);
711 is_configured = false;
712 goto fail;
713 }
714 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
715 if (!ctrl_bit_format) {
716 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
717 is_configured = false;
718 goto fail;
719 }
720 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
721 if (ret != 0) {
722 ALOGE("%s: Failed to set bit format to encoder", __func__);
723 is_configured = false;
724 goto fail;
725 }
726 is_configured = true;
727 a2dp.bt_encoder_format = ENC_CODEC_TYPE_CELT;
728 a2dp.enc_sampling_rate = celt_bt_cfg->sampling_rate;
729 ALOGV("Successfully updated CELT encformat with samplingrate: %d channels:%d",
730 celt_dsp_cfg.custom_cfg.sample_rate, celt_dsp_cfg.custom_cfg.num_channels);
731fail:
732 return is_configured;
733}
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530734bool configure_a2dp_encoder_format()
735{
736 void *codec_info = NULL;
737 uint8_t multi_cast = 0, num_dev = 1;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530738 enc_codec_t codec_type = ENC_CODEC_TYPE_INVALID;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530739 bool is_configured = false;
740
741 if (!a2dp.audio_get_codec_config) {
742 ALOGE(" a2dp handle is not identified, ignoring a2dp encoder config");
743 return false;
744 }
745 ALOGD("configure_a2dp_encoder_format start");
746 codec_info = a2dp.audio_get_codec_config(&multi_cast, &num_dev,
747 &codec_type);
748
749 switch(codec_type) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530750 case ENC_CODEC_TYPE_SBC:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530751 ALOGD(" Received SBC encoder supported BT device");
752 is_configured =
753 configure_sbc_enc_format((audio_sbc_encoder_config *)codec_info);
754 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530755 case ENC_CODEC_TYPE_APTX:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530756 ALOGD(" Received APTX encoder supported BT device");
757 is_configured =
758 configure_aptx_enc_format((audio_aptx_encoder_config *)codec_info);
759 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530760 case ENC_CODEC_TYPE_APTX_HD:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530761 ALOGD(" Received APTX HD encoder supported BT device");
762 is_configured =
763 configure_aptx_hd_enc_format((audio_aptx_encoder_config *)codec_info);
764 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530765 case ENC_CODEC_TYPE_AAC:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530766 ALOGD(" Received AAC encoder supported BT device");
767 is_configured =
768 configure_aac_enc_format((audio_aac_encoder_config *)codec_info);
769 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530770 case ENC_CODEC_TYPE_CELT:
771 ALOGD(" Received CELT encoder supported BT device");
772 is_configured =
773 configure_celt_enc_format((audio_celt_encoder_config *)codec_info);
774 break;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530775 default:
776 ALOGD(" Received Unsupported encoder formar");
777 is_configured = false;
778 break;
779 }
780 return is_configured;
781}
782
783int audio_extn_a2dp_start_playback()
784{
785 int ret = 0;
786
787 ALOGD("audio_extn_a2dp_start_playback start");
788
789 if(!(a2dp.bt_lib_handle && a2dp.audio_start_stream
790 && a2dp.audio_get_codec_config)) {
791 ALOGE("a2dp handle is not identified, Ignoring start request");
792 return -ENOSYS;
793 }
794
795 if(a2dp.a2dp_suspended == true) {
796 //session will be restarted after suspend completion
797 ALOGD("a2dp start requested during suspend state");
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530798 return -ENOSYS;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530799 }
800
801 if (!a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
802 ALOGD("calling BT module stream start");
803 /* This call indicates BT IPC lib to start playback */
804 ret = a2dp.audio_start_stream();
805 ALOGE("BT controller start return = %d",ret);
806 if (ret != 0 ) {
807 ALOGE("BT controller start failed");
808 a2dp.a2dp_started = false;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530809 } else {
810 if(configure_a2dp_encoder_format() == true) {
811 a2dp.a2dp_started = true;
812 ret = 0;
813 ALOGD("Start playback successful to BT library");
814 } else {
815 ALOGD(" unable to configure DSP encoder");
816 a2dp.a2dp_started = false;
817 ret = -ETIMEDOUT;
818 }
819 }
820 }
821
822 if (a2dp.a2dp_started)
823 a2dp.a2dp_total_active_session_request++;
824
825 ALOGD("start A2DP playback total active sessions :%d",
826 a2dp.a2dp_total_active_session_request);
827 return ret;
828}
829
Naresh Tanniru03f9dd52016-10-19 18:46:22 +0530830static void reset_a2dp_enc_config_params()
831{
832 int ret =0;
833
834 struct mixer_ctl *ctl_enc_config, *ctrl_bit_format;
835 struct sbc_enc_cfg_t dummy_reset_config;
836
837 memset(&dummy_reset_config, 0x0, sizeof(struct sbc_enc_cfg_t));
838 ctl_enc_config = mixer_get_ctl_by_name(a2dp.adev->mixer,
839 MIXER_ENC_CONFIG_BLOCK);
840 if (!ctl_enc_config) {
841 ALOGE(" ERROR a2dp encoder format mixer control not identifed");
842 } else {
843 ret = mixer_ctl_set_array(ctl_enc_config, (void *)&dummy_reset_config,
844 sizeof(struct sbc_enc_cfg_t));
845 a2dp.bt_encoder_format = ENC_MEDIA_FMT_NONE;
846 }
847 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
848 MIXER_ENC_BIT_FORMAT);
849 if (!ctrl_bit_format) {
850 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
851 } else {
852 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
853 if (ret != 0) {
854 ALOGE("%s: Failed to set bit format to encoder", __func__);
855 }
856 }
857}
858
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530859int audio_extn_a2dp_stop_playback()
860{
861 int ret =0;
862
863 ALOGV("audio_extn_a2dp_stop_playback start");
864 if(!(a2dp.bt_lib_handle && a2dp.audio_stop_stream)) {
865 ALOGE("a2dp handle is not identified, Ignoring start request");
866 return -ENOSYS;
867 }
868
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530869 if (a2dp.a2dp_total_active_session_request > 0)
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530870 a2dp.a2dp_total_active_session_request--;
871
872 if ( a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530873 ALOGV("calling BT module stream stop");
874 ret = a2dp.audio_stop_stream();
875 if (ret < 0)
876 ALOGE("stop stream to BT IPC lib failed");
877 else
878 ALOGV("stop steam to BT IPC lib successful");
Naresh Tanniru03f9dd52016-10-19 18:46:22 +0530879 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530880 }
881 if(!a2dp.a2dp_total_active_session_request)
882 a2dp.a2dp_started = false;
883 ALOGD("Stop A2DP playback total active sessions :%d",
884 a2dp.a2dp_total_active_session_request);
885 return 0;
886}
887
888void audio_extn_a2dp_set_parameters(struct str_parms *parms)
889{
890 int ret, val;
891 char value[32]={0};
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +0530892 struct audio_usecase *uc_info;
893 struct listnode *node;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530894
895 if(a2dp.is_a2dp_offload_supported == false) {
896 ALOGV("no supported encoders identified,ignoring a2dp setparam");
897 return;
898 }
899
900 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
901 sizeof(value));
902 if( ret >= 0) {
903 val = atoi(value);
904 if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
905 ALOGV("Received device connect request for A2DP");
906 open_a2dp_output();
907 }
908 goto param_handled;
909 }
910
911 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value,
912 sizeof(value));
913
914 if( ret >= 0) {
915 val = atoi(value);
916 if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
917 ALOGV("Received device dis- connect request");
Naresh Tanniru03f9dd52016-10-19 18:46:22 +0530918 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530919 close_a2dp_output();
920 }
921 goto param_handled;
922 }
923
924 ret = str_parms_get_str(parms, "A2dpSuspended", value, sizeof(value));
925 if (ret >= 0) {
926 if (a2dp.bt_lib_handle && (a2dp.bt_state != A2DP_STATE_DISCONNECTED) ) {
927 if ((!strncmp(value,"true",sizeof(value)))) {
928 ALOGD("Setting a2dp to suspend state");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530929 a2dp.a2dp_suspended = true;
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +0530930 list_for_each(node, &a2dp.adev->usecase_list) {
931 uc_info = node_to_item(node, struct audio_usecase, list);
932 if (uc_info->type == PCM_PLAYBACK) {
933 pthread_mutex_unlock(&a2dp.adev->lock);
934 check_a2dp_restore(a2dp.adev, uc_info->stream.out, false);
935 pthread_mutex_lock(&a2dp.adev->lock);
936 }
937 }
Naresh Tanniru03f9dd52016-10-19 18:46:22 +0530938 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530939 if(a2dp.audio_suspend_stream)
940 a2dp.audio_suspend_stream();
941 } else if (a2dp.a2dp_suspended == true) {
942 ALOGD("Resetting a2dp suspend state");
Zhou Song10617ed2017-05-26 13:28:48 +0800943 struct audio_usecase *uc_info;
944 struct listnode *node;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530945 if(a2dp.clear_a2dpsuspend_flag)
946 a2dp.clear_a2dpsuspend_flag();
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530947 a2dp.a2dp_suspended = false;
Naresh Tanniru649871a2016-11-04 18:08:32 +0530948 /*
949 * It is possible that before suspend,a2dp sessions can be active
950 * for example during music + voice activation concurrency
951 * a2dp suspend will be called & BT will change to sco mode
952 * though music is paused as a part of voice activation
953 * compress session close happens only after pause timeout(10secs)
954 * so if resume request comes before pause timeout as a2dp session
955 * is already active IPC start will not be called from APM/audio_hw
956 * Fix is to call a2dp start for IPC library post suspend
957 * based on number of active session count
958 */
959 if (a2dp.a2dp_total_active_session_request > 0) {
960 ALOGD(" Calling IPC lib start post suspend state");
961 if(a2dp.audio_start_stream) {
962 ret = a2dp.audio_start_stream();
963 if (ret != 0) {
964 ALOGE("BT controller start failed");
965 a2dp.a2dp_started = false;
966 }
967 }
968 }
Zhou Song10617ed2017-05-26 13:28:48 +0800969 list_for_each(node, &a2dp.adev->usecase_list) {
970 uc_info = node_to_item(node, struct audio_usecase, list);
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +0530971 if (uc_info->type == PCM_PLAYBACK) {
972 pthread_mutex_unlock(&a2dp.adev->lock);
973 check_a2dp_restore(a2dp.adev, uc_info->stream.out, true);
974 pthread_mutex_lock(&a2dp.adev->lock);
975 }
Zhou Song10617ed2017-05-26 13:28:48 +0800976 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530977 }
978 }
979 goto param_handled;
980 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530981param_handled:
982 ALOGV("end of a2dp setparam");
983}
984
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530985void audio_extn_a2dp_set_handoff_mode(bool is_on)
986{
987 a2dp.is_handoff_in_progress = is_on;
988}
989
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530990bool audio_extn_a2dp_is_force_device_switch()
991{
992 //During encoder reconfiguration mode, force a2dp device switch
Ashish Jainc597d102016-12-12 10:31:34 +0530993 // Or if a2dp device is selected but earlier start failed ( as a2dp
994 // was suspended, force retry.
995 return a2dp.is_handoff_in_progress || !a2dp.a2dp_started;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530996}
997
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530998void audio_extn_a2dp_get_apptype_params(uint32_t *sample_rate,
999 uint32_t *bit_width)
1000{
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301001 if(a2dp.bt_encoder_format == ENC_CODEC_TYPE_APTX_HD)
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301002 *bit_width = 24;
1003 else
1004 *bit_width = 16;
1005 *sample_rate = a2dp.enc_sampling_rate;
1006}
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301007
1008bool audio_extn_a2dp_is_ready()
1009{
1010 bool ret = false;
1011
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301012 if (a2dp.a2dp_suspended)
1013 return ret;
1014
Aniket Kumar Lata901bcb82017-03-10 15:42:46 -08001015 if ((a2dp.bt_state != A2DP_STATE_DISCONNECTED) &&
1016 (a2dp.is_a2dp_offload_supported) &&
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301017 (a2dp.audio_check_a2dp_ready))
1018 ret = a2dp.audio_check_a2dp_ready();
1019 return ret;
1020}
1021
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301022bool audio_extn_a2dp_is_suspended()
1023{
1024 return a2dp.a2dp_suspended;
1025}
1026
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301027void audio_extn_a2dp_init (void *adev)
1028{
1029 a2dp.adev = (struct audio_device*)adev;
1030 a2dp.bt_lib_handle = NULL;
1031 a2dp.a2dp_started = false;
1032 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
1033 a2dp.a2dp_total_active_session_request = 0;
1034 a2dp.a2dp_suspended = false;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301035 a2dp.bt_encoder_format = ENC_CODEC_TYPE_INVALID;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301036 a2dp.enc_sampling_rate = 48000;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301037 a2dp.is_a2dp_offload_supported = false;
1038 a2dp.is_handoff_in_progress = false;
1039 update_offload_codec_capabilities();
1040}
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001041
1042uint32_t audio_extn_a2dp_get_encoder_latency()
1043{
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001044 uint32_t latency = 0;
1045 int avsync_runtime_prop = 0;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301046 int sbc_offset = 0, aptx_offset = 0, aptxhd_offset = 0, aac_offset = 0, celt_offset = 0;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001047 char value[PROPERTY_VALUE_MAX];
1048
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001049 memset(value, '\0', sizeof(char)*PROPERTY_VALUE_MAX);
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -07001050 avsync_runtime_prop = property_get("vendor.audio.a2dp.codec.latency", value, NULL);
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001051 if (avsync_runtime_prop > 0) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301052 if (sscanf(value, "%d/%d/%d/%d/%d",
1053 &sbc_offset, &aptx_offset, &aptxhd_offset, &aac_offset, &celt_offset) != 5) {
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001054 ALOGI("Failed to parse avsync offset params from '%s'.", value);
1055 avsync_runtime_prop = 0;
1056 }
1057 }
1058
yidongh0515e042017-07-06 15:00:34 +08001059 uint32_t slatency = 0;
1060 if (a2dp.audio_get_a2dp_sink_latency && a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
1061 slatency = a2dp.audio_get_a2dp_sink_latency();
1062 }
1063
Aniket Kumar Latafaaffde2017-03-22 19:18:15 -07001064 switch(a2dp.bt_encoder_format) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301065 case ENC_CODEC_TYPE_SBC:
yidongh0515e042017-07-06 15:00:34 +08001066 latency = (avsync_runtime_prop > 0) ? sbc_offset : ENCODER_LATENCY_SBC;
1067 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_SBC : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001068 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301069 case ENC_CODEC_TYPE_APTX:
yidongh0515e042017-07-06 15:00:34 +08001070 latency = (avsync_runtime_prop > 0) ? aptx_offset : ENCODER_LATENCY_APTX;
1071 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001072 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301073 case ENC_CODEC_TYPE_APTX_HD:
yidongh0515e042017-07-06 15:00:34 +08001074 latency = (avsync_runtime_prop > 0) ? aptxhd_offset : ENCODER_LATENCY_APTX_HD;
1075 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX_HD : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001076 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301077 case ENC_CODEC_TYPE_AAC:
yidongh0515e042017-07-06 15:00:34 +08001078 latency = (avsync_runtime_prop > 0) ? aac_offset : ENCODER_LATENCY_AAC;
1079 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_AAC : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001080 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301081 case ENC_CODEC_TYPE_CELT:
1082 latency = (avsync_runtime_prop > 0) ? celt_offset : ENCODER_LATENCY_CELT;
1083 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_CELT : slatency;
1084 break;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001085 default:
1086 latency = 200;
1087 break;
1088 }
1089 return latency;
1090}
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301091#endif // SPLIT_A2DP_ENABLED