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
EncPacking(SBC_ENC_PARAMS * pstrEncParams)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