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