]> granicus.if.org Git - esp-idf/commitdiff
component/bt: modify the SBC encoder to support mSBC mode
authorwangmengyang <wangmengyang@espressif.com>
Fri, 25 May 2018 06:23:38 +0000 (14:23 +0800)
committerbaohongde <baohongde@espressif.com>
Fri, 24 May 2019 09:33:52 +0000 (17:33 +0800)
components/bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c
components/bt/bluedroid/external/sbc/encoder/include/sbc_encoder.h
components/bt/bluedroid/external/sbc/encoder/srce/sbc_encoder.c
components/bt/bluedroid/external/sbc/encoder/srce/sbc_packing.c

index c67b9783cfcd9ee6306aee794e81b6a68c0ce8a5..b734325e30c378eea7269649fe2cf0c3716fe369 100644 (file)
@@ -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();
 
index 8a507a7d3078e713d1100ebd0c44412ab62cef0f..b7b807f536bb273f4f72580ff357622930d026e4 100644 (file)
 
 #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*/
index 378111b0078ff973789acde7647aecd92f36b206..c0ab99b8306dcbec3be94ee771b5c31c0d78d9a1 100644 (file)
@@ -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,82 +205,110 @@ 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->sbc_mode != SBC_MODE_MSBC) {
+        /* Required number of channels */
+        if (pstrEncParams->s16ChannelMode == SBC_MONO) {
+            pstrEncParams->s16NumOfChannels = 1;
+        } else {
+            pstrEncParams->s16NumOfChannels = 2;
+        }
 
-    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--;
+        /* 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->s16NumOfSubBands == 8) {
-            pstrEncParams->s16BitPool = (s16Bitpool > 255) ? 255 : s16Bitpool;
+        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 {
-            pstrEncParams->s16BitPool = (s16Bitpool > 128) ? 128 : s16Bitpool;
+            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 ) );
-
-        pstrEncParams->s16BitPool = (s16Bitpool >
-                                     (16 * pstrEncParams->s16NumOfSubBands))
-                                    ? (16 * pstrEncParams->s16NumOfSubBands) : s16Bitpool;
-    }
+        // mSBC
 
-    if (pstrEncParams->s16BitPool < 0) {
-        pstrEncParams->s16BitPool = 0;
-    }
-    /* sampling freq */
-    HeaderParams = ((pstrEncParams->s16SamplingFreq & 3) << 6);
+        // 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;
 
-    /* number of blocks*/
-    HeaderParams |= (((pstrEncParams->s16NumOfBlocks - 4) & 12) << 2);
+        /* Bit pool value: 26 */
+        pstrEncParams->s16BitPool = 26;
 
-    /* channel mode: mono, dual...*/
-    HeaderParams |= ((pstrEncParams->s16ChannelMode & 3) << 2);
+        /* number of subbands: 8 */
+        pstrEncParams->s16NumOfSubBands = 8;
 
-    /* Loudness or SNR */
-    HeaderParams |= ((pstrEncParams->s16AllocationMethod & 1) << 1);
-    HeaderParams |= ((pstrEncParams->s16NumOfSubBands >> 3) & 1);  /*4 or 8*/
-    pstrEncParams->FrameHeader = HeaderParams;
+        /* 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->s16NumOfSubBands == 4) {
         if (pstrEncParams->s16NumOfChannels == 1) {
index d2019baaf14ab37b99e36dd63ff1e89e843ee9e0..4b1dc259d59728e055f6d6222482a97c8013d768 100644 (file)
@@ -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*/