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