mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
components/bt: Enable mSBC and add decoder and encoder
This commit is contained in:
parent
20758443df
commit
dd906a91a5
@ -232,6 +232,8 @@ const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = {
|
|||||||
bta_hf_client_st_closing
|
bta_hf_client_st_closing
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char *bta_hf_client_version = "1.6";
|
||||||
|
|
||||||
/* HF Client control block */
|
/* HF Client control block */
|
||||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||||
tBTA_HF_CLIENT_CB bta_hf_client_cb;
|
tBTA_HF_CLIENT_CB bta_hf_client_cb;
|
||||||
@ -385,15 +387,11 @@ static void bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA *p_data)
|
|||||||
bta_hf_client_cb.p_cback = p_data->api_enable.p_cback;
|
bta_hf_client_cb.p_cback = p_data->api_enable.p_cback;
|
||||||
|
|
||||||
/* check if mSBC support enabled */
|
/* check if mSBC support enabled */
|
||||||
#if 0 // todo
|
if (strcmp(bta_hf_client_version, "1.6") == 0) {
|
||||||
char value[PROPERTY_VALUE_MAX];
|
|
||||||
property_get("ro.bluetooth.hfp.ver", value, "0");
|
|
||||||
if (strcmp(value, "1.6") == 0) {
|
|
||||||
bta_hf_client_cb.msbc_enabled = TRUE;
|
bta_hf_client_cb.msbc_enabled = TRUE;
|
||||||
}
|
} else{
|
||||||
#else
|
|
||||||
bta_hf_client_cb.msbc_enabled = FALSE;
|
bta_hf_client_cb.msbc_enabled = FALSE;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
|
bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
|
||||||
|
|
||||||
|
@ -268,13 +268,28 @@ static void bta_hf_client_sco_conn_cback(UINT16 sco_idx)
|
|||||||
{
|
{
|
||||||
BT_HDR *p_buf;
|
BT_HDR *p_buf;
|
||||||
UINT8 *rem_bd;
|
UINT8 *rem_bd;
|
||||||
|
tBTM_ESCO_DATA sco_data;
|
||||||
|
|
||||||
APPL_TRACE_DEBUG("%s %d", __FUNCTION__, sco_idx);
|
APPL_TRACE_DEBUG("%s %d", __FUNCTION__, sco_idx);
|
||||||
|
|
||||||
rem_bd = BTM_ReadScoBdAddr(sco_idx);
|
rem_bd = BTM_ReadScoBdAddr(sco_idx);
|
||||||
|
BTM_ReadEScoLinkParms (sco_idx, &sco_data);
|
||||||
|
|
||||||
if (rem_bd && bdcmp(bta_hf_client_cb.scb.peer_addr, rem_bd) == 0 &&
|
if (rem_bd && bdcmp(bta_hf_client_cb.scb.peer_addr, rem_bd) == 0 &&
|
||||||
bta_hf_client_cb.scb.svc_conn && bta_hf_client_cb.scb.sco_idx == sco_idx) {
|
bta_hf_client_cb.scb.svc_conn && bta_hf_client_cb.scb.sco_idx == sco_idx) {
|
||||||
|
|
||||||
|
bta_hf_client_cb.scb.link_type = sco_data.link_type;
|
||||||
|
bta_hf_client_cb.scb.tx_interval = sco_data.tx_interval;
|
||||||
|
bta_hf_client_cb.scb.retrans_window = sco_data.retrans_window;
|
||||||
|
bta_hf_client_cb.scb.air_mode = sco_data.air_mode;
|
||||||
|
if (sco_data.air_mode == BTM_SCO_AIR_MODE_CVSD) {
|
||||||
|
bta_hf_client_cb.scb.tx_pkt_len = sco_data.tx_pkt_len * 2;
|
||||||
|
bta_hf_client_cb.scb.rx_pkt_len = sco_data.rx_pkt_len * 2;
|
||||||
|
} else {
|
||||||
|
bta_hf_client_cb.scb.tx_pkt_len = sco_data.tx_pkt_len;
|
||||||
|
bta_hf_client_cb.scb.rx_pkt_len = sco_data.rx_pkt_len;
|
||||||
|
}
|
||||||
|
|
||||||
if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
|
if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
|
||||||
p_buf->event = BTA_HF_CLIENT_SCO_OPEN_EVT;
|
p_buf->event = BTA_HF_CLIENT_SCO_OPEN_EVT;
|
||||||
p_buf->layer_specific = bta_hf_client_cb.scb.conn_handle;
|
p_buf->layer_specific = bta_hf_client_cb.scb.conn_handle;
|
||||||
@ -428,20 +443,20 @@ static void bta_hf_client_sco_event(UINT8 event)
|
|||||||
|
|
||||||
#if (BTM_SCO_HCI_INCLUDED == TRUE )
|
#if (BTM_SCO_HCI_INCLUDED == TRUE )
|
||||||
if (event == BTA_HF_CLIENT_SCO_CI_DATA_E) {
|
if (event == BTA_HF_CLIENT_SCO_CI_DATA_E) {
|
||||||
uint16_t pkt_offset = 1 + HCI_SCO_PREAMBLE_SIZE;
|
UINT16 pkt_offset = 1 + HCI_SCO_PREAMBLE_SIZE;
|
||||||
uint16_t len_to_send = 0;
|
UINT16 len_to_send = 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
p_buf = osi_malloc(sizeof(BT_HDR) + pkt_offset + BTM_SCO_DATA_SIZE_MAX);
|
p_buf = osi_calloc(sizeof(BT_HDR) + pkt_offset + p_scb->tx_pkt_len);
|
||||||
if (!p_buf) {
|
if (!p_buf) {
|
||||||
APPL_TRACE_WARNING("%s, no mem", __FUNCTION__);
|
APPL_TRACE_WARNING("%s, no mem", __FUNCTION__);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
p_buf->offset = pkt_offset;
|
p_buf->offset = pkt_offset;
|
||||||
p_buf->len = BTM_SCO_DATA_SIZE_MAX;
|
len_to_send = bta_hf_client_sco_co_out_data(p_buf->data + pkt_offset);
|
||||||
len_to_send = bta_hf_client_sco_co_out_data(p_buf->data + pkt_offset, BTM_SCO_DATA_SIZE_MAX);
|
p_buf->len = len_to_send;
|
||||||
if (len_to_send == BTM_SCO_DATA_SIZE_MAX) {
|
if (len_to_send == p_scb->tx_pkt_len) {
|
||||||
// expect to get the exact size of data from upper layer
|
// expect to get the exact size of data from upper layer
|
||||||
if (bta_hf_client_cb.scb.sco_state == BTA_HF_CLIENT_SCO_OPEN_ST) {
|
if (bta_hf_client_cb.scb.sco_state == BTA_HF_CLIENT_SCO_OPEN_ST) {
|
||||||
tBTM_STATUS write_stat = BTM_WriteScoData(p_scb->sco_idx, p_buf);
|
tBTM_STATUS write_stat = BTM_WriteScoData(p_scb->sco_idx, p_buf);
|
||||||
@ -731,7 +746,8 @@ void bta_hf_client_sco_conn_open(tBTA_HF_CLIENT_DATA *p_data)
|
|||||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
||||||
bta_hf_client_co_audio_state(bta_hf_client_cb.scb.sco_idx, SCO_STATE_ON, 0);
|
bta_hf_client_co_audio_state(bta_hf_client_cb.scb.sco_idx, SCO_STATE_ON, 0);
|
||||||
/* open SCO codec if SCO is routed through transport */
|
/* open SCO codec if SCO is routed through transport */
|
||||||
bta_hf_client_sco_co_open(bta_hf_client_cb.scb.sco_idx, BTA_HFP_SCO_OUT_PKT_SIZE, BTA_HF_CLIENT_CI_SCO_DATA_EVT);
|
bta_hf_client_sco_co_open(bta_hf_client_cb.scb.sco_idx, bta_hf_client_cb.scb.air_mode,
|
||||||
|
bta_hf_client_cb.scb.tx_pkt_len, BTA_HF_CLIENT_CI_SCO_DATA_EVT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_MSBC) {
|
if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_MSBC) {
|
||||||
|
@ -157,6 +157,13 @@ typedef struct {
|
|||||||
tBTM_SCO_CODEC_TYPE negotiated_codec; /* negotiated codec */
|
tBTM_SCO_CODEC_TYPE negotiated_codec; /* negotiated codec */
|
||||||
TIMER_LIST_ENT colli_timer; /* Collision timer */
|
TIMER_LIST_ENT colli_timer; /* Collision timer */
|
||||||
BOOLEAN colli_tmr_on; /* TRUE if collision timer is active */
|
BOOLEAN colli_tmr_on; /* TRUE if collision timer is active */
|
||||||
|
|
||||||
|
UINT16 rx_pkt_len;
|
||||||
|
UINT16 tx_pkt_len;
|
||||||
|
UINT8 link_type; /* BTM_LINK_TYPE_SCO or BTM_LINK_TYPE_ESCO */
|
||||||
|
UINT8 tx_interval;
|
||||||
|
UINT8 retrans_window;
|
||||||
|
UINT8 air_mode;
|
||||||
} tBTA_HF_CLIENT_SCB;
|
} tBTA_HF_CLIENT_SCB;
|
||||||
|
|
||||||
/* sco states */
|
/* sco states */
|
||||||
|
@ -73,7 +73,7 @@ tBTA_HFP_SCO_ROUTE_TYPE bta_hf_client_sco_co_init(UINT32 rx_bw, UINT32 tx_bw,
|
|||||||
** Returns void
|
** Returns void
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
void bta_hf_client_sco_co_open(UINT16 handle, UINT8 pkt_size, UINT16 event);
|
void bta_hf_client_sco_co_open(UINT16 handle, UINT8 air_mode, UINT8 pkt_size, UINT16 event);
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
@ -96,7 +96,7 @@ void bta_hf_client_sco_co_close(void);
|
|||||||
** Returns number of bytes got from application
|
** Returns number of bytes got from application
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
uint32_t bta_hf_client_sco_co_out_data(uint8_t *p_buf, uint32_t sz);
|
uint32_t bta_hf_client_sco_co_out_data(UINT8 *p_buf);
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
|
@ -516,7 +516,7 @@ static void btc_a2dp_sink_handle_decoder_reset(tBTC_MEDIA_SINK_CFG_UPDATE *p_msg
|
|||||||
btc_aa_snk_cb.rx_flush = FALSE;
|
btc_aa_snk_cb.rx_flush = FALSE;
|
||||||
APPL_TRACE_EVENT("Reset to sink role");
|
APPL_TRACE_EVENT("Reset to sink role");
|
||||||
status = OI_CODEC_SBC_DecoderReset(&btc_sbc_decoder_context, btc_sbc_decoder_context_data,
|
status = OI_CODEC_SBC_DecoderReset(&btc_sbc_decoder_context, btc_sbc_decoder_context_data,
|
||||||
BTC_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 2, 2, FALSE);
|
BTC_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 2, 2, FALSE, FALSE);
|
||||||
if (!OI_SUCCESS(status)) {
|
if (!OI_SUCCESS(status)) {
|
||||||
APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
|
APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,17 @@
|
|||||||
|
|
||||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
#include "btm_int.h"
|
||||||
|
#include "stack/btm_api.h"
|
||||||
|
#include "oi_codec_sbc.h"
|
||||||
|
#include "oi_status.h"
|
||||||
|
#include "sbc_encoder.h"
|
||||||
|
|
||||||
#if (PLC_INCLUDED == TRUE)
|
#if (PLC_INCLUDED == TRUE)
|
||||||
#include "sbc_plc.h"
|
#include "sbc_plc.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
bool first_good_frame_found;
|
||||||
sbc_plc_state_t plc_state;
|
sbc_plc_state_t plc_state;
|
||||||
int16_t sbc_plc_out[SBC_FS];
|
int16_t sbc_plc_out[SBC_FS];
|
||||||
} bta_hf_ct_plc_t;
|
} bta_hf_ct_plc_t;
|
||||||
@ -39,6 +46,31 @@ static bta_hf_ct_plc_t *bta_hf_ct_plc_ptr;
|
|||||||
|
|
||||||
#endif ///(PLC_INCLUDED == TRUE)
|
#endif ///(PLC_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
|
||||||
|
#define HF_SBC_DEC_CONTEXT_DATA_LEN (CODEC_DATA_WORDS(1, SBC_CODEC_FAST_FILTER_BUFFERS))
|
||||||
|
#define HF_SBC_DEC_PCM_DATA_LEN 240
|
||||||
|
#define HF_SBC_ENC_PCM_DATA_LEN 240
|
||||||
|
|
||||||
|
#if HFP_DYNAMIC_MEMORY == FALSE
|
||||||
|
static OI_CODEC_SBC_DECODER_CONTEXT hf_sbc_decoder_context;
|
||||||
|
static OI_UINT32 hf_sbc_decoder_context_data[HF_SBC_DEC_CONTEXT_DATA_LEN];
|
||||||
|
static OI_INT16 hf_sbc_decode_pcm_data[HF_SBC_DEC_PCM_DATA_LEN];
|
||||||
|
|
||||||
|
static SBC_ENC_PARAMS hf_sbc_encoder;
|
||||||
|
#else
|
||||||
|
static OI_CODEC_SBC_DECODER_CONTEXT *hf_sbc_decoder_context_ptr;
|
||||||
|
static OI_UINT32 *hf_sbc_decoder_context_data;
|
||||||
|
static OI_INT16 *hf_sbc_decode_pcm_data;
|
||||||
|
#define hf_sbc_decoder_context (*hf_sbc_decoder_context_ptr)
|
||||||
|
|
||||||
|
static SBC_ENC_PARAMS *hf_sbc_encoder_ptr;
|
||||||
|
#define hf_sbc_encoder (*hf_sbc_encoder_ptr)
|
||||||
|
#endif /* HFP_DYNAMIC_MEMORY == FALSE */
|
||||||
|
|
||||||
|
static UINT8 hf_sequence_number = 0;
|
||||||
|
static UINT8 hf_air_mode;
|
||||||
|
static UINT8 hf_pkt_size;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
** Function bta_hf_client_co_audio_state
|
** Function bta_hf_client_co_audio_state
|
||||||
@ -86,10 +118,56 @@ tBTA_HFP_SCO_ROUTE_TYPE bta_hf_client_sco_co_init(UINT32 rx_bw, UINT32 tx_bw,
|
|||||||
{
|
{
|
||||||
APPL_TRACE_EVENT("%s rx_bw %d, tx_bw %d, codec %d", __FUNCTION__, rx_bw, tx_bw,
|
APPL_TRACE_EVENT("%s rx_bw %d, tx_bw %d, codec %d", __FUNCTION__, rx_bw, tx_bw,
|
||||||
p_codec_info->codec_type);
|
p_codec_info->codec_type);
|
||||||
|
|
||||||
return BTA_HFP_SCO_ROUTE_HCI;
|
return BTA_HFP_SCO_ROUTE_HCI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_hf_dec_init
|
||||||
|
**
|
||||||
|
** Description Initialize decoding task
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_hf_dec_init(void) {
|
||||||
|
#if (PLC_INCLUDED == TRUE)
|
||||||
|
sbc_plc_init(&(bta_hf_ct_plc.plc_state));
|
||||||
|
#endif ///(PLC_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
OI_STATUS status;
|
||||||
|
|
||||||
|
status = OI_CODEC_SBC_DecoderReset(&hf_sbc_decoder_context, hf_sbc_decoder_context_data,
|
||||||
|
HF_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 1, 1, FALSE, TRUE);
|
||||||
|
if (!OI_SUCCESS(status)) {
|
||||||
|
APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_hf_enc_init
|
||||||
|
**
|
||||||
|
** Description Initialize encoding task
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_hf_enc_init(void) {
|
||||||
|
hf_sequence_number = 0;
|
||||||
|
|
||||||
|
hf_sbc_encoder.sbc_mode = SBC_MODE_MSBC;
|
||||||
|
hf_sbc_encoder.s16NumOfBlocks = 15;
|
||||||
|
hf_sbc_encoder.s16NumOfSubBands = 8;
|
||||||
|
hf_sbc_encoder.s16AllocationMethod = SBC_LOUDNESS;
|
||||||
|
hf_sbc_encoder.s16BitPool = 26;
|
||||||
|
hf_sbc_encoder.s16ChannelMode = SBC_MONO;
|
||||||
|
hf_sbc_encoder.s16NumOfChannels = 1;
|
||||||
|
hf_sbc_encoder.s16SamplingFreq = SBC_sf16000;
|
||||||
|
|
||||||
|
SBC_Encoder_Init(&(hf_sbc_encoder));
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
** Function bta_hf_client_sco_co_open
|
** Function bta_hf_client_sco_co_open
|
||||||
@ -100,23 +178,78 @@ tBTA_HFP_SCO_ROUTE_TYPE bta_hf_client_sco_co_init(UINT32 rx_bw, UINT32 tx_bw,
|
|||||||
** Returns void
|
** Returns void
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
void bta_hf_client_sco_co_open(UINT16 handle, UINT8 pkt_size, UINT16 event)
|
void bta_hf_client_sco_co_open(UINT16 handle, UINT8 air_mode, UINT8 pkt_size, UINT16 event)
|
||||||
{
|
{
|
||||||
APPL_TRACE_EVENT("%s hdl %x, pkt_sz %u, event %u", __FUNCTION__, handle,
|
APPL_TRACE_EVENT("%s hdl %x, pkt_sz %u, event %u", __FUNCTION__, handle,
|
||||||
pkt_size, event);
|
pkt_size, event);
|
||||||
|
|
||||||
#if (PLC_INCLUDED == TRUE)
|
hf_air_mode = air_mode;
|
||||||
|
hf_pkt_size = pkt_size;
|
||||||
|
|
||||||
|
if (air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
|
||||||
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
if ((bta_hf_ct_plc_ptr = (bta_hf_ct_plc_t *)osi_malloc(sizeof(bta_hf_ct_plc_t))) == NULL) {
|
hf_sbc_decoder_context_ptr = osi_calloc(sizeof(OI_CODEC_SBC_DECODER_CONTEXT));
|
||||||
APPL_TRACE_ERROR("%s malloc fail.", __FUNCTION__);
|
hf_sbc_decoder_context_data = osi_calloc(HF_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32));
|
||||||
return;
|
hf_sbc_decode_pcm_data = osi_calloc(HF_SBC_DEC_PCM_DATA_LEN * sizeof(OI_INT16));
|
||||||
|
if (!hf_sbc_decoder_context_ptr || !hf_sbc_decoder_context_data || !hf_sbc_decode_pcm_data) {
|
||||||
|
APPL_TRACE_ERROR("%s failed to allocate SBC decoder", __FUNCTION__);
|
||||||
|
goto error_exit;
|
||||||
}
|
}
|
||||||
memset((void *)bta_hf_ct_plc_ptr, 0, sizeof(bta_hf_ct_plc_t));
|
|
||||||
|
hf_sbc_encoder_ptr = osi_calloc(sizeof(SBC_ENC_PARAMS));
|
||||||
|
|
||||||
|
if (!hf_sbc_encoder_ptr) {
|
||||||
|
APPL_TRACE_ERROR("%s failed to allocate SBC encoder", __FUNCTION__);
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (PLC_INCLUDED == TRUE)
|
||||||
|
bta_hf_ct_plc_ptr = (bta_hf_ct_plc_t *)osi_calloc(sizeof(bta_hf_ct_plc_t));
|
||||||
|
if (!bta_hf_ct_plc_ptr) {
|
||||||
|
APPL_TRACE_ERROR("%s malloc fail.", __FUNCTION__);
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
#endif ///(PLC_INCLUDED == TRUE)
|
||||||
|
|
||||||
#endif /// (HFP_DYNAMIC_MEMORY == TRUE)
|
#endif /// (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
|
|
||||||
sbc_plc_init(&(bta_hf_ct_plc.plc_state));
|
bta_hf_dec_init();
|
||||||
|
bta_hf_enc_init();
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
error_exit:;
|
||||||
|
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
|
if (hf_sbc_decoder_context_ptr) {
|
||||||
|
osi_free(hf_sbc_decoder_context_ptr);
|
||||||
|
hf_sbc_decoder_context_ptr = NULL;
|
||||||
|
}
|
||||||
|
if (hf_sbc_decoder_context_data) {
|
||||||
|
osi_free(hf_sbc_decoder_context_data);
|
||||||
|
hf_sbc_decoder_context_data = NULL;
|
||||||
|
}
|
||||||
|
if (hf_sbc_decode_pcm_data) {
|
||||||
|
osi_free(hf_sbc_decode_pcm_data);
|
||||||
|
hf_sbc_decode_pcm_data = NULL;
|
||||||
|
}
|
||||||
|
if (hf_sbc_encoder_ptr) {
|
||||||
|
osi_free(hf_sbc_encoder_ptr);
|
||||||
|
hf_sbc_encoder_ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (PLC_INCLUDED == TRUE)
|
||||||
|
if (bta_hf_ct_plc_ptr) {
|
||||||
|
osi_free(bta_hf_ct_plc_ptr);
|
||||||
|
bta_hf_ct_plc_ptr = NULL;
|
||||||
|
}
|
||||||
#endif ///(PLC_INCLUDED == TRUE)
|
#endif ///(PLC_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
#endif /// (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
|
} else {
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -133,14 +266,66 @@ void bta_hf_client_sco_co_close(void)
|
|||||||
{
|
{
|
||||||
APPL_TRACE_EVENT("%s", __FUNCTION__);
|
APPL_TRACE_EVENT("%s", __FUNCTION__);
|
||||||
|
|
||||||
|
if (hf_air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
|
||||||
#if (PLC_INCLUDED == TRUE)
|
#if (PLC_INCLUDED == TRUE)
|
||||||
sbc_plc_deinit(&(bta_hf_ct_plc.plc_state));
|
sbc_plc_deinit(&(bta_hf_ct_plc.plc_state));
|
||||||
|
bta_hf_ct_plc.first_good_frame_found = FALSE;
|
||||||
|
|
||||||
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
osi_free(bta_hf_ct_plc_ptr);
|
osi_free(bta_hf_ct_plc_ptr);
|
||||||
#endif /// (HFP_DYNAMIC_MEMORY == TRUE)
|
#endif /// (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
|
|
||||||
#endif ///(PLC_INCLUDED == TRUE)
|
#endif ///(PLC_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
#if (HFP_DYNAMIC_MEMORY == TRUE)
|
||||||
|
osi_free(hf_sbc_decoder_context_ptr);
|
||||||
|
hf_sbc_decoder_context_ptr = NULL;
|
||||||
|
|
||||||
|
osi_free(hf_sbc_decoder_context_data);
|
||||||
|
hf_sbc_decoder_context_data = NULL;
|
||||||
|
|
||||||
|
osi_free(hf_sbc_decode_pcm_data);
|
||||||
|
hf_sbc_decode_pcm_data = NULL;
|
||||||
|
|
||||||
|
osi_free(hf_sbc_encoder_ptr);
|
||||||
|
hf_sbc_encoder_ptr = NULL;
|
||||||
|
#endif /* HFP_DYNAMIC_MEMORY == TRUE */
|
||||||
|
} else {
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_hf_client_h2_header
|
||||||
|
**
|
||||||
|
** Description This function is called to fill in H2 header
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_hf_client_h2_header(UINT16 *p_buf)
|
||||||
|
{
|
||||||
|
// H2: Header with synchronization word and sequence number
|
||||||
|
#define BTA_HF_H2_HEADER 0x0801
|
||||||
|
#define BTA_HF_H2_HEADER_BIT0_MASK (1 << 0)
|
||||||
|
#define BTA_HF_H2_HEADER_BIT1_MASK (1 << 1)
|
||||||
|
#define BTA_HF_H2_HEADER_SN0_BIT_OFFSET1 12
|
||||||
|
#define BTA_HF_H2_HEADER_SN0_BIT_OFFSET2 13
|
||||||
|
#define BTA_HF_H2_HEADER_SN1_BIT_OFFSET1 14
|
||||||
|
#define BTA_HF_H2_HEADER_SN1_BIT_OFFSET2 15
|
||||||
|
|
||||||
|
UINT16 h2_header = BTA_HF_H2_HEADER;
|
||||||
|
UINT8 h2_header_sn0 = hf_sequence_number & BTA_HF_H2_HEADER_BIT0_MASK;
|
||||||
|
UINT8 h2_header_sn1 = hf_sequence_number & BTA_HF_H2_HEADER_BIT1_MASK;
|
||||||
|
h2_header |= (h2_header_sn0 << BTA_HF_H2_HEADER_SN0_BIT_OFFSET1
|
||||||
|
| h2_header_sn0 << BTA_HF_H2_HEADER_SN0_BIT_OFFSET2
|
||||||
|
| h2_header_sn1 << (BTA_HF_H2_HEADER_SN1_BIT_OFFSET1 - 1)
|
||||||
|
| h2_header_sn1 << (BTA_HF_H2_HEADER_SN1_BIT_OFFSET2 - 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
hf_sequence_number++;
|
||||||
|
*p_buf = h2_header;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -152,9 +337,101 @@ void bta_hf_client_sco_co_close(void)
|
|||||||
** Returns number of bytes got from application
|
** Returns number of bytes got from application
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
uint32_t bta_hf_client_sco_co_out_data(uint8_t *p_buf, uint32_t sz)
|
uint32_t bta_hf_client_sco_co_out_data(UINT8 *p_buf)
|
||||||
{
|
{
|
||||||
return btc_hf_client_outgoing_data_cb_to_app(p_buf, sz);
|
if (hf_air_mode == BTM_SCO_AIR_MODE_CVSD) {
|
||||||
|
// CVSD
|
||||||
|
return btc_hf_client_outgoing_data_cb_to_app(p_buf, hf_pkt_size);
|
||||||
|
} else if (hf_air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
|
||||||
|
// mSBC
|
||||||
|
UINT32 size = btc_hf_client_outgoing_data_cb_to_app((UINT8 *)hf_sbc_encoder.as16PcmBuffer, HF_SBC_ENC_PCM_DATA_LEN);
|
||||||
|
if (size != HF_SBC_ENC_PCM_DATA_LEN){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bta_hf_client_h2_header((UINT16 *)p_buf);
|
||||||
|
hf_sbc_encoder.pu8Packet = p_buf + 2;
|
||||||
|
|
||||||
|
SBC_Encoder(&hf_sbc_encoder);
|
||||||
|
if (hf_sbc_encoder.u16PacketLength == BTM_ESCO_DATA_SIZE) {
|
||||||
|
return BTM_ESCO_DATA_SIZE_MAX;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, hf_air_mode);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
** Function bta_hf_client_decode_msbc_frame
|
||||||
|
**
|
||||||
|
** Description This function is called decode a mSBC frame
|
||||||
|
**
|
||||||
|
** Returns void
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
static void bta_hf_client_decode_msbc_frame(UINT8 **data, UINT8 *length, BOOLEAN is_bad_frame){
|
||||||
|
OI_STATUS status;
|
||||||
|
const OI_BYTE *zero_signal_frame_data;
|
||||||
|
UINT8 zero_signal_frame_len = BTM_ESCO_DATA_SIZE;
|
||||||
|
UINT32 sbc_frame_len = HF_SBC_DEC_PCM_DATA_LEN;
|
||||||
|
|
||||||
|
if (is_bad_frame){
|
||||||
|
status = OI_CODEC_SBC_CHECKSUM_MISMATCH;
|
||||||
|
} else {
|
||||||
|
status = OI_CODEC_SBC_DecodeFrame(&hf_sbc_decoder_context, (const OI_BYTE **)data,
|
||||||
|
(OI_UINT32 *)length,
|
||||||
|
(OI_INT16 *)hf_sbc_decode_pcm_data,
|
||||||
|
(OI_UINT32 *)&sbc_frame_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PLC_INCLUDED will be set to TRUE when enabling Wide Band Speech
|
||||||
|
#if (PLC_INCLUDED == TRUE)
|
||||||
|
switch(status){
|
||||||
|
case OI_OK:
|
||||||
|
bta_hf_ct_plc.first_good_frame_found = TRUE;
|
||||||
|
sbc_plc_good_frame(&(bta_hf_ct_plc.plc_state), (int16_t *)hf_sbc_decode_pcm_data, bta_hf_ct_plc.sbc_plc_out);
|
||||||
|
case OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA:
|
||||||
|
case OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA:
|
||||||
|
case OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA:
|
||||||
|
break;
|
||||||
|
case OI_CODEC_SBC_NO_SYNCWORD:
|
||||||
|
case OI_CODEC_SBC_CHECKSUM_MISMATCH:
|
||||||
|
if (!bta_hf_ct_plc.first_good_frame_found) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
zero_signal_frame_data = sbc_plc_zero_signal_frame();
|
||||||
|
sbc_frame_len = HF_SBC_DEC_PCM_DATA_LEN;
|
||||||
|
status = OI_CODEC_SBC_DecodeFrame(&hf_sbc_decoder_context, &zero_signal_frame_data,
|
||||||
|
(OI_UINT32 *)&zero_signal_frame_len,
|
||||||
|
(OI_INT16 *)hf_sbc_decode_pcm_data,
|
||||||
|
(OI_UINT32 *)&sbc_frame_len);
|
||||||
|
|
||||||
|
sbc_plc_bad_frame(&(bta_hf_ct_plc.plc_state), hf_sbc_decode_pcm_data, bta_hf_ct_plc.sbc_plc_out);
|
||||||
|
break;
|
||||||
|
case OI_STATUS_INVALID_PARAMETERS:
|
||||||
|
// This caused by corrupt frames.
|
||||||
|
// The codec apparently does not recover from this.
|
||||||
|
// Re-initialize the codec.
|
||||||
|
APPL_TRACE_ERROR("Frame decode error: OI_STATUS_INVALID_PARAMETERS");
|
||||||
|
|
||||||
|
if (!OI_SUCCESS(OI_CODEC_SBC_DecoderReset(&hf_sbc_decoder_context, hf_sbc_decoder_context_data,
|
||||||
|
HF_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 1, 1, FALSE, TRUE))) {
|
||||||
|
APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
APPL_TRACE_ERROR("Frame decode error: %d", status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif ///(PLC_INCLUDED == TRUE)
|
||||||
|
|
||||||
|
if (OI_SUCCESS(status)){
|
||||||
|
btc_hf_client_incoming_data_cb_to_app((const uint8_t *)(bta_hf_ct_plc.sbc_plc_out), sbc_frame_len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -170,14 +447,36 @@ void bta_hf_client_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
|
|||||||
{
|
{
|
||||||
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||||
UINT8 pkt_size = 0;
|
UINT8 pkt_size = 0;
|
||||||
|
UINT16 handle, sco_index;
|
||||||
|
|
||||||
STREAM_SKIP_UINT16(p);
|
STREAM_TO_UINT16 (handle, p);
|
||||||
STREAM_TO_UINT8 (pkt_size, p);
|
STREAM_TO_UINT8 (pkt_size, p);
|
||||||
|
|
||||||
|
handle = BTMD_GET_HANDLE (handle);
|
||||||
|
sco_index = btm_find_scb_by_handle(handle);
|
||||||
|
tSCO_CONN *sco_p = &btm_cb.sco_cb.sco_db[sco_index];
|
||||||
|
|
||||||
|
if (sco_p->esco.data.air_mode == BTM_SCO_AIR_MODE_CVSD) {
|
||||||
|
// CVSD
|
||||||
if(status != BTM_SCO_DATA_CORRECT){
|
if(status != BTM_SCO_DATA_CORRECT){
|
||||||
APPL_TRACE_DEBUG("%s: not a correct frame(%d).", __func__, status);
|
APPL_TRACE_DEBUG("%s: not a correct frame(%d).", __func__, status);
|
||||||
}
|
}
|
||||||
btc_hf_client_incoming_data_cb_to_app(p, pkt_size);
|
btc_hf_client_incoming_data_cb_to_app(p, pkt_size);
|
||||||
|
} else if (sco_p->esco.data.air_mode == BTM_SCO_AIR_MODE_TRANSPNT) {
|
||||||
|
// mSBC
|
||||||
|
BOOLEAN is_bad_frame = false;
|
||||||
|
UINT8 msbc_frame_size = BTM_ESCO_DATA_SIZE;
|
||||||
|
if (pkt_size < msbc_frame_size) {
|
||||||
|
is_bad_frame = true;
|
||||||
|
}
|
||||||
|
if (status != BTM_SCO_DATA_CORRECT) {
|
||||||
|
is_bad_frame = true;
|
||||||
|
}
|
||||||
|
UINT8 *data = p;
|
||||||
|
bta_hf_client_decode_msbc_frame(&data, &pkt_size, is_bad_frame);
|
||||||
|
} else {
|
||||||
|
APPL_TRACE_ERROR("%s invaild air mode: %d", __FUNCTION__, sco_p->esco.data.air_mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */
|
#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */
|
||||||
|
@ -87,6 +87,12 @@
|
|||||||
#ifndef BTM_MAX_SCO_LINKS
|
#ifndef BTM_MAX_SCO_LINKS
|
||||||
#define BTM_MAX_SCO_LINKS (1)
|
#define BTM_MAX_SCO_LINKS (1)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef SBC_DEC_INCLUDED
|
||||||
|
#define SBC_DEC_INCLUDED TRUE
|
||||||
|
#endif
|
||||||
|
#ifndef SBC_ENC_INCLUDED
|
||||||
|
#define SBC_ENC_INCLUDED TRUE
|
||||||
|
#endif
|
||||||
#endif /* CONFIG_HFP_HF_ENABLE */
|
#endif /* CONFIG_HFP_HF_ENABLE */
|
||||||
|
|
||||||
#if CONFIG_BT_SSP_ENABLED
|
#if CONFIG_BT_SSP_ENABLED
|
||||||
@ -610,6 +616,16 @@
|
|||||||
#define BTM_SCO_DATA_SIZE_MAX 120 //240
|
#define BTM_SCO_DATA_SIZE_MAX 120 //240
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* max TX eSCO data packet size */
|
||||||
|
#ifndef BTM_ESCO_DATA_SIZE_MAX
|
||||||
|
#define BTM_ESCO_DATA_SIZE_MAX 60
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* TX eSCO data packet size */
|
||||||
|
#ifndef BTM_ESCO_DATA_SIZE
|
||||||
|
#define BTM_ESCO_DATA_SIZE 57
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The size in bytes of the BTM inquiry database. 5 As Default */
|
/* The size in bytes of the BTM inquiry database. 5 As Default */
|
||||||
#ifndef BTM_INQ_DB_SIZE
|
#ifndef BTM_INQ_DB_SIZE
|
||||||
#define BTM_INQ_DB_SIZE 5
|
#define BTM_INQ_DB_SIZE 5
|
||||||
|
@ -78,6 +78,9 @@ Declarations of codec functions, data types, and macros.
|
|||||||
#define OI_SBC_ENHANCED_SYNCWORD 0x9d
|
#define OI_SBC_ENHANCED_SYNCWORD 0x9d
|
||||||
#define OI_mSBC_SYNCWORD 0xad
|
#define OI_mSBC_SYNCWORD 0xad
|
||||||
|
|
||||||
|
#define OI_SBC_MODE_STD 0
|
||||||
|
#define OI_SBC_MODE_MSBC 1
|
||||||
|
|
||||||
/**@name Sampling frequencies */
|
/**@name Sampling frequencies */
|
||||||
/**@{*/
|
/**@{*/
|
||||||
#define SBC_FREQ_16000 0 /**< The sampling frequency is 16 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
|
#define SBC_FREQ_16000 0 /**< The sampling frequency is 16 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
|
||||||
@ -200,6 +203,7 @@ typedef struct {
|
|||||||
OI_UINT8 restrictSubbands;
|
OI_UINT8 restrictSubbands;
|
||||||
OI_UINT8 enhancedEnabled;
|
OI_UINT8 enhancedEnabled;
|
||||||
OI_UINT8 bufferedBlocks;
|
OI_UINT8 bufferedBlocks;
|
||||||
|
OI_UINT8 sbc_mode; /* OI_SBC_MODE_STD or OI_SBC_MODE_MSBC */
|
||||||
} OI_CODEC_SBC_DECODER_CONTEXT;
|
} OI_CODEC_SBC_DECODER_CONTEXT;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -236,7 +240,8 @@ OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
|
|||||||
OI_UINT32 decoderDataBytes,
|
OI_UINT32 decoderDataBytes,
|
||||||
OI_UINT8 maxChannels,
|
OI_UINT8 maxChannels,
|
||||||
OI_UINT8 pcmStride,
|
OI_UINT8 pcmStride,
|
||||||
OI_BOOL enhanced);
|
OI_BOOL enhanced,
|
||||||
|
OI_BOOL msbc_enable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function restricts the kind of SBC frames that the Decoder will
|
* This function restricts the kind of SBC frames that the Decoder will
|
||||||
|
@ -170,7 +170,8 @@ INLINE OI_STATUS internal_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
|
|||||||
OI_UINT32 decoderDataBytes,
|
OI_UINT32 decoderDataBytes,
|
||||||
OI_BYTE maxChannels,
|
OI_BYTE maxChannels,
|
||||||
OI_BYTE pcmStride,
|
OI_BYTE pcmStride,
|
||||||
OI_BOOL enhanced);
|
OI_BOOL enhanced,
|
||||||
|
OI_BOOL msbc_enable);
|
||||||
|
|
||||||
INLINE OI_UINT16 OI_SBC_CalculateFrameAndHeaderlen(OI_CODEC_SBC_FRAME_INFO *frame, OI_UINT *headerLen_);
|
INLINE OI_UINT16 OI_SBC_CalculateFrameAndHeaderlen(OI_CODEC_SBC_FRAME_INFO *frame, OI_UINT *headerLen_);
|
||||||
|
|
||||||
|
@ -47,7 +47,8 @@ INLINE OI_STATUS internal_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
|
|||||||
OI_UINT32 decoderDataBytes,
|
OI_UINT32 decoderDataBytes,
|
||||||
OI_BYTE maxChannels,
|
OI_BYTE maxChannels,
|
||||||
OI_BYTE pcmStride,
|
OI_BYTE pcmStride,
|
||||||
OI_BOOL enhanced)
|
OI_BOOL enhanced,
|
||||||
|
OI_BOOL msbc_enable)
|
||||||
{
|
{
|
||||||
OI_UINT i;
|
OI_UINT i;
|
||||||
OI_STATUS status;
|
OI_STATUS status;
|
||||||
@ -65,6 +66,12 @@ INLINE OI_STATUS internal_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (msbc_enable) {
|
||||||
|
context->sbc_mode = OI_SBC_MODE_MSBC;
|
||||||
|
} else {
|
||||||
|
context->sbc_mode = OI_SBC_MODE_STD;
|
||||||
|
}
|
||||||
|
|
||||||
status = OI_CODEC_SBC_Alloc(&context->common, decoderData, decoderDataBytes, maxChannels, pcmStride);
|
status = OI_CODEC_SBC_Alloc(&context->common, decoderData, decoderDataBytes, maxChannels, pcmStride);
|
||||||
|
|
||||||
if (!OI_SUCCESS(status)) {
|
if (!OI_SUCCESS(status)) {
|
||||||
|
@ -79,9 +79,9 @@ PRIVATE OI_STATUS FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT *context,
|
|||||||
return OI_CODEC_SBC_NO_SYNCWORD;
|
return OI_CODEC_SBC_NO_SYNCWORD;
|
||||||
}
|
}
|
||||||
#else // SBC_ENHANCED
|
#else // SBC_ENHANCED
|
||||||
|
while (*frameBytes
|
||||||
while (*frameBytes && (**frameData != OI_SBC_SYNCWORD)
|
&& (!(context->sbc_mode == OI_SBC_MODE_STD && **frameData == OI_SBC_SYNCWORD))
|
||||||
&& (**frameData != OI_mSBC_SYNCWORD)) {
|
&& (!(context->sbc_mode == OI_SBC_MODE_MSBC && **frameData == OI_mSBC_SYNCWORD))) {
|
||||||
(*frameBytes)--;
|
(*frameBytes)--;
|
||||||
(*frameData)++;
|
(*frameData)++;
|
||||||
}
|
}
|
||||||
@ -230,9 +230,10 @@ OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
|
|||||||
OI_UINT32 decoderDataBytes,
|
OI_UINT32 decoderDataBytes,
|
||||||
OI_UINT8 maxChannels,
|
OI_UINT8 maxChannels,
|
||||||
OI_UINT8 pcmStride,
|
OI_UINT8 pcmStride,
|
||||||
OI_BOOL enhanced)
|
OI_BOOL enhanced,
|
||||||
|
OI_BOOL msbc_enable)
|
||||||
{
|
{
|
||||||
return internal_DecoderReset(context, decoderData, decoderDataBytes, maxChannels, pcmStride, enhanced);
|
return internal_DecoderReset(context, decoderData, decoderDataBytes, maxChannels, pcmStride, enhanced, msbc_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
|
OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
|
||||||
|
@ -50,21 +50,25 @@ static float rcos[SBC_OLAL] = {
|
|||||||
// 0.96984631f,0.88302222f, 0.75f,0.58682409f,
|
// 0.96984631f,0.88302222f, 0.75f,0.58682409f,
|
||||||
// 0.41317591f, 0.25f,0.11697778f,0.09015369f};
|
// 0.41317591f, 0.25f,0.11697778f,0.09015369f};
|
||||||
|
|
||||||
|
|
||||||
static float SqrtByCarmack(const float x){
|
static float SqrtByCarmack(const float x){
|
||||||
|
union {
|
||||||
int i;
|
int i;
|
||||||
float x2, y;
|
float y;
|
||||||
|
} float_int;
|
||||||
|
|
||||||
|
float x2;
|
||||||
const float threehalfs = 1.5f;
|
const float threehalfs = 1.5f;
|
||||||
|
|
||||||
x2 = x * 0.5f;
|
x2 = x * 0.5f;
|
||||||
y = x;
|
float_int.y = x;
|
||||||
i = *(int *)&y;
|
|
||||||
i = 0x5f375a86 - (i >> 1);
|
|
||||||
y = *(float *)&i;
|
|
||||||
y = y * (threehalfs - (x2 * y *y));
|
|
||||||
// y = y * (threehalfs - (x2 * y *y));
|
|
||||||
// y = y * (threehalfs - (x2 * y *y));
|
|
||||||
|
|
||||||
return (x * y);
|
float_int.i = 0x5f375a86 - (float_int.i >> 1);
|
||||||
|
float_int.y = float_int.y * (threehalfs - (x2 * float_int.y * float_int.y));
|
||||||
|
// float_int.y = float_int.y * (threehalfs - (x2 * float_int.y * float_int.y));
|
||||||
|
// float_int.y = float_int.y * (threehalfs - (x2 * float_int.y * float_int.y));
|
||||||
|
|
||||||
|
return (x * float_int.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float absolute(float x){
|
static float absolute(float x){
|
||||||
|
@ -320,6 +320,10 @@ typedef UINT8 *BTM_BD_NAME_PTR; /* Pointer to Device name
|
|||||||
*/
|
*/
|
||||||
typedef tBTM_SEC_CBACK tBTM_SEC_CALLBACK;
|
typedef tBTM_SEC_CBACK tBTM_SEC_CALLBACK;
|
||||||
|
|
||||||
|
#define BTM_DATA_HANDLE_MASK 0x0FFF
|
||||||
|
|
||||||
|
#define BTMD_GET_HANDLE(u16) (UINT16)((u16) & BTM_DATA_HANDLE_MASK)
|
||||||
|
|
||||||
typedef void (tBTM_SCO_IND_CBACK) (UINT16 sco_inx) ;
|
typedef void (tBTM_SCO_IND_CBACK) (UINT16 sco_inx) ;
|
||||||
|
|
||||||
/* MACROs to convert from SCO packet types mask to ESCO and back */
|
/* MACROs to convert from SCO packet types mask to ESCO and back */
|
||||||
|
@ -992,7 +992,7 @@ typedef UINT8 tBTM_SCO_AIR_MODE_TYPE;
|
|||||||
|
|
||||||
#define BTM_VOICE_SETTING_TRANS ((UINT16) (HCI_INP_CODING_LINEAR | \
|
#define BTM_VOICE_SETTING_TRANS ((UINT16) (HCI_INP_CODING_LINEAR | \
|
||||||
HCI_INP_DATA_FMT_2S_COMPLEMENT | \
|
HCI_INP_DATA_FMT_2S_COMPLEMENT | \
|
||||||
HCI_INP_SAMPLE_SIZE_16BIT | \
|
HCI_INP_SAMPLE_SIZE_8BIT | \
|
||||||
HCI_AIR_CODING_FORMAT_TRANSPNT))
|
HCI_AIR_CODING_FORMAT_TRANSPNT))
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
|
Loading…
x
Reference in New Issue
Block a user