xref: /btstack/3rd-party/bluedroid/encoder/srce/sbc_packing.c (revision b29e92f97ffd81bc8a1057634c8d1552fc963a6a)
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