From 7c28611a3dbd650dda0635f4c01fcfaed49cd7ba Mon Sep 17 00:00:00 2001 From: wangmengyang Date: Fri, 25 May 2018 14:23:38 +0800 Subject: [PATCH] component/bt: modify the SBC encoder to support mSBC mode --- .../btc/profile/std/a2dp/btc_a2dp_source.c | 3 +- .../sbc/encoder/include/sbc_encoder.h | 7 + .../external/sbc/encoder/srce/sbc_encoder.c | 171 ++++++++++-------- .../external/sbc/encoder/srce/sbc_packing.c | 13 +- 4 files changed, 117 insertions(+), 77 deletions(-) diff --git a/components/bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c b/components/bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c index c67b9783cf..b734325e30 100644 --- a/components/bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c +++ b/components/bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c @@ -820,7 +820,7 @@ 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_sbc_encoder.sbc_mode = SBC_MODE_STD; btc_sbc_encoder.s16ChannelMode = pInitAudio->ChannelMode; btc_sbc_encoder.s16NumOfSubBands = pInitAudio->NumOfSubBands; btc_sbc_encoder.s16NumOfBlocks = pInitAudio->NumOfBlocks; @@ -879,7 +879,6 @@ static void btc_a2dp_source_enc_update(BT_HDR *p_msg) BTC_MEDIA_AA_SBC_OFFSET - sizeof(BT_HDR)) < pUpdateAudio->MinMtuSize) ? (BTC_MEDIA_AA_BUF_SIZE - BTC_MEDIA_AA_SBC_OFFSET - sizeof(BT_HDR)) : pUpdateAudio->MinMtuSize; - /* Set the initial target bit rate */ pstrEncParams->u16BitRate = btc_a2dp_source_get_sbc_rate(); diff --git a/components/bt/bluedroid/external/sbc/encoder/include/sbc_encoder.h b/components/bt/bluedroid/external/sbc/encoder/include/sbc_encoder.h index 8a507a7d30..b7b807f536 100644 --- a/components/bt/bluedroid/external/sbc/encoder/include/sbc_encoder.h +++ b/components/bt/bluedroid/external/sbc/encoder/include/sbc_encoder.h @@ -67,6 +67,12 @@ #define SBC_NULL 0 +#define SBC_MODE_STD 0 +#define SBC_MODE_MSBC 1 + +#define SBC_SYNC_WORD_STD (0x9C) +#define SBC_SYNC_WORD_MSBC (0xAD) + #ifndef SBC_MAX_NUM_FRAME #define SBC_MAX_NUM_FRAME 1 #endif @@ -161,6 +167,7 @@ typedef struct SBC_ENC_PARAMS_TAG { SINT16 s16BitPool; /* 16*numOfSb for mono & dual; 32*numOfSb for stereo & joint stereo */ UINT16 u16BitRate; + UINT8 sbc_mode; /* SBC_MODE_STD or SBC_MODE_MSBC */ UINT8 u8NumPacketToEncode; /* number of sbc frame to encode. Default is 1 */ #if (SBC_JOINT_STE_INCLUDED == TRUE) SINT16 as16Join[SBC_MAX_NUM_OF_SUBBANDS]; /*1 if JS, 0 otherwise*/ diff --git a/components/bt/bluedroid/external/sbc/encoder/srce/sbc_encoder.c b/components/bt/bluedroid/external/sbc/encoder/srce/sbc_encoder.c index 378111b007..c0ab99b830 100644 --- a/components/bt/bluedroid/external/sbc/encoder/srce/sbc_encoder.c +++ b/components/bt/bluedroid/external/sbc/encoder/srce/sbc_encoder.c @@ -184,7 +184,6 @@ void SBC_Encoder(SBC_ENC_PARAMS *pstrEncParams) /* Quantize the encoded audio */ EncPacking(pstrEncParams); - } while (--(pstrEncParams->u8NumPacketToEncode)); pstrEncParams->u8NumPacketToEncode = 1; /* default is one for retrocompatibility purpose */ @@ -206,83 +205,111 @@ void SBC_Encoder_Init(SBC_ENC_PARAMS *pstrEncParams) pstrEncParams->u8NumPacketToEncode = 1; /* default is one for retrocompatibility purpose */ - /* Required number of channels */ - if (pstrEncParams->s16ChannelMode == SBC_MONO) { - pstrEncParams->s16NumOfChannels = 1; - } else { - pstrEncParams->s16NumOfChannels = 2; - } - - /* Bit pool calculation */ - if (pstrEncParams->s16SamplingFreq == SBC_sf16000) { - s16SamplingFreq = 16000; - } else if (pstrEncParams->s16SamplingFreq == SBC_sf32000) { - s16SamplingFreq = 32000; - } else if (pstrEncParams->s16SamplingFreq == SBC_sf44100) { - s16SamplingFreq = 44100; - } else { - s16SamplingFreq = 48000; - } - - if ( (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) - || (pstrEncParams->s16ChannelMode == SBC_STEREO) ) { - s16Bitpool = (SINT16)( (pstrEncParams->u16BitRate * - pstrEncParams->s16NumOfSubBands * 1000 / s16SamplingFreq) - - ( (32 + (4 * pstrEncParams->s16NumOfSubBands * - pstrEncParams->s16NumOfChannels) - + ( (pstrEncParams->s16ChannelMode - 2) * - pstrEncParams->s16NumOfSubBands ) ) - / pstrEncParams->s16NumOfBlocks) ); - - s16FrameLen = 4 + (4 * pstrEncParams->s16NumOfSubBands * - pstrEncParams->s16NumOfChannels) / 8 - + ( ((pstrEncParams->s16ChannelMode - 2) * - pstrEncParams->s16NumOfSubBands) - + (pstrEncParams->s16NumOfBlocks * s16Bitpool) ) / 8; - - s16BitRate = (8 * s16FrameLen * s16SamplingFreq) - / (pstrEncParams->s16NumOfSubBands * - pstrEncParams->s16NumOfBlocks * 1000); - - if (s16BitRate > pstrEncParams->u16BitRate) { - s16Bitpool--; - } - - if (pstrEncParams->s16NumOfSubBands == 8) { - pstrEncParams->s16BitPool = (s16Bitpool > 255) ? 255 : s16Bitpool; + if (pstrEncParams->sbc_mode != SBC_MODE_MSBC) { + /* Required number of channels */ + if (pstrEncParams->s16ChannelMode == SBC_MONO) { + pstrEncParams->s16NumOfChannels = 1; } else { - pstrEncParams->s16BitPool = (s16Bitpool > 128) ? 128 : s16Bitpool; + pstrEncParams->s16NumOfChannels = 2; } + + /* Bit pool calculation */ + if (pstrEncParams->s16SamplingFreq == SBC_sf16000) { + s16SamplingFreq = 16000; + } else if (pstrEncParams->s16SamplingFreq == SBC_sf32000) { + s16SamplingFreq = 32000; + } else if (pstrEncParams->s16SamplingFreq == SBC_sf44100) { + s16SamplingFreq = 44100; + } else { + s16SamplingFreq = 48000; + } + + if ( (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) + || (pstrEncParams->s16ChannelMode == SBC_STEREO) ) { + s16Bitpool = (SINT16)( (pstrEncParams->u16BitRate * + pstrEncParams->s16NumOfSubBands * 1000 / s16SamplingFreq) + - ( (32 + (4 * pstrEncParams->s16NumOfSubBands * + pstrEncParams->s16NumOfChannels) + + ( (pstrEncParams->s16ChannelMode - 2) * + pstrEncParams->s16NumOfSubBands ) ) + / pstrEncParams->s16NumOfBlocks) ); + + s16FrameLen = 4 + (4 * pstrEncParams->s16NumOfSubBands * + pstrEncParams->s16NumOfChannels) / 8 + + ( ((pstrEncParams->s16ChannelMode - 2) * + pstrEncParams->s16NumOfSubBands) + + (pstrEncParams->s16NumOfBlocks * s16Bitpool) ) / 8; + + s16BitRate = (8 * s16FrameLen * s16SamplingFreq) + / (pstrEncParams->s16NumOfSubBands * + pstrEncParams->s16NumOfBlocks * 1000); + + if (s16BitRate > pstrEncParams->u16BitRate) { + s16Bitpool--; + } + + if (pstrEncParams->s16NumOfSubBands == 8) { + pstrEncParams->s16BitPool = (s16Bitpool > 255) ? 255 : s16Bitpool; + } else { + pstrEncParams->s16BitPool = (s16Bitpool > 128) ? 128 : s16Bitpool; + } + } else { + s16Bitpool = (SINT16)( ((pstrEncParams->s16NumOfSubBands * + pstrEncParams->u16BitRate * 1000) + / (s16SamplingFreq * pstrEncParams->s16NumOfChannels)) + - ( ( (32 / pstrEncParams->s16NumOfChannels) + + (4 * pstrEncParams->s16NumOfSubBands) ) + / pstrEncParams->s16NumOfBlocks ) ); + + pstrEncParams->s16BitPool = (s16Bitpool > + (16 * pstrEncParams->s16NumOfSubBands)) + ? (16 * pstrEncParams->s16NumOfSubBands) : s16Bitpool; + } + + if (pstrEncParams->s16BitPool < 0) { + pstrEncParams->s16BitPool = 0; + } + /* sampling freq */ + HeaderParams = ((pstrEncParams->s16SamplingFreq & 3) << 6); + + /* number of blocks*/ + HeaderParams |= (((pstrEncParams->s16NumOfBlocks - 4) & 12) << 2); + + /* channel mode: mono, dual...*/ + HeaderParams |= ((pstrEncParams->s16ChannelMode & 3) << 2); + + /* Loudness or SNR */ + HeaderParams |= ((pstrEncParams->s16AllocationMethod & 1) << 1); + HeaderParams |= ((pstrEncParams->s16NumOfSubBands >> 3) & 1); /*4 or 8*/ + + pstrEncParams->FrameHeader = HeaderParams; } else { - s16Bitpool = (SINT16)( ((pstrEncParams->s16NumOfSubBands * - pstrEncParams->u16BitRate * 1000) - / (s16SamplingFreq * pstrEncParams->s16NumOfChannels)) - - ( ( (32 / pstrEncParams->s16NumOfChannels) + - (4 * pstrEncParams->s16NumOfSubBands) ) - / pstrEncParams->s16NumOfBlocks ) ); + // mSBC - pstrEncParams->s16BitPool = (s16Bitpool > - (16 * pstrEncParams->s16NumOfSubBands)) - ? (16 * pstrEncParams->s16NumOfSubBands) : s16Bitpool; + // Use mSBC encoding parameters to reset the control field + /* Required number of channels: 1 */ + pstrEncParams->s16ChannelMode = SBC_MONO; + pstrEncParams->s16NumOfChannels = 1; + + /* Required Sampling frequency : 16KHz */ + pstrEncParams->s16SamplingFreq = SBC_sf16000; + + /* Bit pool value: 26 */ + pstrEncParams->s16BitPool = 26; + + /* number of subbands: 8 */ + pstrEncParams->s16NumOfSubBands = 8; + + /* number of blocks: 15 */ + pstrEncParams->s16NumOfBlocks = 15; + + /* allocation method: loudness */ + pstrEncParams->s16AllocationMethod = SBC_LOUDNESS; + + /* set the header paramers, unused for mSBC */ + pstrEncParams->FrameHeader = 0; } - if (pstrEncParams->s16BitPool < 0) { - pstrEncParams->s16BitPool = 0; - } - /* sampling freq */ - HeaderParams = ((pstrEncParams->s16SamplingFreq & 3) << 6); - - /* number of blocks*/ - HeaderParams |= (((pstrEncParams->s16NumOfBlocks - 4) & 12) << 2); - - /* channel mode: mono, dual...*/ - HeaderParams |= ((pstrEncParams->s16ChannelMode & 3) << 2); - - /* Loudness or SNR */ - HeaderParams |= ((pstrEncParams->s16AllocationMethod & 1) << 1); - HeaderParams |= ((pstrEncParams->s16NumOfSubBands >> 3) & 1); /*4 or 8*/ - pstrEncParams->FrameHeader = HeaderParams; - if (pstrEncParams->s16NumOfSubBands == 4) { if (pstrEncParams->s16NumOfChannels == 1) { EncMaxShiftCounter = ((ENC_VX_BUFFER_SIZE - 4 * 10) >> 2) << 2; diff --git a/components/bt/bluedroid/external/sbc/encoder/srce/sbc_packing.c b/components/bt/bluedroid/external/sbc/encoder/srce/sbc_packing.c index d2019baaf1..4b1dc259d5 100644 --- a/components/bt/bluedroid/external/sbc/encoder/srce/sbc_packing.c +++ b/components/bt/bluedroid/external/sbc/encoder/srce/sbc_packing.c @@ -84,10 +84,17 @@ void EncPacking(SBC_ENC_PARAMS *pstrEncParams) #endif pu8PacketPtr = pstrEncParams->pu8NextPacket; /*Initialize the ptr*/ - *pu8PacketPtr++ = (UINT8)0x9C; /*Sync word*/ - *pu8PacketPtr++ = (UINT8)(pstrEncParams->FrameHeader); + if (pstrEncParams->sbc_mode != SBC_MODE_MSBC) { + *pu8PacketPtr++ = (UINT8)SBC_SYNC_WORD_STD; /*Sync word*/ + *pu8PacketPtr++ = (UINT8)(pstrEncParams->FrameHeader); - *pu8PacketPtr = (UINT8)(pstrEncParams->s16BitPool & 0x00FF); + *pu8PacketPtr = (UINT8)(pstrEncParams->s16BitPool & 0x00FF); + } else { + *pu8PacketPtr++ = (UINT8)SBC_SYNC_WORD_MSBC; /*Sync word*/ + // two reserved bytes + *pu8PacketPtr++ = 0; + *pu8PacketPtr = 0; + } pu8PacketPtr += 2; /*skip for CRC*/ /*here it indicate if it is byte boundary or nibble boundary*/