Merge "floss: Add support of mSBC to embdrv for HFP WBS"

GitOrigin-RevId: b57d8854948aaa5643e3495efaade1b87fe3df45
Change-Id: Ie31cc335ccb82f6c2e5cddbee37d6bbf1acdefcb
diff --git a/system/embdrv/sbc/decoder/include/oi_codec_sbc.h b/system/embdrv/sbc/decoder/include/oi_codec_sbc.h
index ee761db..3e69ff3 100644
--- a/system/embdrv/sbc/decoder/include/oi_codec_sbc.h
+++ b/system/embdrv/sbc/decoder/include/oi_codec_sbc.h
@@ -79,6 +79,7 @@
 
 #define OI_SBC_SYNCWORD 0x9c
 #define OI_SBC_ENHANCED_SYNCWORD 0x9d
+#define OI_SBC_MSBC_SYNCWORD 0xad
 
 /**@name Sampling frequencies */
 /**@{*/
@@ -136,6 +137,9 @@
 /**< A block size of 16 blocks was used to encode the stream. One possible value
  * for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
 #define SBC_BLOCKS_16 3
+/**< A block size of 15 blocks was used to encode the stream. One possible value
+ * for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
+#define SBC_BLOCKS_15 4
 /**@}*/
 
 /**@name Bit allocation methods */
@@ -238,6 +242,7 @@
   uint8_t restrictSubbands;
   uint8_t enhancedEnabled;
   uint8_t bufferedBlocks;
+  uint8_t mSbcEnabled;
 } OI_CODEC_SBC_DECODER_CONTEXT;
 
 typedef struct {
@@ -297,6 +302,9 @@
 OI_STATUS OI_CODEC_SBC_DecoderLimit(OI_CODEC_SBC_DECODER_CONTEXT* context,
                                     OI_BOOL enhanced, uint8_t subbands);
 
+OI_STATUS OI_CODEC_SBC_DecoderConfigureMSbc(
+    OI_CODEC_SBC_DECODER_CONTEXT* context);
+
 /**
  * This function sets the decoder parameters for a raw decode where the decoder
  * parameters are not available in the sbc data stream.
diff --git a/system/embdrv/sbc/decoder/include/oi_codec_sbc_private.h b/system/embdrv/sbc/decoder/include/oi_codec_sbc_private.h
index 080fe5d..7775670 100644
--- a/system/embdrv/sbc/decoder/include/oi_codec_sbc_private.h
+++ b/system/embdrv/sbc/decoder/include/oi_codec_sbc_private.h
@@ -93,7 +93,7 @@
 } BITNEED_UNION2;
 
 static const uint16_t freq_values[] = {16000, 32000, 44100, 48000};
-static const uint8_t block_values[] = {4, 8, 12, 16};
+static const uint8_t block_values[] = {4, 8, 12, 16, 15};
 static const uint8_t channel_values[] = {1, 2, 2, 2};
 static const uint8_t band_values[] = {4, 8};
 
diff --git a/system/embdrv/sbc/decoder/srce/decoder-oina.c b/system/embdrv/sbc/decoder/srce/decoder-oina.c
index 3553d06..1999868 100644
--- a/system/embdrv/sbc/decoder/srce/decoder-oina.c
+++ b/system/embdrv/sbc/decoder/srce/decoder-oina.c
@@ -61,7 +61,7 @@
     return OI_STATUS_INVALID_PARAMETERS;
   }
 
-  if (blocks > SBC_BLOCKS_16) {
+  if (blocks > SBC_BLOCKS_15) {
     return OI_STATUS_INVALID_PARAMETERS;
   }
 
diff --git a/system/embdrv/sbc/decoder/srce/decoder-sbc.c b/system/embdrv/sbc/decoder/srce/decoder-sbc.c
index d5c59d9..8080d3b 100644
--- a/system/embdrv/sbc/decoder/srce/decoder-sbc.c
+++ b/system/embdrv/sbc/decoder/srce/decoder-sbc.c
@@ -47,15 +47,26 @@
 PRIVATE OI_STATUS FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT* context,
                                const OI_BYTE** frameData,
                                uint32_t* frameBytes) {
+  if (*frameBytes == 0) {
+    return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
+  }
+
+  if (context->mSbcEnabled) {
+    while (*frameBytes && **frameData != OI_SBC_MSBC_SYNCWORD) {
+      (*frameBytes)--;
+      (*frameData)++;
+    }
+    if (*frameBytes == 0) {
+      return OI_CODEC_SBC_NO_SYNCWORD;
+    }
+    return OI_OK;
+  }
+
 #ifdef SBC_ENHANCED
   OI_BYTE search1 = OI_SBC_SYNCWORD;
   OI_BYTE search2 = OI_SBC_ENHANCED_SYNCWORD;
 #endif  // SBC_ENHANCED
 
-  if (*frameBytes == 0) {
-    return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
-  }
-
 #ifdef SBC_ENHANCED
   if (context->limitFrameFormat && context->enhancedEnabled) {
     /* If the context is restricted, only search for specified SYNCWORD */
@@ -240,6 +251,22 @@
                                maxChannels, pcmStride, enhanced);
 }
 
+OI_STATUS OI_CODEC_SBC_DecoderConfigureMSbc(
+    OI_CODEC_SBC_DECODER_CONTEXT* context) {
+  context->mSbcEnabled = TRUE;
+  context->common.frameInfo.enhanced = FALSE;
+  context->common.frameInfo.freqIndex = SBC_FREQ_16000;
+  context->common.frameInfo.mode = SBC_MONO;
+  context->common.frameInfo.subbands = SBC_SUBBANDS_8;
+  context->common.frameInfo.blocks = SBC_BLOCKS_15;
+  context->common.frameInfo.alloc = SBC_LOUDNESS;
+  context->common.frameInfo.bitpool = 26;
+
+  OI_SBC_ExpandFrameFields(&context->common.frameInfo);
+
+  return OI_OK;
+}
+
 OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT* context,
                                    const OI_BYTE** frameData,
                                    uint32_t* frameBytes, int16_t* pcmData,
@@ -262,9 +289,16 @@
     return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
   }
 
-  TRACE(("Reading Header"));
-  OI_SBC_ReadHeader(&context->common, *frameData);
-
+  if (context->mSbcEnabled) {
+    /*
+     * There is no parameter embedded in mSBC's header as the parameters are
+     * fixed unlike the general SBC. We only need the packet's crc for mSBC.
+     */
+    context->common.frameInfo.crc = (*frameData)[3];
+  } else {
+    TRACE(("Reading Header"));
+    OI_SBC_ReadHeader(&context->common, *frameData);
+  }
   /*
    * Some implementations load the decoder into RAM and use overlays for 4 vs 8
    * subbands. We need
@@ -347,6 +381,11 @@
   }
   TRACE(("-OI_CODEC_SBC_DecodeFrame: %d", status));
 
+  /* mSBC is designed with 8 bits of zeros at the end for padding. */
+  if (context->mSbcEnabled) {
+    *frameBytes -= 1;
+  }
+
   return status;
 }
 
diff --git a/system/embdrv/sbc/encoder/include/sbc_encoder.h b/system/embdrv/sbc/encoder/include/sbc_encoder.h
index ad01089..1d4b7e2 100644
--- a/system/embdrv/sbc/encoder/include/sbc_encoder.h
+++ b/system/embdrv/sbc/encoder/include/sbc_encoder.h
@@ -68,6 +68,8 @@
 
 #define SBC_NULL 0
 
+#define SBC_MSBC_SYNCWORD 0xAD
+
 #ifndef SBC_MAX_NUM_FRAME
 #define SBC_MAX_NUM_FRAME 1
 #endif
@@ -187,6 +189,8 @@
   int16_t as16Bits[SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS];
 
   uint16_t FrameHeader;
+  uint8_t SyncWord; /* Default to be 0x9C for SBC if not assigned.
+                       Assigning to 0xAD for mSBC */
 
 } SBC_ENC_PARAMS;
 
diff --git a/system/embdrv/sbc/encoder/srce/sbc_packing.c b/system/embdrv/sbc/encoder/srce/sbc_packing.c
index 205b373..9218207 100644
--- a/system/embdrv/sbc/encoder/srce/sbc_packing.c
+++ b/system/embdrv/sbc/encoder/srce/sbc_packing.c
@@ -79,8 +79,12 @@
 #endif
 #endif
 
-  pu8PacketPtr = output;           /*Initialize the ptr*/
-  *pu8PacketPtr++ = (uint8_t)0x9C; /*Sync word*/
+  pu8PacketPtr = output; /*Initialize the ptr*/
+  if (!pstrEncParams->SyncWord) {
+    *pu8PacketPtr++ = (uint8_t)0x9C; /*Sync word*/
+  } else {
+    *pu8PacketPtr++ = pstrEncParams->SyncWord; /*Sync word*/
+  }
   *pu8PacketPtr++ = (uint8_t)(pstrEncParams->FrameHeader);
 
   *pu8PacketPtr = (uint8_t)(pstrEncParams->s16BitPool & 0x00FF);