Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8bb85bc authored by En-Shuo Hsu's avatar En-Shuo Hsu
Browse files

floss: Add support of mSBC to embdrv for HFP WBS

Add logic for embdrv to also work for mSBC.
Also add an abstraction of msbc encoder and decoder for HFP.

Bug: 232463744
Tag: #floss
Test: compile and used with the following WBS prototype CL
Change-Id: I083d6ab4f9f38f1518411090a1b865deebb0f9da
parent f3f0202f
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -79,6 +79,7 @@ Declarations of codec functions, data types, and macros.


#define OI_SBC_SYNCWORD 0x9c
#define OI_SBC_SYNCWORD 0x9c
#define OI_SBC_ENHANCED_SYNCWORD 0x9d
#define OI_SBC_ENHANCED_SYNCWORD 0x9d
#define OI_SBC_MSBC_SYNCWORD 0xad


/**@name Sampling frequencies */
/**@name Sampling frequencies */
/**@{*/
/**@{*/
@@ -136,6 +137,9 @@ Declarations of codec functions, data types, and macros.
/**< A block size of 16 blocks was used to encode the stream. One possible value
/**< 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() */
 * for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_BLOCKS_16 3
#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 */
/**@name Bit allocation methods */
@@ -238,6 +242,7 @@ typedef struct {
  uint8_t restrictSubbands;
  uint8_t restrictSubbands;
  uint8_t enhancedEnabled;
  uint8_t enhancedEnabled;
  uint8_t bufferedBlocks;
  uint8_t bufferedBlocks;
  uint8_t mSbcEnabled;
} OI_CODEC_SBC_DECODER_CONTEXT;
} OI_CODEC_SBC_DECODER_CONTEXT;


typedef struct {
typedef struct {
@@ -297,6 +302,9 @@ OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT* context,
OI_STATUS OI_CODEC_SBC_DecoderLimit(OI_CODEC_SBC_DECODER_CONTEXT* context,
OI_STATUS OI_CODEC_SBC_DecoderLimit(OI_CODEC_SBC_DECODER_CONTEXT* context,
                                    OI_BOOL enhanced, uint8_t subbands);
                                    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
 * This function sets the decoder parameters for a raw decode where the decoder
 * parameters are not available in the sbc data stream.
 * parameters are not available in the sbc data stream.
+1 −1
Original line number Original line Diff line number Diff line
@@ -93,7 +93,7 @@ typedef union {
} BITNEED_UNION2;
} BITNEED_UNION2;


static const uint16_t freq_values[] = {16000, 32000, 44100, 48000};
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 channel_values[] = {1, 2, 2, 2};
static const uint8_t band_values[] = {4, 8};
static const uint8_t band_values[] = {4, 8};


+1 −1
Original line number Original line Diff line number Diff line
@@ -61,7 +61,7 @@ OI_STATUS OI_CODEC_SBC_DecoderConfigureRaw(
    return OI_STATUS_INVALID_PARAMETERS;
    return OI_STATUS_INVALID_PARAMETERS;
  }
  }


  if (blocks > SBC_BLOCKS_16) {
  if (blocks > SBC_BLOCKS_15) {
    return OI_STATUS_INVALID_PARAMETERS;
    return OI_STATUS_INVALID_PARAMETERS;
  }
  }


+46 −7
Original line number Original line Diff line number Diff line
@@ -47,15 +47,26 @@
PRIVATE OI_STATUS FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT* context,
PRIVATE OI_STATUS FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT* context,
                               const OI_BYTE** frameData,
                               const OI_BYTE** frameData,
                               uint32_t* frameBytes) {
                               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
#ifdef SBC_ENHANCED
  OI_BYTE search1 = OI_SBC_SYNCWORD;
  OI_BYTE search1 = OI_SBC_SYNCWORD;
  OI_BYTE search2 = OI_SBC_ENHANCED_SYNCWORD;
  OI_BYTE search2 = OI_SBC_ENHANCED_SYNCWORD;
#endif  // SBC_ENHANCED
#endif  // SBC_ENHANCED


  if (*frameBytes == 0) {
    return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
  }

#ifdef SBC_ENHANCED
#ifdef SBC_ENHANCED
  if (context->limitFrameFormat && context->enhancedEnabled) {
  if (context->limitFrameFormat && context->enhancedEnabled) {
    /* If the context is restricted, only search for specified SYNCWORD */
    /* If the context is restricted, only search for specified SYNCWORD */
@@ -240,6 +251,22 @@ OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT* context,
                               maxChannels, pcmStride, enhanced);
                               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,
OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT* context,
                                   const OI_BYTE** frameData,
                                   const OI_BYTE** frameData,
                                   uint32_t* frameBytes, int16_t* pcmData,
                                   uint32_t* frameBytes, int16_t* pcmData,
@@ -262,9 +289,16 @@ OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT* context,
    return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
    return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
  }
  }


  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"));
    TRACE(("Reading Header"));
    OI_SBC_ReadHeader(&context->common, *frameData);
    OI_SBC_ReadHeader(&context->common, *frameData);

  }
  /*
  /*
   * Some implementations load the decoder into RAM and use overlays for 4 vs 8
   * Some implementations load the decoder into RAM and use overlays for 4 vs 8
   * subbands. We need
   * subbands. We need
@@ -347,6 +381,11 @@ OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT* context,
  }
  }
  TRACE(("-OI_CODEC_SBC_DecodeFrame: %d", status));
  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;
  return status;
}
}


+4 −0
Original line number Original line Diff line number Diff line
@@ -68,6 +68,8 @@


#define SBC_NULL 0
#define SBC_NULL 0


#define SBC_MSBC_SYNCWORD 0xAD

#ifndef SBC_MAX_NUM_FRAME
#ifndef SBC_MAX_NUM_FRAME
#define SBC_MAX_NUM_FRAME 1
#define SBC_MAX_NUM_FRAME 1
#endif
#endif
@@ -187,6 +189,8 @@ typedef struct SBC_ENC_PARAMS_TAG {
  int16_t as16Bits[SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS];
  int16_t as16Bits[SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS];


  uint16_t FrameHeader;
  uint16_t FrameHeader;
  uint8_t SyncWord; /* Default to be 0x9C for SBC if not assigned.
                       Assigning to 0xAD for mSBC */


} SBC_ENC_PARAMS;
} SBC_ENC_PARAMS;


Loading