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 uint8_t * reserved_ptr = (void*) 0; 88 if (pstrEncParams->mSBCEnabled){ 89 *pu8PacketPtr++ = (UINT8)0xAD; /*Sync word*/ 90 reserved_ptr = pu8PacketPtr; 91 } else { 92 *pu8PacketPtr++ = (UINT8)0x9C; /*Sync word*/ 93 } 94 /* BK4BTSTACK_CHANGE END */ 95 *pu8PacketPtr++=(UINT8)(pstrEncParams->FrameHeader); 96 97 *pu8PacketPtr = (UINT8)(pstrEncParams->s16BitPool & 0x00FF); 98 pu8PacketPtr += 2; /*skip for CRC*/ 99 100 /*here it indicate if it is byte boundary or nibble boundary*/ 101 s32PresentBit = 8; 102 Temp=0; 103 #if (SBC_JOINT_STE_INCLUDED == TRUE) 104 if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) 105 { 106 /* pack join stero parameters */ 107 for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++) 108 { 109 Temp <<= 1; 110 Temp |= pstrEncParams->as16Join[s32Sb]; 111 } 112 113 /* pack RFA */ 114 if (s32NumOfSubBands == SUB_BANDS_4) 115 { 116 s32PresentBit = 4; 117 } 118 else 119 { 120 *(pu8PacketPtr++)=Temp; 121 Temp = 0; 122 } 123 } 124 #endif 125 126 /* Pack Scale factor */ 127 ps16GenPtr = pstrEncParams->as16ScaleFactor; 128 s32Sb=s32NumOfChannels*s32NumOfSubBands; 129 /*Temp=*pu8PacketPtr;*/ 130 for (s32Ch = s32Sb; s32Ch >0; s32Ch--) 131 { 132 Temp<<= 4; 133 Temp |= *ps16GenPtr++; 134 135 if(s32PresentBit == 4) 136 { 137 s32PresentBit = 8; 138 *(pu8PacketPtr++)=Temp; 139 Temp = 0; 140 } 141 else 142 { 143 s32PresentBit = 4; 144 } 145 } 146 147 /* Pack samples */ 148 ps32SbPtr = pstrEncParams->s32SbBuffer; 149 /*Temp=*pu8PacketPtr;*/ 150 s32NumOfBlocks= pstrEncParams->s16NumOfBlocks; 151 for (s32Blk = s32NumOfBlocks-1; s32Blk >=0; s32Blk--) 152 { 153 ps16GenPtr = pstrEncParams->as16Bits; 154 ps16ScfPtr = pstrEncParams->as16ScaleFactor; 155 for (s32Ch = s32Sb-1; s32Ch >= 0; s32Ch--) 156 { 157 s32LoopCount = *ps16GenPtr++; 158 if (s32LoopCount != 0) 159 { 160 #if (SBC_IS_64_MULT_IN_QUANTIZER==TRUE) 161 /* finding level from reconstruction part of decoder */ 162 u32SfRaisedToPow2 = ((UINT32)1 << ((*ps16ScfPtr)+1)); 163 u16Levels = (UINT16)(((UINT32)1 << s32LoopCount) - 1); 164 165 /* quantizer */ 166 s32Temp1 = (*ps32SbPtr >> 2) + (u32SfRaisedToPow2 << 12); 167 s32Temp2 = u16Levels; 168 169 Mult64 (s32Temp1, s32Temp2, s32Low, s32Hi); 170 171 s32Low1 = s32Low >> ((*ps16ScfPtr)+2); 172 s32Low1 &= ((UINT32)1 << (32 - ((*ps16ScfPtr)+2))) - 1; 173 s32Hi1 = s32Hi << (32 - ((*ps16ScfPtr) +2)); 174 175 u32QuantizedSbValue0 = (UINT16)((s32Low1 | s32Hi1) >> 12); 176 #else 177 /* finding level from reconstruction part of decoder */ 178 u32SfRaisedToPow2 = ((UINT32)1 << *ps16ScfPtr); 179 u16Levels = (UINT16)(((UINT32)1 << s32LoopCount)-1); 180 181 /* quantizer */ 182 s32Temp1 = (*ps32SbPtr >> 15) + u32SfRaisedToPow2; 183 Mult32(s32Temp1,u16Levels,s32Low); 184 s32Low>>= (*ps16ScfPtr+1); 185 u32QuantizedSbValue0 = (UINT16)s32Low; 186 #endif 187 /*store the number of bits required and the quantized s32Sb 188 sample to ease the coding*/ 189 u32QuantizedSbValue = u32QuantizedSbValue0; 190 191 if(s32PresentBit >= s32LoopCount) 192 { 193 Temp <<= s32LoopCount; 194 Temp |= u32QuantizedSbValue; 195 s32PresentBit -= s32LoopCount; 196 } 197 else 198 { 199 while (s32PresentBit < s32LoopCount) 200 { 201 s32LoopCount -= s32PresentBit; 202 u32QuantizedSbValue >>= s32LoopCount; 203 204 /*remove the unwanted msbs*/ 205 /*u32QuantizedSbValue <<= 16 - s32PresentBit; 206 u32QuantizedSbValue >>= 16 - s32PresentBit;*/ 207 208 Temp <<= s32PresentBit; 209 210 Temp |= u32QuantizedSbValue ; 211 /*restore the original*/ 212 u32QuantizedSbValue=u32QuantizedSbValue0; 213 214 *(pu8PacketPtr++)=Temp; 215 Temp = 0; 216 s32PresentBit = 8; 217 } 218 Temp <<= s32LoopCount; 219 220 /* remove the unwanted msbs */ 221 /*u32QuantizedSbValue <<= 16 - s32LoopCount; 222 u32QuantizedSbValue >>= 16 - s32LoopCount;*/ 223 224 Temp |= u32QuantizedSbValue; 225 226 s32PresentBit -= s32LoopCount; 227 } 228 } 229 ps16ScfPtr++; 230 ps32SbPtr++; 231 } 232 } 233 234 Temp <<= s32PresentBit; 235 *pu8PacketPtr=Temp; 236 pstrEncParams->u16PacketLength=pu8PacketPtr-pstrEncParams->pu8NextPacket+1; 237 /*find CRC*/ 238 pu8PacketPtr = pstrEncParams->pu8NextPacket+1; /*Initialize the ptr*/ 239 u8CRC = 0x0F; 240 s32LoopCount = s32Sb >> 1; 241 242 /* BK4BTSTACK_CHANGE START */ 243 if (reserved_ptr){ 244 // overwrite fixed values for mSBC before CRC calculation 245 *reserved_ptr++ = 0; 246 *reserved_ptr++ = 0; 247 } 248 /* BK4BTSTACK_CHANGE END */ 249 250 251 /* 252 The loops is run from the start of the packet till the scale factor 253 parameters. In case of JS, 'join' parameter is included in the packet 254 so that many more bytes are included in CRC calculation. 255 */ 256 Temp=*pu8PacketPtr; 257 for (s32Ch=1; s32Ch < (s32LoopCount+4); s32Ch++) 258 { 259 /* skip sync word and CRC bytes */ 260 if (s32Ch != 3) 261 { 262 for (s32LoopCountJ=7; s32LoopCountJ>=0; s32LoopCountJ--) 263 { 264 u8XoredVal = ((u8CRC >> 7) & 0x01) ^((Temp >> s32LoopCountJ) & 0x01); 265 u8CRC <<= 1; 266 u8CRC ^= (u8XoredVal * 0x1D); 267 u8CRC &= 0xFF; 268 } 269 } 270 Temp=*(++pu8PacketPtr); 271 } 272 273 if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) 274 { 275 for (s32LoopCountJ = 7; s32LoopCountJ >= (8 - s32NumOfSubBands); s32LoopCountJ--) 276 { 277 u8XoredVal = ((u8CRC >> 7) & 0x01) ^((Temp >> s32LoopCountJ) & 0x01); 278 u8CRC <<= 1; 279 u8CRC ^= (u8XoredVal * 0x1D); 280 u8CRC &= 0xFF; 281 } 282 } 283 284 /* CRC calculation ends here */ 285 286 /* store CRC in packet */ 287 pu8PacketPtr = pstrEncParams->pu8NextPacket; /*Initialize the ptr*/ 288 pu8PacketPtr += 3; 289 *pu8PacketPtr = u8CRC; 290 pstrEncParams->pu8NextPacket+=pstrEncParams->u16PacketLength; /* move the pointer to the end in case there is more than one frame to encode */ 291 } 292 293