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);