mSBC: extend SBC library for mSBC

This commit is contained in:
Milanka Ringwald 2016-06-16 12:36:20 +02:00
parent f33cc9ef94
commit 435e3c4e0d
9 changed files with 96 additions and 28 deletions

View File

@ -170,6 +170,9 @@ typedef struct {
OI_BYTE formatByte;
OI_UINT8 pcmStride;
OI_UINT8 maxChannels;
/* BK4BTSTACK_CHANGE START */
OI_UINT8 mSBCEnabled; // default 0
/* BK4BTSTACK_CHANGE END */
} OI_CODEC_SBC_COMMON_CONTEXT;
@ -237,6 +240,12 @@ OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT8 pcmStride,
OI_BOOL enhanced);
/* BK4BTSTACK_CHANGE START */
OI_STATUS OI_CODEC_mSBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT32 *decoderData,
OI_UINT32 decoderDataBytes);
/* BK4BTSTACK_CHANGE END */
/**
* This function restricts the kind of SBC frames that the Decoder will
* process. Its use is optional. If used, it must be called after
@ -295,6 +304,7 @@ OI_STATUS OI_CODEC_SBC_DecoderConfigureRaw(OI_CODEC_SBC_DECODER_CONTEXT *context
OI_UINT8 alloc,
OI_UINT8 maxBitpool);
/**
* Decode one SBC frame. The frame has no header bytes. The context must have been previously
* initialized by calling OI_CODEC_SBC_DecoderConfigureRaw().

View File

@ -66,6 +66,12 @@ Function prototypes and macro definitions used internally by the codec.
#include "oi_assert.h"
#include "oi_codec_sbc.h"
/* BK4BTSTACK_CHANGE START */
#ifndef OI_mSBC_SYNCWORD
#define OI_mSBC_SYNCWORD 0xad
#endif
/* BK4BTSTACK_CHANGE END */
#ifndef OI_SBC_SYNCWORD
#define OI_SBC_SYNCWORD 0x9c
#endif

View File

@ -90,9 +90,14 @@ INLINE void OI_SBC_ReadHeader(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE
OI_CODEC_SBC_FRAME_INFO *frame = &common->frameInfo;
OI_UINT8 d1;
OI_ASSERT(data[0] == OI_SBC_SYNCWORD || data[0] == OI_SBC_ENHANCED_SYNCWORD);
/* BK4BTSTACK_CHANGE START */
if (common->mSBCEnabled){
OI_ASSERT(data[0] == OI_mSBC_SYNCWORD);
} else {
OI_ASSERT(data[0] == OI_SBC_SYNCWORD || data[0] == OI_SBC_ENHANCED_SYNCWORD);
}
/* BK4BTSTACK_CHANGE END */
/* Avoid filling out all these strucutures if we already remember the values
* from last time. Just in case we get a stream corresponding to data[1] ==
* 0, DecoderReset is responsible for ensuring the lookup table entries have
@ -105,7 +110,14 @@ INLINE void OI_SBC_ReadHeader(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE
frame->frequency = freq_values[frame->freqIndex];
frame->blocks = (d1 & (BIT5 | BIT4)) >> 4;
frame->nrof_blocks = block_values[frame->blocks];
/* BK4BTSTACK_CHANGE START */
if (common->mSBCEnabled){
frame->nrof_blocks = 15;
} else {
frame->nrof_blocks = block_values[frame->blocks];
}
/* BK4BTSTACK_CHANGE END */
frame->mode = (d1 & (BIT3 | BIT2)) >> 2;
frame->nrof_channels = channel_values[frame->mode];

View File

@ -76,7 +76,13 @@ PRIVATE OI_STATUS FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT *context,
return OI_CODEC_SBC_NO_SYNCWORD;
}
#else // SBC_ENHANCED
while (*frameBytes && (**frameData != OI_SBC_SYNCWORD)) {
/* BK4BTSTACK_CHANGE START */
OI_UINT8 syncword = OI_SBC_SYNCWORD;
if (context->common.mSBCEnabled){
syncword = OI_mSBC_SYNCWORD;
}
/* BK4BTSTACK_CHANGE END */
while (*frameBytes && (**frameData != syncword)) {
(*frameBytes)--;
(*frameData)++;
}
@ -223,6 +229,7 @@ PRIVATE OI_STATUS internal_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
return status;
}
OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT32 *decoderData,
OI_UINT32 decoderDataBytes,
@ -233,6 +240,17 @@ OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
return internal_DecoderReset(context, decoderData, decoderDataBytes, maxChannels, pcmStride, enhanced);
}
/* BK4BTSTACK_CHANGE START */
OI_STATUS OI_CODEC_mSBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT32 *decoderData,
OI_UINT32 decoderDataBytes)
{
OI_STATUS status = OI_CODEC_SBC_DecoderReset(context, decoderData, decoderDataBytes, 1, 1, FALSE);
context->common.mSBCEnabled = TRUE;
return status;
}
/* BK4BTSTACK_CHANGE END */
OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes,

View File

@ -157,7 +157,7 @@ typedef struct SBC_ENC_PARAMS_TAG
SINT16 s16ChannelMode; /* mono, dual, streo or joint streo*/
SINT16 s16NumOfSubBands; /* 4 or 8 */
SINT16 s16NumOfChannels;
SINT16 s16NumOfBlocks; /* 4, 8, 12 or 16*/
SINT16 s16NumOfBlocks; /* SBC: 4, 8, 12 or 16; mSBC: 15*/
SINT16 s16AllocationMethod; /* loudness or SNR*/
SINT16 s16BitPool; /* 16*numOfSb for mono & dual;
32*numOfSb for stereo & joint stereo */
@ -187,7 +187,9 @@ typedef struct SBC_ENC_PARAMS_TAG
UINT8 *pu8NextPacket;
UINT16 FrameHeader;
UINT16 u16PacketLength;
/* BK4BTSTACK_CHANGE START */
UINT8 mSBCEnabled;
/* BK4BTSTACK_CHANGE END */
}SBC_ENC_PARAMS;
#ifdef __cplusplus

View File

@ -371,6 +371,8 @@ void SBC_Encoder_Init(SBC_ENC_PARAMS *pstrEncParams)
HeaderParams = ((pstrEncParams->s16SamplingFreq & 3)<< 6);
/* number of blocks*/
UINT8 num = (((pstrEncParams->s16NumOfBlocks -4) & 12) << 2);
printf("number of blocks %d, %d\n", num, pstrEncParams->s16NumOfBlocks);
HeaderParams |= (((pstrEncParams->s16NumOfBlocks -4) & 12) << 2);
/* channel mode: mono, dual...*/

View File

@ -82,7 +82,8 @@ void EncPacking(SBC_ENC_PARAMS *pstrEncParams)
#endif
pu8PacketPtr = pstrEncParams->pu8NextPacket; /*Initialize the ptr*/
*pu8PacketPtr++ = (UINT8)0x9C; /*Sync word*/
*pu8PacketPtr++ = (UINT8)0xAD; /*Sync word*/
*pu8PacketPtr++=(UINT8)(pstrEncParams->FrameHeader);
*pu8PacketPtr = (UINT8)(pstrEncParams->s16BitPool & 0x00FF);

View File

@ -104,6 +104,7 @@ void little_endian_fstore_32(FILE *wav_file, uint32_t value){
fwrite(&buf, 1, 4, wav_file);
}
static void write_wav_header(FILE * wav_file, int num_samples, int num_channels, int sample_rate, int frame_count){
unsigned int bytes_per_sample = 2;
@ -170,14 +171,13 @@ int main (int argc, const char * argv[]){
const OI_BYTE *frameData = data;
OI_UINT32 pcmBytes = sizeof(pcmData);
OI_STATUS status = OI_CODEC_SBC_DecoderReset(&context, decoderData, sizeof(decoderData), 1, 1, FALSE);
// OI_STATUS status = OI_CODEC_SBC_DecoderReset(&context, decoderData, sizeof(decoderData), 1, 1, FALSE);
OI_STATUS status = OI_CODEC_mSBC_DecoderReset(&context, decoderData, sizeof(decoderData));
if (status != 0){
printf("Reset decoder error %d\n", status);
return -1;
}
int num_samples = 0;
int num_channels = 0;
int sample_rate = 0;

View File

@ -80,22 +80,24 @@ static void read_wav_header(FILE * wav_fd, SBC_ENC_PARAMS *context){
uint8_t buf[10];
fread(&buf, 1, 4, wav_fd);
buf[4] = 0;
printf("%s\n", buf ); // RIFF
// printf("%s\n", buf ); // RIFF
little_endian_fread_32(wav_fd); // 36 + bytes_per_sample * num_samples * frame_count
fread(&buf, 1, 4, wav_fd);
buf[4] = 0;
printf("%s\n", buf ); // WAVE
// printf("%s\n", buf ); // WAVE
fread(&buf, 1, 4, wav_fd);
buf[4] = 0;
printf("%s\n", buf ); // fmt
// printf("%s\n", buf ); // fmt
int fmt_length = little_endian_fread_32(wav_fd);
int fmt_format_tag = little_endian_fread_16(wav_fd);
// int fmt_length =
little_endian_fread_32(wav_fd);
// int fmt_format_tag =
little_endian_fread_16(wav_fd);
printf("fmt_length %d == 16, format %d == 1\n", fmt_length, fmt_format_tag);
// printf("fmt_length %d == 16, format %d == 1\n", fmt_length, fmt_format_tag);
context->s16NumOfChannels = little_endian_fread_16(wav_fd);
if (context->s16NumOfChannels == 1){
@ -124,7 +126,7 @@ static void read_wav_header(FILE * wav_fd, SBC_ENC_PARAMS *context){
little_endian_fread_16(wav_fd);
fread(&buf, 1, 4, wav_fd);
printf("%s\n", buf ); // data
// printf("%s\n", buf ); // data
num_data_bytes = little_endian_fread_32(wav_fd);
}
@ -145,22 +147,33 @@ static int sbc_num_frames(SBC_ENC_PARAMS * context){
}
static void write_sbc_file(FILE * sbc_fd, SBC_ENC_PARAMS * context){
int i;
for (i=0;i<context->u16PacketLength;i++){
printf("%02x ", context->pu8Packet[i]);
}
printf("\n");
// int i;
// for (i=0;i<context->u16PacketLength;i++){
// printf("%02x ", context->pu8Packet[i]);
// }
// printf("\n");
printf("write %u bytes\n", context->u16PacketLength);
fwrite(context->pu8Packet, 1, context->u16PacketLength, sbc_fd);
}
static void SBC_Encoder_Context_Init(SBC_ENC_PARAMS * context, FILE * fd, int blocks, int subbands, int allmethod, int bitpool){
static void SBC_Encoder_Context_Init(SBC_ENC_PARAMS * context, FILE * fd, int blocks, int subbands, int allmethod, int bitpool, int chmode, int mSBCEnabled){
if (mSBCEnabled){
blocks = 15;
subbands = 8;
allmethod = SBC_LOUDNESS;
bitpool = 26;
chmode = SBC_MONO;
}
context->s16NumOfSubBands = subbands;
context->s16NumOfBlocks = blocks;
context->s16AllocationMethod = allmethod;
context->s16BitPool = bitpool;
context->pu8Packet = sbc_packet;
context->s16ChannelMode = chmode;
context->mSBCEnabled = mSBCEnabled;
read_wav_header(fd, context);
}
@ -184,19 +197,23 @@ int main (int argc, const char * argv[]){
return -1;
}
SBC_Encoder_Context_Init(&context, wav_fd, SBC_BLOCK_3, SUB_BANDS_4, SBC_LOUDNESS, 31);
SBC_Encoder_Context_Init(&context, wav_fd, SBC_BLOCK_3, SUB_BANDS_4, SBC_LOUDNESS, 31, SBC_MONO, 1);
SBC_Encoder_Init(&context);
printf("channels %d, subbands %d, blocks %d\n", context.s16NumOfChannels, context.s16NumOfSubBands, context.s16NumOfBlocks);
int num_frames = sbc_num_frames(&context);
int frame_count = 0;
printf("num frames %d\n", num_frames);
while (frame_count < num_frames){
printf("frame_count %d\n", frame_count);
read_audio_frame(wav_fd, &context);
SBC_Encoder(&context);
if (context.mSBCEnabled){
context.pu8Packet[0] = 0xad;
}
write_sbc_file(sbc_fd, &context);
frame_count++;
}
printf("Done, frame count %d\n", frame_count);
fclose(wav_fd);
fclose(sbc_fd);
return 0;