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