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