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