|
|
@@ -156,7 +156,6 @@ typedef struct {
|
|
|
tBTC_AV_FEEDING_MODE feeding_mode;
|
|
|
tBTC_AV_MEDIA_FEEDINGS_STATE media_feeding_state;
|
|
|
tBTC_AV_MEDIA_FEEDINGS media_feeding;
|
|
|
- SBC_ENC_PARAMS encoder;
|
|
|
osi_alarm_t *media_alarm;
|
|
|
} tBTC_A2DP_SOURCE_CB;
|
|
|
|
|
|
@@ -187,6 +186,13 @@ static QueueSetHandle_t btc_aa_src_queue_set;
|
|
|
static esp_a2d_source_data_cb_t btc_aa_src_data_cb = NULL;
|
|
|
static UINT64 last_frame_us = 0;
|
|
|
|
|
|
+#if BTC_SBC_ENC_DYNAMIC_MEMORY == FALSE
|
|
|
+static SBC_ENC_PARAMS btc_sbc_encoder;
|
|
|
+#else
|
|
|
+static SBC_ENC_PARAMS *btc_sbc_encoder_ptr;
|
|
|
+#define btc_sbc_encoder (*btc_sbc_encoder_ptr)
|
|
|
+#endif /* BTC_SBC_ENC_DYNAMIC_MEMORY == FALSE */
|
|
|
+
|
|
|
void btc_a2dp_src_reg_data_cb(esp_a2d_source_data_cb_t callback)
|
|
|
{
|
|
|
// todo: critical section protection
|
|
|
@@ -310,6 +316,14 @@ bool btc_a2dp_source_startup(void)
|
|
|
|
|
|
APPL_TRACE_EVENT("## A2DP SOURCE START MEDIA THREAD ##");
|
|
|
|
|
|
+#if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE
|
|
|
+ btc_sbc_encoder_ptr = osi_calloc(sizeof(SBC_ENC_PARAMS));
|
|
|
+ if (!btc_sbc_encoder_ptr) {
|
|
|
+ APPL_TRACE_ERROR("failed to allocate SBC encoder");
|
|
|
+ goto error_exit;
|
|
|
+ }
|
|
|
+#endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */
|
|
|
+
|
|
|
btc_aa_src_queue_set = xQueueCreateSet(BTC_A2DP_SOURCE_TASK_QUEUE_SET_LEN);
|
|
|
configASSERT(btc_aa_src_queue_set);
|
|
|
btc_aa_src_data_queue = xQueueCreate(BTC_A2DP_SOURCE_DATA_QUEUE_LEN, sizeof(void *));
|
|
|
@@ -355,6 +369,12 @@ error_exit:;
|
|
|
vQueueDelete(btc_aa_src_queue_set);
|
|
|
btc_aa_src_queue_set = NULL;
|
|
|
}
|
|
|
+#if (BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE)
|
|
|
+ if (btc_sbc_encoder_ptr) {
|
|
|
+ osi_free(btc_sbc_encoder_ptr);
|
|
|
+ btc_sbc_encoder_ptr = NULL;
|
|
|
+ }
|
|
|
+#endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
@@ -381,6 +401,11 @@ void btc_a2dp_source_shutdown(void)
|
|
|
|
|
|
vQueueDelete(btc_aa_src_queue_set);
|
|
|
btc_aa_src_queue_set = NULL;
|
|
|
+
|
|
|
+#if (BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE)
|
|
|
+ osi_free(btc_sbc_encoder_ptr);
|
|
|
+ btc_sbc_encoder_ptr = NULL;
|
|
|
+#endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
@@ -794,13 +819,14 @@ static void btc_a2dp_source_enc_init(BT_HDR *p_msg)
|
|
|
btc_aa_src_cb.timestamp = 0;
|
|
|
|
|
|
/* SBC encoder config (enforced even if not used) */
|
|
|
- btc_aa_src_cb.encoder.s16ChannelMode = pInitAudio->ChannelMode;
|
|
|
- btc_aa_src_cb.encoder.s16NumOfSubBands = pInitAudio->NumOfSubBands;
|
|
|
- btc_aa_src_cb.encoder.s16NumOfBlocks = pInitAudio->NumOfBlocks;
|
|
|
- btc_aa_src_cb.encoder.s16AllocationMethod = pInitAudio->AllocationMethod;
|
|
|
- btc_aa_src_cb.encoder.s16SamplingFreq = pInitAudio->SamplingFreq;
|
|
|
|
|
|
- btc_aa_src_cb.encoder.u16BitRate = btc_a2dp_source_get_sbc_rate();
|
|
|
+ btc_sbc_encoder.s16ChannelMode = pInitAudio->ChannelMode;
|
|
|
+ btc_sbc_encoder.s16NumOfSubBands = pInitAudio->NumOfSubBands;
|
|
|
+ btc_sbc_encoder.s16NumOfBlocks = pInitAudio->NumOfBlocks;
|
|
|
+ btc_sbc_encoder.s16AllocationMethod = pInitAudio->AllocationMethod;
|
|
|
+ btc_sbc_encoder.s16SamplingFreq = pInitAudio->SamplingFreq;
|
|
|
+
|
|
|
+ btc_sbc_encoder.u16BitRate = btc_a2dp_source_get_sbc_rate();
|
|
|
|
|
|
/* Default transcoding is PCM to SBC, modified by feeding configuration */
|
|
|
btc_aa_src_cb.TxTranscoding = BTC_MEDIA_TRSCD_PCM_2_SBC;
|
|
|
@@ -811,14 +837,14 @@ static void btc_a2dp_source_enc_init(BT_HDR *p_msg)
|
|
|
APPL_TRACE_EVENT("btc_a2dp_source_enc_init mtu %d, peer mtu %d",
|
|
|
btc_aa_src_cb.TxAaMtuSize, pInitAudio->MtuSize);
|
|
|
APPL_TRACE_EVENT(" ch mode %d, subnd %d, nb blk %d, alloc %d, rate %d, freq %d",
|
|
|
- btc_aa_src_cb.encoder.s16ChannelMode, btc_aa_src_cb.encoder.s16NumOfSubBands,
|
|
|
- btc_aa_src_cb.encoder.s16NumOfBlocks,
|
|
|
- btc_aa_src_cb.encoder.s16AllocationMethod, btc_aa_src_cb.encoder.u16BitRate,
|
|
|
- btc_aa_src_cb.encoder.s16SamplingFreq);
|
|
|
+ btc_sbc_encoder.s16ChannelMode, btc_sbc_encoder.s16NumOfSubBands,
|
|
|
+ btc_sbc_encoder.s16NumOfBlocks,
|
|
|
+ btc_sbc_encoder.s16AllocationMethod, btc_sbc_encoder.u16BitRate,
|
|
|
+ btc_sbc_encoder.s16SamplingFreq);
|
|
|
|
|
|
/* Reset entirely the SBC encoder */
|
|
|
- SBC_Encoder_Init(&(btc_aa_src_cb.encoder));
|
|
|
- APPL_TRACE_DEBUG("btc_a2dp_source_enc_init bit pool %d", btc_aa_src_cb.encoder.s16BitPool);
|
|
|
+ SBC_Encoder_Init(&(btc_sbc_encoder));
|
|
|
+ APPL_TRACE_DEBUG("btc_a2dp_source_enc_init bit pool %d", btc_sbc_encoder.s16BitPool);
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -835,7 +861,7 @@ static void btc_a2dp_source_enc_init(BT_HDR *p_msg)
|
|
|
static void btc_a2dp_source_enc_update(BT_HDR *p_msg)
|
|
|
{
|
|
|
tBTC_MEDIA_UPDATE_AUDIO *pUpdateAudio = (tBTC_MEDIA_UPDATE_AUDIO *) p_msg;
|
|
|
- SBC_ENC_PARAMS *pstrEncParams = &btc_aa_src_cb.encoder;
|
|
|
+ SBC_ENC_PARAMS *pstrEncParams = &btc_sbc_encoder;
|
|
|
UINT16 s16SamplingFreq;
|
|
|
SINT16 s16BitPool = 0;
|
|
|
SINT16 s16BitRate;
|
|
|
@@ -928,19 +954,19 @@ static void btc_a2dp_source_enc_update(BT_HDR *p_msg)
|
|
|
if (s16BitPool > pUpdateAudio->MaxBitPool) {
|
|
|
APPL_TRACE_DEBUG("%s computed bitpool too large (%d)", __FUNCTION__, s16BitPool);
|
|
|
/* Decrease bitrate */
|
|
|
- btc_aa_src_cb.encoder.u16BitRate -= BTC_MEDIA_BITRATE_STEP;
|
|
|
+ btc_sbc_encoder.u16BitRate -= BTC_MEDIA_BITRATE_STEP;
|
|
|
/* Record that we have decreased the bitrate */
|
|
|
protect |= 1;
|
|
|
} else if (s16BitPool < pUpdateAudio->MinBitPool) {
|
|
|
APPL_TRACE_WARNING("%s computed bitpool too small (%d)", __FUNCTION__, s16BitPool);
|
|
|
|
|
|
/* Increase bitrate */
|
|
|
- UINT16 previous_u16BitRate = btc_aa_src_cb.encoder.u16BitRate;
|
|
|
- btc_aa_src_cb.encoder.u16BitRate += BTC_MEDIA_BITRATE_STEP;
|
|
|
+ UINT16 previous_u16BitRate = btc_sbc_encoder.u16BitRate;
|
|
|
+ btc_sbc_encoder.u16BitRate += BTC_MEDIA_BITRATE_STEP;
|
|
|
/* Record that we have increased the bitrate */
|
|
|
protect |= 2;
|
|
|
/* Check over-flow */
|
|
|
- if (btc_aa_src_cb.encoder.u16BitRate < previous_u16BitRate) {
|
|
|
+ if (btc_sbc_encoder.u16BitRate < previous_u16BitRate) {
|
|
|
protect |= 3;
|
|
|
}
|
|
|
} else {
|
|
|
@@ -957,10 +983,10 @@ static void btc_a2dp_source_enc_update(BT_HDR *p_msg)
|
|
|
pstrEncParams->s16BitPool = s16BitPool;
|
|
|
|
|
|
APPL_TRACE_DEBUG("%s final bit rate %d, final bit pool %d", __FUNCTION__,
|
|
|
- btc_aa_src_cb.encoder.u16BitRate, btc_aa_src_cb.encoder.s16BitPool);
|
|
|
+ btc_sbc_encoder.u16BitRate, btc_sbc_encoder.s16BitPool);
|
|
|
|
|
|
/* make sure we reinitialize encoder with new settings */
|
|
|
- SBC_Encoder_Init(&(btc_aa_src_cb.encoder));
|
|
|
+ SBC_Encoder_Init(&(btc_sbc_encoder));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -991,10 +1017,10 @@ static void btc_a2dp_source_pcm2sbc_init(tBTC_MEDIA_INIT_AUDIO_FEEDING *p_feedin
|
|
|
case 32000:
|
|
|
case 48000:
|
|
|
/* For these sampling_freq the AV connection must be 48000 */
|
|
|
- if (btc_aa_src_cb.encoder.s16SamplingFreq != SBC_sf48000) {
|
|
|
+ if (btc_sbc_encoder.s16SamplingFreq != SBC_sf48000) {
|
|
|
/* Reconfiguration needed at 48000 */
|
|
|
APPL_TRACE_DEBUG("SBC Reconfiguration needed at 48000");
|
|
|
- btc_aa_src_cb.encoder.s16SamplingFreq = SBC_sf48000;
|
|
|
+ btc_sbc_encoder.s16SamplingFreq = SBC_sf48000;
|
|
|
reconfig_needed = TRUE;
|
|
|
}
|
|
|
break;
|
|
|
@@ -1003,10 +1029,10 @@ static void btc_a2dp_source_pcm2sbc_init(tBTC_MEDIA_INIT_AUDIO_FEEDING *p_feedin
|
|
|
case 22050:
|
|
|
case 44100:
|
|
|
/* For these sampling_freq the AV connection must be 44100 */
|
|
|
- if (btc_aa_src_cb.encoder.s16SamplingFreq != SBC_sf44100) {
|
|
|
+ if (btc_sbc_encoder.s16SamplingFreq != SBC_sf44100) {
|
|
|
/* Reconfiguration needed at 44100 */
|
|
|
APPL_TRACE_DEBUG("SBC Reconfiguration needed at 44100");
|
|
|
- btc_aa_src_cb.encoder.s16SamplingFreq = SBC_sf44100;
|
|
|
+ btc_sbc_encoder.s16SamplingFreq = SBC_sf44100;
|
|
|
reconfig_needed = TRUE;
|
|
|
}
|
|
|
break;
|
|
|
@@ -1016,21 +1042,21 @@ static void btc_a2dp_source_pcm2sbc_init(tBTC_MEDIA_INIT_AUDIO_FEEDING *p_feedin
|
|
|
}
|
|
|
|
|
|
/* Some AV Headsets do not support Mono => always ask for Stereo */
|
|
|
- if (btc_aa_src_cb.encoder.s16ChannelMode == SBC_MONO) {
|
|
|
+ if (btc_sbc_encoder.s16ChannelMode == SBC_MONO) {
|
|
|
APPL_TRACE_DEBUG("SBC Reconfiguration needed in Stereo");
|
|
|
- btc_aa_src_cb.encoder.s16ChannelMode = SBC_JOINT_STEREO;
|
|
|
+ btc_sbc_encoder.s16ChannelMode = SBC_JOINT_STEREO;
|
|
|
reconfig_needed = TRUE;
|
|
|
}
|
|
|
|
|
|
if (reconfig_needed != FALSE) {
|
|
|
APPL_TRACE_DEBUG("%s :: mtu %d", __FUNCTION__, btc_aa_src_cb.TxAaMtuSize);
|
|
|
APPL_TRACE_DEBUG("ch mode %d, nbsubd %d, nb %d, alloc %d, rate %d, freq %d",
|
|
|
- btc_aa_src_cb.encoder.s16ChannelMode,
|
|
|
- btc_aa_src_cb.encoder.s16NumOfSubBands, btc_aa_src_cb.encoder.s16NumOfBlocks,
|
|
|
- btc_aa_src_cb.encoder.s16AllocationMethod, btc_aa_src_cb.encoder.u16BitRate,
|
|
|
- btc_aa_src_cb.encoder.s16SamplingFreq);
|
|
|
+ btc_sbc_encoder.s16ChannelMode,
|
|
|
+ btc_sbc_encoder.s16NumOfSubBands, btc_sbc_encoder.s16NumOfBlocks,
|
|
|
+ btc_sbc_encoder.s16AllocationMethod, btc_sbc_encoder.u16BitRate,
|
|
|
+ btc_sbc_encoder.s16SamplingFreq);
|
|
|
|
|
|
- SBC_Encoder_Init(&(btc_aa_src_cb.encoder));
|
|
|
+ SBC_Encoder_Init(&(btc_sbc_encoder));
|
|
|
} else {
|
|
|
APPL_TRACE_DEBUG("%s no SBC reconfig needed", __FUNCTION__);
|
|
|
}
|
|
|
@@ -1105,8 +1131,8 @@ static UINT8 btc_get_num_aa_frame(void)
|
|
|
|
|
|
switch (btc_aa_src_cb.TxTranscoding) {
|
|
|
case BTC_MEDIA_TRSCD_PCM_2_SBC: {
|
|
|
- UINT32 pcm_bytes_per_frame = btc_aa_src_cb.encoder.s16NumOfSubBands *
|
|
|
- btc_aa_src_cb.encoder.s16NumOfBlocks *
|
|
|
+ UINT32 pcm_bytes_per_frame = btc_sbc_encoder.s16NumOfSubBands *
|
|
|
+ btc_sbc_encoder.s16NumOfBlocks *
|
|
|
btc_aa_src_cb.media_feeding.cfg.pcm.num_channel *
|
|
|
btc_aa_src_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
|
|
|
|
|
|
@@ -1162,12 +1188,12 @@ static UINT8 btc_get_num_aa_frame(void)
|
|
|
|
|
|
BOOLEAN btc_media_aa_read_feeding(void)
|
|
|
{
|
|
|
- UINT16 blocm_x_subband = btc_aa_src_cb.encoder.s16NumOfSubBands * \
|
|
|
- btc_aa_src_cb.encoder.s16NumOfBlocks;
|
|
|
+ UINT16 blocm_x_subband = btc_sbc_encoder.s16NumOfSubBands * \
|
|
|
+ btc_sbc_encoder.s16NumOfBlocks;
|
|
|
UINT32 read_size;
|
|
|
UINT16 sbc_sampling = 48000;
|
|
|
UINT32 src_samples;
|
|
|
- UINT16 bytes_needed = blocm_x_subband * btc_aa_src_cb.encoder.s16NumOfChannels * \
|
|
|
+ UINT16 bytes_needed = blocm_x_subband * btc_sbc_encoder.s16NumOfChannels * \
|
|
|
btc_aa_src_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
|
|
|
static UINT16 up_sampled_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
|
|
|
* SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * 2];
|
|
|
@@ -1181,7 +1207,7 @@ BOOLEAN btc_media_aa_read_feeding(void)
|
|
|
UINT32 nb_byte_read = 0;
|
|
|
|
|
|
/* Get the SBC sampling rate */
|
|
|
- switch (btc_aa_src_cb.encoder.s16SamplingFreq) {
|
|
|
+ switch (btc_sbc_encoder.s16SamplingFreq) {
|
|
|
case SBC_sf48000:
|
|
|
sbc_sampling = 48000;
|
|
|
break;
|
|
|
@@ -1199,7 +1225,7 @@ BOOLEAN btc_media_aa_read_feeding(void)
|
|
|
if (sbc_sampling == btc_aa_src_cb.media_feeding.cfg.pcm.sampling_freq) {
|
|
|
read_size = bytes_needed - btc_aa_src_cb.media_feeding_state.pcm.aa_feed_residue;
|
|
|
nb_byte_read = btc_aa_src_data_read(
|
|
|
- ((uint8_t *)btc_aa_src_cb.encoder.as16PcmBuffer) +
|
|
|
+ ((uint8_t *)btc_sbc_encoder.as16PcmBuffer) +
|
|
|
btc_aa_src_cb.media_feeding_state.pcm.aa_feed_residue,
|
|
|
read_size);
|
|
|
if (nb_byte_read == read_size) {
|
|
|
@@ -1293,7 +1319,7 @@ BOOLEAN btc_media_aa_read_feeding(void)
|
|
|
/* only copy the pcm sample when we have up-sampled enough PCM */
|
|
|
if (btc_aa_src_cb.media_feeding_state.pcm.aa_feed_residue >= bytes_needed) {
|
|
|
/* Copy the output pcm samples in SBC encoding buffer */
|
|
|
- memcpy((UINT8 *)btc_aa_src_cb.encoder.as16PcmBuffer,
|
|
|
+ memcpy((UINT8 *)btc_sbc_encoder.as16PcmBuffer,
|
|
|
(UINT8 *)up_sampled_buffer,
|
|
|
bytes_needed);
|
|
|
/* update the residue */
|
|
|
@@ -1322,8 +1348,8 @@ BOOLEAN btc_media_aa_read_feeding(void)
|
|
|
static void btc_media_aa_prep_sbc_2_send(UINT8 nb_frame)
|
|
|
{
|
|
|
BT_HDR *p_buf;
|
|
|
- UINT16 blocm_x_subband = btc_aa_src_cb.encoder.s16NumOfSubBands *
|
|
|
- btc_aa_src_cb.encoder.s16NumOfBlocks;
|
|
|
+ UINT16 blocm_x_subband = btc_sbc_encoder.s16NumOfSubBands *
|
|
|
+ btc_sbc_encoder.s16NumOfBlocks;
|
|
|
|
|
|
while (nb_frame) {
|
|
|
if (NULL == (p_buf = osi_malloc(BTC_MEDIA_AA_BUF_SIZE))) {
|
|
|
@@ -1339,27 +1365,27 @@ static void btc_media_aa_prep_sbc_2_send(UINT8 nb_frame)
|
|
|
|
|
|
do {
|
|
|
/* Write @ of allocated buffer in encoder.pu8Packet */
|
|
|
- btc_aa_src_cb.encoder.pu8Packet = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len;
|
|
|
+ btc_sbc_encoder.pu8Packet = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len;
|
|
|
/* Fill allocated buffer with 0 */
|
|
|
- memset(btc_aa_src_cb.encoder.as16PcmBuffer, 0, blocm_x_subband
|
|
|
- * btc_aa_src_cb.encoder.s16NumOfChannels);
|
|
|
+ memset(btc_sbc_encoder.as16PcmBuffer, 0, blocm_x_subband
|
|
|
+ * btc_sbc_encoder.s16NumOfChannels);
|
|
|
|
|
|
/* Read PCM data and upsample them if needed */
|
|
|
if (btc_media_aa_read_feeding()) {
|
|
|
/* SBC encode and descramble frame */
|
|
|
- SBC_Encoder(&(btc_aa_src_cb.encoder));
|
|
|
- A2D_SbcChkFrInit(btc_aa_src_cb.encoder.pu8Packet);
|
|
|
- A2D_SbcDescramble(btc_aa_src_cb.encoder.pu8Packet, btc_aa_src_cb.encoder.u16PacketLength);
|
|
|
+ SBC_Encoder(&(btc_sbc_encoder));
|
|
|
+ A2D_SbcChkFrInit(btc_sbc_encoder.pu8Packet);
|
|
|
+ A2D_SbcDescramble(btc_sbc_encoder.pu8Packet, btc_sbc_encoder.u16PacketLength);
|
|
|
/* Update SBC frame length */
|
|
|
- p_buf->len += btc_aa_src_cb.encoder.u16PacketLength;
|
|
|
+ p_buf->len += btc_sbc_encoder.u16PacketLength;
|
|
|
nb_frame--;
|
|
|
p_buf->layer_specific++;
|
|
|
} else {
|
|
|
APPL_TRACE_WARNING("btc_media_aa_prep_sbc_2_send underflow %d, %d",
|
|
|
nb_frame, btc_aa_src_cb.media_feeding_state.pcm.aa_feed_residue);
|
|
|
btc_aa_src_cb.media_feeding_state.pcm.counter += nb_frame *
|
|
|
- btc_aa_src_cb.encoder.s16NumOfSubBands *
|
|
|
- btc_aa_src_cb.encoder.s16NumOfBlocks *
|
|
|
+ btc_sbc_encoder.s16NumOfSubBands *
|
|
|
+ btc_sbc_encoder.s16NumOfBlocks *
|
|
|
btc_aa_src_cb.media_feeding.cfg.pcm.num_channel *
|
|
|
btc_aa_src_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
|
|
|
/* no more pcm to read */
|
|
|
@@ -1372,7 +1398,7 @@ static void btc_media_aa_prep_sbc_2_send(UINT8 nb_frame)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- } while (((p_buf->len + btc_aa_src_cb.encoder.u16PacketLength) < btc_aa_src_cb.TxAaMtuSize)
|
|
|
+ } while (((p_buf->len + btc_sbc_encoder.u16PacketLength) < btc_aa_src_cb.TxAaMtuSize)
|
|
|
&& (p_buf->layer_specific < 0x0F) && nb_frame);
|
|
|
|
|
|
if (p_buf->len) {
|