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