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