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