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