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