diff options
author | Kausik Sinnaswamy <kausik@broadcom.com> | 2012-03-07 19:30:20 -0800 |
---|---|---|
committer | Matthew Xie <mattx@google.com> | 2012-07-14 11:19:12 -0700 |
commit | 95fa11b3b2f19a382c7e3a744a6afb452fad86df (patch) | |
tree | 1019e123db4596f2b8bd1259da04b51f3c44d7b2 /embdrv/sbc/encoder/srce/sbc_packing.c | |
parent | e2197423bcf1a93c620be13d458a9da6693fa94d (diff) | |
download | external_bluetooth_bluedroid-95fa11b3b2f19a382c7e3a744a6afb452fad86df.zip external_bluetooth_bluedroid-95fa11b3b2f19a382c7e3a744a6afb452fad86df.tar.gz external_bluetooth_bluedroid-95fa11b3b2f19a382c7e3a744a6afb452fad86df.tar.bz2 |
AV control and data path added
Change-Id: I88ec6084c140fa257154a98e23e075900e84cc8c
Diffstat (limited to 'embdrv/sbc/encoder/srce/sbc_packing.c')
-rw-r--r-- | embdrv/sbc/encoder/srce/sbc_packing.c | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/embdrv/sbc/encoder/srce/sbc_packing.c b/embdrv/sbc/encoder/srce/sbc_packing.c new file mode 100644 index 0000000..55edb9b --- /dev/null +++ b/embdrv/sbc/encoder/srce/sbc_packing.c @@ -0,0 +1,264 @@ +/****************************************************************************** +** +** File Name: $RCSfile: sbc_packing.c,v $ +** +** Description: This file contains code for packing the Encoded data into bit +** streams. +** +** Revision : $Id: sbc_packing.c,v 1.17 2006/04/11 17:07:03 mjougit Exp $ +** +** Copyright (c) 1999-2002, Widcomm Inc., All Rights Reserved. +** Widcomm Bluetooth Core. Proprietary and confidential. +** +******************************************************************************/ + +#include "sbc_encoder.h" +#include "sbc_enc_func_declare.h" + +#if (SBC_ARM_ASM_OPT==TRUE) +#define Mult32(s32In1,s32In2,s32OutLow) \ +{ \ + __asm \ + { \ + MUL s32OutLow,s32In1,s32In2; \ + } \ +} +#define Mult64(s32In1, s32In2, s32OutLow, s32OutHi) \ +{ \ + __asm \ + { \ + SMULL s32OutLow,s32OutHi,s32In1,s32In2 \ + } \ +} +#else +#define Mult32(s32In1,s32In2,s32OutLow) s32OutLow=(SINT32)s32In1*(SINT32)s32In2; +#define Mult64(s32In1, s32In2, s32OutLow, s32OutHi) \ +{ \ + s32OutLow = ((SINT32)(UINT16)s32In1 * (UINT16)s32In2); \ + s32TempVal2 = (SINT32)((s32In1 >> 16) * (UINT16)s32In2); \ + s32Carry = ( (((UINT32)(s32OutLow)>>16)&0xFFFF) + \ + + (s32TempVal2 & 0xFFFF) ) >> 16; \ + s32OutLow += (s32TempVal2 << 16); \ + s32OutHi = (s32TempVal2 >> 16) + s32Carry; \ +} +#endif + +void EncPacking(SBC_ENC_PARAMS *pstrEncParams) +{ + UINT8 *pu8PacketPtr; /* packet ptr*/ + UINT8 Temp; + SINT32 s32Blk; /* counter for block*/ + SINT32 s32Ch; /* counter for channel*/ + SINT32 s32Sb; /* counter for sub-band*/ + SINT32 s32PresentBit; /* represents bit to be stored*/ + /*SINT32 s32LoopCountI; loop counter*/ + SINT32 s32LoopCountJ; /* loop counter*/ + UINT32 u32QuantizedSbValue,u32QuantizedSbValue0; /* temp variable to store quantized sb val*/ + SINT32 s32LoopCount; /* loop counter*/ + UINT8 u8XoredVal; /* to store XORed value in CRC calculation*/ + UINT8 u8CRC; /* to store CRC value*/ + SINT16 *ps16GenPtr; + SINT32 s32NumOfBlocks; + SINT32 s32NumOfSubBands = pstrEncParams->s16NumOfSubBands; + SINT32 s32NumOfChannels = pstrEncParams->s16NumOfChannels; + UINT32 u32SfRaisedToPow2; /*scale factor raised to power 2*/ + SINT16 *ps16ScfPtr; + SINT32 *ps32SbPtr; + UINT16 u16Levels; /*to store levels*/ + SINT32 s32Temp1; /*used in 64-bit multiplication*/ + SINT32 s32Low; /*used in 64-bit multiplication*/ +#if (SBC_IS_64_MULT_IN_QUANTIZER==TRUE) + SINT32 s32Hi1,s32Low1,s32Carry,s32TempVal2,s32Hi, s32Temp2; +#endif + + pu8PacketPtr = pstrEncParams->pu8NextPacket; /*Initialize the ptr*/ + *pu8PacketPtr++ = (UINT8)0x9C; /*Sync word*/ + *pu8PacketPtr++=(UINT8)(pstrEncParams->FrameHeader); + + *pu8PacketPtr = (UINT8)(pstrEncParams->s16BitPool & 0x00FF); + pu8PacketPtr += 2; /*skip for CRC*/ + + /*here it indicate if it is byte boundary or nibble boundary*/ + s32PresentBit = 8; + Temp=0; +#if (SBC_JOINT_STE_INCLUDED == TRUE) + if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) + { + /* pack join stero parameters */ + for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++) + { + Temp <<= 1; + Temp |= pstrEncParams->as16Join[s32Sb]; + } + + /* pack RFA */ + if (s32NumOfSubBands == SUB_BANDS_4) + { + s32PresentBit = 4; + } + else + { + *(pu8PacketPtr++)=Temp; + Temp = 0; + } + } +#endif + + /* Pack Scale factor */ + ps16GenPtr = pstrEncParams->as16ScaleFactor; + s32Sb=s32NumOfChannels*s32NumOfSubBands; + /*Temp=*pu8PacketPtr;*/ + for (s32Ch = s32Sb; s32Ch >0; s32Ch--) + { + Temp<<= 4; + Temp |= *ps16GenPtr++; + + if(s32PresentBit == 4) + { + s32PresentBit = 8; + *(pu8PacketPtr++)=Temp; + Temp = 0; + } + else + { + s32PresentBit = 4; + } + } + + /* Pack samples */ + ps32SbPtr = pstrEncParams->s32SbBuffer; + /*Temp=*pu8PacketPtr;*/ + s32NumOfBlocks= pstrEncParams->s16NumOfBlocks; + for (s32Blk = s32NumOfBlocks-1; s32Blk >=0; s32Blk--) + { + ps16GenPtr = pstrEncParams->as16Bits; + ps16ScfPtr = pstrEncParams->as16ScaleFactor; + for (s32Ch = s32Sb-1; s32Ch >= 0; s32Ch--) + { + s32LoopCount = *ps16GenPtr++; + if (s32LoopCount != 0) + { +#if (SBC_IS_64_MULT_IN_QUANTIZER==TRUE) + /* finding level from reconstruction part of decoder */ + u32SfRaisedToPow2 = ((UINT32)1 << ((*ps16ScfPtr)+1)); + u16Levels = (UINT16)(((UINT32)1 << s32LoopCount) - 1); + + /* quantizer */ + s32Temp1 = (*ps32SbPtr >> 2) + (u32SfRaisedToPow2 << 12); + s32Temp2 = u16Levels; + + Mult64 (s32Temp1, s32Temp2, s32Low, s32Hi); + + s32Low1 = s32Low >> ((*ps16ScfPtr)+2); + s32Low1 &= ((UINT32)1 << (32 - ((*ps16ScfPtr)+2))) - 1; + s32Hi1 = s32Hi << (32 - ((*ps16ScfPtr) +2)); + + u32QuantizedSbValue0 = (UINT16)((s32Low1 | s32Hi1) >> 12); +#else + /* finding level from reconstruction part of decoder */ + u32SfRaisedToPow2 = ((UINT32)1 << *ps16ScfPtr); + u16Levels = (UINT16)(((UINT32)1 << s32LoopCount)-1); + + /* quantizer */ + s32Temp1 = (*ps32SbPtr >> 15) + u32SfRaisedToPow2; + Mult32(s32Temp1,u16Levels,s32Low); + s32Low>>= (*ps16ScfPtr+1); + u32QuantizedSbValue0 = (UINT16)s32Low; +#endif + /*store the number of bits required and the quantized s32Sb + sample to ease the coding*/ + u32QuantizedSbValue = u32QuantizedSbValue0; + + if(s32PresentBit >= s32LoopCount) + { + Temp <<= s32LoopCount; + Temp |= u32QuantizedSbValue; + s32PresentBit -= s32LoopCount; + } + else + { + while (s32PresentBit < s32LoopCount) + { + s32LoopCount -= s32PresentBit; + u32QuantizedSbValue >>= s32LoopCount; + + /*remove the unwanted msbs*/ + /*u32QuantizedSbValue <<= 16 - s32PresentBit; + u32QuantizedSbValue >>= 16 - s32PresentBit;*/ + + Temp <<= s32PresentBit; + + Temp |= u32QuantizedSbValue ; + /*restore the original*/ + u32QuantizedSbValue=u32QuantizedSbValue0; + + *(pu8PacketPtr++)=Temp; + Temp = 0; + s32PresentBit = 8; + } + Temp <<= s32LoopCount; + + /* remove the unwanted msbs */ + /*u32QuantizedSbValue <<= 16 - s32LoopCount; + u32QuantizedSbValue >>= 16 - s32LoopCount;*/ + + Temp |= u32QuantizedSbValue; + + s32PresentBit -= s32LoopCount; + } + } + ps16ScfPtr++; + ps32SbPtr++; + } + } + + Temp <<= s32PresentBit; + *pu8PacketPtr=Temp; + pstrEncParams->u16PacketLength=pu8PacketPtr-pstrEncParams->pu8NextPacket+1; + /*find CRC*/ + pu8PacketPtr = pstrEncParams->pu8NextPacket+1; /*Initialize the ptr*/ + u8CRC = 0x0F; + s32LoopCount = s32Sb >> 1; + + /* + The loops is run from the start of the packet till the scale factor + parameters. In case of JS, 'join' parameter is included in the packet + so that many more bytes are included in CRC calculation. + */ + Temp=*pu8PacketPtr; + for (s32Ch=1; s32Ch < (s32LoopCount+4); s32Ch++) + { + /* skip sync word and CRC bytes */ + if (s32Ch != 3) + { + for (s32LoopCountJ=7; s32LoopCountJ>=0; s32LoopCountJ--) + { + u8XoredVal = ((u8CRC >> 7) & 0x01) ^((Temp >> s32LoopCountJ) & 0x01); + u8CRC <<= 1; + u8CRC ^= (u8XoredVal * 0x1D); + u8CRC &= 0xFF; + } + } + Temp=*(++pu8PacketPtr); + } + + if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) + { + for (s32LoopCountJ = 7; s32LoopCountJ >= (8 - s32NumOfSubBands); s32LoopCountJ--) + { + u8XoredVal = ((u8CRC >> 7) & 0x01) ^((Temp >> s32LoopCountJ) & 0x01); + u8CRC <<= 1; + u8CRC ^= (u8XoredVal * 0x1D); + u8CRC &= 0xFF; + } + } + + /* CRC calculation ends here */ + + /* store CRC in packet */ + pu8PacketPtr = pstrEncParams->pu8NextPacket; /*Initialize the ptr*/ + pu8PacketPtr += 3; + *pu8PacketPtr = u8CRC; + pstrEncParams->pu8NextPacket+=pstrEncParams->u16PacketLength; /* move the pointer to the end in case there is more than one frame to encode */ +} + |