1df25739fSMilanka Ringwald /****************************************************************************** 2df25739fSMilanka Ringwald * 3df25739fSMilanka Ringwald * Copyright (C) 1999-2012 Broadcom Corporation 4df25739fSMilanka Ringwald * 5df25739fSMilanka Ringwald * Licensed under the Apache License, Version 2.0 (the "License"); 6df25739fSMilanka Ringwald * you may not use this file except in compliance with the License. 7df25739fSMilanka Ringwald * You may obtain a copy of the License at: 8df25739fSMilanka Ringwald * 9df25739fSMilanka Ringwald * http://www.apache.org/licenses/LICENSE-2.0 10df25739fSMilanka Ringwald * 11df25739fSMilanka Ringwald * Unless required by applicable law or agreed to in writing, software 12df25739fSMilanka Ringwald * distributed under the License is distributed on an "AS IS" BASIS, 13df25739fSMilanka Ringwald * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14df25739fSMilanka Ringwald * See the License for the specific language governing permissions and 15df25739fSMilanka Ringwald * limitations under the License. 16df25739fSMilanka Ringwald * 17df25739fSMilanka Ringwald ******************************************************************************/ 18df25739fSMilanka Ringwald 19df25739fSMilanka Ringwald /****************************************************************************** 20df25739fSMilanka Ringwald * 21df25739fSMilanka Ringwald * This file contains code for packing the Encoded data into bit streams. 22df25739fSMilanka Ringwald * 23df25739fSMilanka Ringwald ******************************************************************************/ 24df25739fSMilanka Ringwald 25df25739fSMilanka Ringwald #include "sbc_encoder.h" 26df25739fSMilanka Ringwald #include "sbc_enc_func_declare.h" 27df25739fSMilanka Ringwald 28df25739fSMilanka Ringwald #if (SBC_ARM_ASM_OPT==TRUE) 29df25739fSMilanka Ringwald #define Mult32(s32In1,s32In2,s32OutLow) \ 30df25739fSMilanka Ringwald { \ 31df25739fSMilanka Ringwald __asm \ 32df25739fSMilanka Ringwald { \ 33df25739fSMilanka Ringwald MUL s32OutLow,s32In1,s32In2; \ 34df25739fSMilanka Ringwald } \ 35df25739fSMilanka Ringwald } 36df25739fSMilanka Ringwald #define Mult64(s32In1, s32In2, s32OutLow, s32OutHi) \ 37df25739fSMilanka Ringwald { \ 38df25739fSMilanka Ringwald __asm \ 39df25739fSMilanka Ringwald { \ 40df25739fSMilanka Ringwald SMULL s32OutLow,s32OutHi,s32In1,s32In2 \ 41df25739fSMilanka Ringwald } \ 42df25739fSMilanka Ringwald } 43df25739fSMilanka Ringwald #else 44df25739fSMilanka Ringwald #define Mult32(s32In1,s32In2,s32OutLow) s32OutLow=(SINT32)s32In1*(SINT32)s32In2; 45df25739fSMilanka Ringwald #define Mult64(s32In1, s32In2, s32OutLow, s32OutHi) \ 46df25739fSMilanka Ringwald { \ 47df25739fSMilanka Ringwald s32OutLow = ((SINT32)(UINT16)s32In1 * (UINT16)s32In2); \ 48df25739fSMilanka Ringwald s32TempVal2 = (SINT32)((s32In1 >> 16) * (UINT16)s32In2); \ 49df25739fSMilanka Ringwald s32Carry = ( (((UINT32)(s32OutLow)>>16)&0xFFFF) + \ 50df25739fSMilanka Ringwald + (s32TempVal2 & 0xFFFF) ) >> 16; \ 51df25739fSMilanka Ringwald s32OutLow += (s32TempVal2 << 16); \ 52df25739fSMilanka Ringwald s32OutHi = (s32TempVal2 >> 16) + s32Carry; \ 53df25739fSMilanka Ringwald } 54df25739fSMilanka Ringwald #endif 55df25739fSMilanka Ringwald 56df25739fSMilanka Ringwald void EncPacking(SBC_ENC_PARAMS *pstrEncParams) 57df25739fSMilanka Ringwald { 58df25739fSMilanka Ringwald UINT8 *pu8PacketPtr; /* packet ptr*/ 59df25739fSMilanka Ringwald UINT8 Temp; 60df25739fSMilanka Ringwald SINT32 s32Blk; /* counter for block*/ 61df25739fSMilanka Ringwald SINT32 s32Ch; /* counter for channel*/ 62df25739fSMilanka Ringwald SINT32 s32Sb; /* counter for sub-band*/ 63df25739fSMilanka Ringwald SINT32 s32PresentBit; /* represents bit to be stored*/ 64df25739fSMilanka Ringwald /*SINT32 s32LoopCountI; loop counter*/ 65df25739fSMilanka Ringwald SINT32 s32LoopCountJ; /* loop counter*/ 66df25739fSMilanka Ringwald UINT32 u32QuantizedSbValue,u32QuantizedSbValue0; /* temp variable to store quantized sb val*/ 67df25739fSMilanka Ringwald SINT32 s32LoopCount; /* loop counter*/ 68df25739fSMilanka Ringwald UINT8 u8XoredVal; /* to store XORed value in CRC calculation*/ 69df25739fSMilanka Ringwald UINT8 u8CRC; /* to store CRC value*/ 70df25739fSMilanka Ringwald SINT16 *ps16GenPtr; 71df25739fSMilanka Ringwald SINT32 s32NumOfBlocks; 72df25739fSMilanka Ringwald SINT32 s32NumOfSubBands = pstrEncParams->s16NumOfSubBands; 73df25739fSMilanka Ringwald SINT32 s32NumOfChannels = pstrEncParams->s16NumOfChannels; 74df25739fSMilanka Ringwald UINT32 u32SfRaisedToPow2; /*scale factor raised to power 2*/ 75df25739fSMilanka Ringwald SINT16 *ps16ScfPtr; 76df25739fSMilanka Ringwald SINT32 *ps32SbPtr; 77df25739fSMilanka Ringwald UINT16 u16Levels; /*to store levels*/ 78df25739fSMilanka Ringwald SINT32 s32Temp1; /*used in 64-bit multiplication*/ 79df25739fSMilanka Ringwald SINT32 s32Low; /*used in 64-bit multiplication*/ 80df25739fSMilanka Ringwald #if (SBC_IS_64_MULT_IN_QUANTIZER==TRUE) 81df25739fSMilanka Ringwald SINT32 s32Hi1,s32Low1,s32Carry,s32TempVal2,s32Hi, s32Temp2; 82df25739fSMilanka Ringwald #endif 83df25739fSMilanka Ringwald 84df25739fSMilanka Ringwald pu8PacketPtr = pstrEncParams->pu8NextPacket; /*Initialize the ptr*/ 85435e3c4eSMilanka Ringwald 86*ca50f5f5SMilanka Ringwald /* BK4BTSTACK_CHANGE START */ 87*ca50f5f5SMilanka Ringwald if (pstrEncParams->mSBCEnabled){ 88435e3c4eSMilanka Ringwald *pu8PacketPtr++ = (UINT8)0xAD; /*Sync word*/ 89*ca50f5f5SMilanka Ringwald } else { 90*ca50f5f5SMilanka Ringwald *pu8PacketPtr++ = (UINT8)0x9C; /*Sync word*/ 91*ca50f5f5SMilanka Ringwald } 92*ca50f5f5SMilanka Ringwald /* BK4BTSTACK_CHANGE END */ 93df25739fSMilanka Ringwald *pu8PacketPtr++=(UINT8)(pstrEncParams->FrameHeader); 94df25739fSMilanka Ringwald 95df25739fSMilanka Ringwald *pu8PacketPtr = (UINT8)(pstrEncParams->s16BitPool & 0x00FF); 96df25739fSMilanka Ringwald pu8PacketPtr += 2; /*skip for CRC*/ 97df25739fSMilanka Ringwald 98df25739fSMilanka Ringwald /*here it indicate if it is byte boundary or nibble boundary*/ 99df25739fSMilanka Ringwald s32PresentBit = 8; 100df25739fSMilanka Ringwald Temp=0; 101df25739fSMilanka Ringwald #if (SBC_JOINT_STE_INCLUDED == TRUE) 102df25739fSMilanka Ringwald if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) 103df25739fSMilanka Ringwald { 104df25739fSMilanka Ringwald /* pack join stero parameters */ 105df25739fSMilanka Ringwald for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++) 106df25739fSMilanka Ringwald { 107df25739fSMilanka Ringwald Temp <<= 1; 108df25739fSMilanka Ringwald Temp |= pstrEncParams->as16Join[s32Sb]; 109df25739fSMilanka Ringwald } 110df25739fSMilanka Ringwald 111df25739fSMilanka Ringwald /* pack RFA */ 112df25739fSMilanka Ringwald if (s32NumOfSubBands == SUB_BANDS_4) 113df25739fSMilanka Ringwald { 114df25739fSMilanka Ringwald s32PresentBit = 4; 115df25739fSMilanka Ringwald } 116df25739fSMilanka Ringwald else 117df25739fSMilanka Ringwald { 118df25739fSMilanka Ringwald *(pu8PacketPtr++)=Temp; 119df25739fSMilanka Ringwald Temp = 0; 120df25739fSMilanka Ringwald } 121df25739fSMilanka Ringwald } 122df25739fSMilanka Ringwald #endif 123df25739fSMilanka Ringwald 124df25739fSMilanka Ringwald /* Pack Scale factor */ 125df25739fSMilanka Ringwald ps16GenPtr = pstrEncParams->as16ScaleFactor; 126df25739fSMilanka Ringwald s32Sb=s32NumOfChannels*s32NumOfSubBands; 127df25739fSMilanka Ringwald /*Temp=*pu8PacketPtr;*/ 128df25739fSMilanka Ringwald for (s32Ch = s32Sb; s32Ch >0; s32Ch--) 129df25739fSMilanka Ringwald { 130df25739fSMilanka Ringwald Temp<<= 4; 131df25739fSMilanka Ringwald Temp |= *ps16GenPtr++; 132df25739fSMilanka Ringwald 133df25739fSMilanka Ringwald if(s32PresentBit == 4) 134df25739fSMilanka Ringwald { 135df25739fSMilanka Ringwald s32PresentBit = 8; 136df25739fSMilanka Ringwald *(pu8PacketPtr++)=Temp; 137df25739fSMilanka Ringwald Temp = 0; 138df25739fSMilanka Ringwald } 139df25739fSMilanka Ringwald else 140df25739fSMilanka Ringwald { 141df25739fSMilanka Ringwald s32PresentBit = 4; 142df25739fSMilanka Ringwald } 143df25739fSMilanka Ringwald } 144df25739fSMilanka Ringwald 145df25739fSMilanka Ringwald /* Pack samples */ 146df25739fSMilanka Ringwald ps32SbPtr = pstrEncParams->s32SbBuffer; 147df25739fSMilanka Ringwald /*Temp=*pu8PacketPtr;*/ 148df25739fSMilanka Ringwald s32NumOfBlocks= pstrEncParams->s16NumOfBlocks; 149df25739fSMilanka Ringwald for (s32Blk = s32NumOfBlocks-1; s32Blk >=0; s32Blk--) 150df25739fSMilanka Ringwald { 151df25739fSMilanka Ringwald ps16GenPtr = pstrEncParams->as16Bits; 152df25739fSMilanka Ringwald ps16ScfPtr = pstrEncParams->as16ScaleFactor; 153df25739fSMilanka Ringwald for (s32Ch = s32Sb-1; s32Ch >= 0; s32Ch--) 154df25739fSMilanka Ringwald { 155df25739fSMilanka Ringwald s32LoopCount = *ps16GenPtr++; 156df25739fSMilanka Ringwald if (s32LoopCount != 0) 157df25739fSMilanka Ringwald { 158df25739fSMilanka Ringwald #if (SBC_IS_64_MULT_IN_QUANTIZER==TRUE) 159df25739fSMilanka Ringwald /* finding level from reconstruction part of decoder */ 160df25739fSMilanka Ringwald u32SfRaisedToPow2 = ((UINT32)1 << ((*ps16ScfPtr)+1)); 161df25739fSMilanka Ringwald u16Levels = (UINT16)(((UINT32)1 << s32LoopCount) - 1); 162df25739fSMilanka Ringwald 163df25739fSMilanka Ringwald /* quantizer */ 164df25739fSMilanka Ringwald s32Temp1 = (*ps32SbPtr >> 2) + (u32SfRaisedToPow2 << 12); 165df25739fSMilanka Ringwald s32Temp2 = u16Levels; 166df25739fSMilanka Ringwald 167df25739fSMilanka Ringwald Mult64 (s32Temp1, s32Temp2, s32Low, s32Hi); 168df25739fSMilanka Ringwald 169df25739fSMilanka Ringwald s32Low1 = s32Low >> ((*ps16ScfPtr)+2); 170df25739fSMilanka Ringwald s32Low1 &= ((UINT32)1 << (32 - ((*ps16ScfPtr)+2))) - 1; 171df25739fSMilanka Ringwald s32Hi1 = s32Hi << (32 - ((*ps16ScfPtr) +2)); 172df25739fSMilanka Ringwald 173df25739fSMilanka Ringwald u32QuantizedSbValue0 = (UINT16)((s32Low1 | s32Hi1) >> 12); 174df25739fSMilanka Ringwald #else 175df25739fSMilanka Ringwald /* finding level from reconstruction part of decoder */ 176df25739fSMilanka Ringwald u32SfRaisedToPow2 = ((UINT32)1 << *ps16ScfPtr); 177df25739fSMilanka Ringwald u16Levels = (UINT16)(((UINT32)1 << s32LoopCount)-1); 178df25739fSMilanka Ringwald 179df25739fSMilanka Ringwald /* quantizer */ 180df25739fSMilanka Ringwald s32Temp1 = (*ps32SbPtr >> 15) + u32SfRaisedToPow2; 181df25739fSMilanka Ringwald Mult32(s32Temp1,u16Levels,s32Low); 182df25739fSMilanka Ringwald s32Low>>= (*ps16ScfPtr+1); 183df25739fSMilanka Ringwald u32QuantizedSbValue0 = (UINT16)s32Low; 184df25739fSMilanka Ringwald #endif 185df25739fSMilanka Ringwald /*store the number of bits required and the quantized s32Sb 186df25739fSMilanka Ringwald sample to ease the coding*/ 187df25739fSMilanka Ringwald u32QuantizedSbValue = u32QuantizedSbValue0; 188df25739fSMilanka Ringwald 189df25739fSMilanka Ringwald if(s32PresentBit >= s32LoopCount) 190df25739fSMilanka Ringwald { 191df25739fSMilanka Ringwald Temp <<= s32LoopCount; 192df25739fSMilanka Ringwald Temp |= u32QuantizedSbValue; 193df25739fSMilanka Ringwald s32PresentBit -= s32LoopCount; 194df25739fSMilanka Ringwald } 195df25739fSMilanka Ringwald else 196df25739fSMilanka Ringwald { 197df25739fSMilanka Ringwald while (s32PresentBit < s32LoopCount) 198df25739fSMilanka Ringwald { 199df25739fSMilanka Ringwald s32LoopCount -= s32PresentBit; 200df25739fSMilanka Ringwald u32QuantizedSbValue >>= s32LoopCount; 201df25739fSMilanka Ringwald 202df25739fSMilanka Ringwald /*remove the unwanted msbs*/ 203df25739fSMilanka Ringwald /*u32QuantizedSbValue <<= 16 - s32PresentBit; 204df25739fSMilanka Ringwald u32QuantizedSbValue >>= 16 - s32PresentBit;*/ 205df25739fSMilanka Ringwald 206df25739fSMilanka Ringwald Temp <<= s32PresentBit; 207df25739fSMilanka Ringwald 208df25739fSMilanka Ringwald Temp |= u32QuantizedSbValue ; 209df25739fSMilanka Ringwald /*restore the original*/ 210df25739fSMilanka Ringwald u32QuantizedSbValue=u32QuantizedSbValue0; 211df25739fSMilanka Ringwald 212df25739fSMilanka Ringwald *(pu8PacketPtr++)=Temp; 213df25739fSMilanka Ringwald Temp = 0; 214df25739fSMilanka Ringwald s32PresentBit = 8; 215df25739fSMilanka Ringwald } 216df25739fSMilanka Ringwald Temp <<= s32LoopCount; 217df25739fSMilanka Ringwald 218df25739fSMilanka Ringwald /* remove the unwanted msbs */ 219df25739fSMilanka Ringwald /*u32QuantizedSbValue <<= 16 - s32LoopCount; 220df25739fSMilanka Ringwald u32QuantizedSbValue >>= 16 - s32LoopCount;*/ 221df25739fSMilanka Ringwald 222df25739fSMilanka Ringwald Temp |= u32QuantizedSbValue; 223df25739fSMilanka Ringwald 224df25739fSMilanka Ringwald s32PresentBit -= s32LoopCount; 225df25739fSMilanka Ringwald } 226df25739fSMilanka Ringwald } 227df25739fSMilanka Ringwald ps16ScfPtr++; 228df25739fSMilanka Ringwald ps32SbPtr++; 229df25739fSMilanka Ringwald } 230df25739fSMilanka Ringwald } 231df25739fSMilanka Ringwald 232df25739fSMilanka Ringwald Temp <<= s32PresentBit; 233df25739fSMilanka Ringwald *pu8PacketPtr=Temp; 234df25739fSMilanka Ringwald pstrEncParams->u16PacketLength=pu8PacketPtr-pstrEncParams->pu8NextPacket+1; 235df25739fSMilanka Ringwald /*find CRC*/ 236df25739fSMilanka Ringwald pu8PacketPtr = pstrEncParams->pu8NextPacket+1; /*Initialize the ptr*/ 237df25739fSMilanka Ringwald u8CRC = 0x0F; 238df25739fSMilanka Ringwald s32LoopCount = s32Sb >> 1; 239df25739fSMilanka Ringwald 240df25739fSMilanka Ringwald /* 241df25739fSMilanka Ringwald The loops is run from the start of the packet till the scale factor 242df25739fSMilanka Ringwald parameters. In case of JS, 'join' parameter is included in the packet 243df25739fSMilanka Ringwald so that many more bytes are included in CRC calculation. 244df25739fSMilanka Ringwald */ 245df25739fSMilanka Ringwald Temp=*pu8PacketPtr; 246df25739fSMilanka Ringwald for (s32Ch=1; s32Ch < (s32LoopCount+4); s32Ch++) 247df25739fSMilanka Ringwald { 248df25739fSMilanka Ringwald /* skip sync word and CRC bytes */ 249df25739fSMilanka Ringwald if (s32Ch != 3) 250df25739fSMilanka Ringwald { 251df25739fSMilanka Ringwald for (s32LoopCountJ=7; s32LoopCountJ>=0; s32LoopCountJ--) 252df25739fSMilanka Ringwald { 253df25739fSMilanka Ringwald u8XoredVal = ((u8CRC >> 7) & 0x01) ^((Temp >> s32LoopCountJ) & 0x01); 254df25739fSMilanka Ringwald u8CRC <<= 1; 255df25739fSMilanka Ringwald u8CRC ^= (u8XoredVal * 0x1D); 256df25739fSMilanka Ringwald u8CRC &= 0xFF; 257df25739fSMilanka Ringwald } 258df25739fSMilanka Ringwald } 259df25739fSMilanka Ringwald Temp=*(++pu8PacketPtr); 260df25739fSMilanka Ringwald } 261df25739fSMilanka Ringwald 262df25739fSMilanka Ringwald if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) 263df25739fSMilanka Ringwald { 264df25739fSMilanka Ringwald for (s32LoopCountJ = 7; s32LoopCountJ >= (8 - s32NumOfSubBands); s32LoopCountJ--) 265df25739fSMilanka Ringwald { 266df25739fSMilanka Ringwald u8XoredVal = ((u8CRC >> 7) & 0x01) ^((Temp >> s32LoopCountJ) & 0x01); 267df25739fSMilanka Ringwald u8CRC <<= 1; 268df25739fSMilanka Ringwald u8CRC ^= (u8XoredVal * 0x1D); 269df25739fSMilanka Ringwald u8CRC &= 0xFF; 270df25739fSMilanka Ringwald } 271df25739fSMilanka Ringwald } 272df25739fSMilanka Ringwald 273df25739fSMilanka Ringwald /* CRC calculation ends here */ 274df25739fSMilanka Ringwald 275df25739fSMilanka Ringwald /* store CRC in packet */ 276df25739fSMilanka Ringwald pu8PacketPtr = pstrEncParams->pu8NextPacket; /*Initialize the ptr*/ 277df25739fSMilanka Ringwald pu8PacketPtr += 3; 278df25739fSMilanka Ringwald *pu8PacketPtr = u8CRC; 279df25739fSMilanka Ringwald pstrEncParams->pu8NextPacket+=pstrEncParams->u16PacketLength; /* move the pointer to the end in case there is more than one frame to encode */ 280df25739fSMilanka Ringwald } 281df25739fSMilanka Ringwald 282