xref: /aosp_15_r20/external/aac/libAACdec/src/block.cpp (revision e54365361535b070c2db7374cec45c159c7d0e7a)
1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker 
4*e5436536SAndroid Build Coastguard Worker © Copyright  1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
5*e5436536SAndroid Build Coastguard Worker Forschung e.V. All rights reserved.
6*e5436536SAndroid Build Coastguard Worker 
7*e5436536SAndroid Build Coastguard Worker  1.    INTRODUCTION
8*e5436536SAndroid Build Coastguard Worker The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9*e5436536SAndroid Build Coastguard Worker that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10*e5436536SAndroid Build Coastguard Worker scheme for digital audio. This FDK AAC Codec software is intended to be used on
11*e5436536SAndroid Build Coastguard Worker a wide variety of Android devices.
12*e5436536SAndroid Build Coastguard Worker 
13*e5436536SAndroid Build Coastguard Worker AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14*e5436536SAndroid Build Coastguard Worker general perceptual audio codecs. AAC-ELD is considered the best-performing
15*e5436536SAndroid Build Coastguard Worker full-bandwidth communications codec by independent studies and is widely
16*e5436536SAndroid Build Coastguard Worker deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17*e5436536SAndroid Build Coastguard Worker specifications.
18*e5436536SAndroid Build Coastguard Worker 
19*e5436536SAndroid Build Coastguard Worker Patent licenses for necessary patent claims for the FDK AAC Codec (including
20*e5436536SAndroid Build Coastguard Worker those of Fraunhofer) may be obtained through Via Licensing
21*e5436536SAndroid Build Coastguard Worker (www.vialicensing.com) or through the respective patent owners individually for
22*e5436536SAndroid Build Coastguard Worker the purpose of encoding or decoding bit streams in products that are compliant
23*e5436536SAndroid Build Coastguard Worker with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24*e5436536SAndroid Build Coastguard Worker Android devices already license these patent claims through Via Licensing or
25*e5436536SAndroid Build Coastguard Worker directly from the patent owners, and therefore FDK AAC Codec software may
26*e5436536SAndroid Build Coastguard Worker already be covered under those patent licenses when it is used for those
27*e5436536SAndroid Build Coastguard Worker licensed purposes only.
28*e5436536SAndroid Build Coastguard Worker 
29*e5436536SAndroid Build Coastguard Worker Commercially-licensed AAC software libraries, including floating-point versions
30*e5436536SAndroid Build Coastguard Worker with enhanced sound quality, are also available from Fraunhofer. Users are
31*e5436536SAndroid Build Coastguard Worker encouraged to check the Fraunhofer website for additional applications
32*e5436536SAndroid Build Coastguard Worker information and documentation.
33*e5436536SAndroid Build Coastguard Worker 
34*e5436536SAndroid Build Coastguard Worker 2.    COPYRIGHT LICENSE
35*e5436536SAndroid Build Coastguard Worker 
36*e5436536SAndroid Build Coastguard Worker Redistribution and use in source and binary forms, with or without modification,
37*e5436536SAndroid Build Coastguard Worker are permitted without payment of copyright license fees provided that you
38*e5436536SAndroid Build Coastguard Worker satisfy the following conditions:
39*e5436536SAndroid Build Coastguard Worker 
40*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in redistributions of
41*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec or your modifications thereto in source code form.
42*e5436536SAndroid Build Coastguard Worker 
43*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in the documentation
44*e5436536SAndroid Build Coastguard Worker and/or other materials provided with redistributions of the FDK AAC Codec or
45*e5436536SAndroid Build Coastguard Worker your modifications thereto in binary form. You must make available free of
46*e5436536SAndroid Build Coastguard Worker charge copies of the complete source code of the FDK AAC Codec and your
47*e5436536SAndroid Build Coastguard Worker modifications thereto to recipients of copies in binary form.
48*e5436536SAndroid Build Coastguard Worker 
49*e5436536SAndroid Build Coastguard Worker The name of Fraunhofer may not be used to endorse or promote products derived
50*e5436536SAndroid Build Coastguard Worker from this library without prior written permission.
51*e5436536SAndroid Build Coastguard Worker 
52*e5436536SAndroid Build Coastguard Worker You may not charge copyright license fees for anyone to use, copy or distribute
53*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec software or your modifications thereto.
54*e5436536SAndroid Build Coastguard Worker 
55*e5436536SAndroid Build Coastguard Worker Your modified versions of the FDK AAC Codec must carry prominent notices stating
56*e5436536SAndroid Build Coastguard Worker that you changed the software and the date of any change. For modified versions
57*e5436536SAndroid Build Coastguard Worker of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58*e5436536SAndroid Build Coastguard Worker must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59*e5436536SAndroid Build Coastguard Worker AAC Codec Library for Android."
60*e5436536SAndroid Build Coastguard Worker 
61*e5436536SAndroid Build Coastguard Worker 3.    NO PATENT LICENSE
62*e5436536SAndroid Build Coastguard Worker 
63*e5436536SAndroid Build Coastguard Worker NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64*e5436536SAndroid Build Coastguard Worker limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65*e5436536SAndroid Build Coastguard Worker Fraunhofer provides no warranty of patent non-infringement with respect to this
66*e5436536SAndroid Build Coastguard Worker software.
67*e5436536SAndroid Build Coastguard Worker 
68*e5436536SAndroid Build Coastguard Worker You may use this FDK AAC Codec software or modifications thereto only for
69*e5436536SAndroid Build Coastguard Worker purposes that are authorized by appropriate patent licenses.
70*e5436536SAndroid Build Coastguard Worker 
71*e5436536SAndroid Build Coastguard Worker 4.    DISCLAIMER
72*e5436536SAndroid Build Coastguard Worker 
73*e5436536SAndroid Build Coastguard Worker This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74*e5436536SAndroid Build Coastguard Worker holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75*e5436536SAndroid Build Coastguard Worker including but not limited to the implied warranties of merchantability and
76*e5436536SAndroid Build Coastguard Worker fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77*e5436536SAndroid Build Coastguard Worker CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78*e5436536SAndroid Build Coastguard Worker or consequential damages, including but not limited to procurement of substitute
79*e5436536SAndroid Build Coastguard Worker goods or services; loss of use, data, or profits, or business interruption,
80*e5436536SAndroid Build Coastguard Worker however caused and on any theory of liability, whether in contract, strict
81*e5436536SAndroid Build Coastguard Worker liability, or tort (including negligence), arising in any way out of the use of
82*e5436536SAndroid Build Coastguard Worker this software, even if advised of the possibility of such damage.
83*e5436536SAndroid Build Coastguard Worker 
84*e5436536SAndroid Build Coastguard Worker 5.    CONTACT INFORMATION
85*e5436536SAndroid Build Coastguard Worker 
86*e5436536SAndroid Build Coastguard Worker Fraunhofer Institute for Integrated Circuits IIS
87*e5436536SAndroid Build Coastguard Worker Attention: Audio and Multimedia Departments - FDK AAC LL
88*e5436536SAndroid Build Coastguard Worker Am Wolfsmantel 33
89*e5436536SAndroid Build Coastguard Worker 91058 Erlangen, Germany
90*e5436536SAndroid Build Coastguard Worker 
91*e5436536SAndroid Build Coastguard Worker www.iis.fraunhofer.de/amm
92*e5436536SAndroid Build Coastguard Worker [email protected]
93*e5436536SAndroid Build Coastguard Worker ----------------------------------------------------------------------------- */
94*e5436536SAndroid Build Coastguard Worker 
95*e5436536SAndroid Build Coastguard Worker /**************************** AAC decoder library ******************************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):   Josef Hoepfl
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: long/short-block decoding
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "block.h"
104*e5436536SAndroid Build Coastguard Worker 
105*e5436536SAndroid Build Coastguard Worker #include "aac_rom.h"
106*e5436536SAndroid Build Coastguard Worker #include "FDK_bitstream.h"
107*e5436536SAndroid Build Coastguard Worker #include "scale.h"
108*e5436536SAndroid Build Coastguard Worker #include "FDK_tools_rom.h"
109*e5436536SAndroid Build Coastguard Worker 
110*e5436536SAndroid Build Coastguard Worker #include "usacdec_fac.h"
111*e5436536SAndroid Build Coastguard Worker #include "usacdec_lpd.h"
112*e5436536SAndroid Build Coastguard Worker #include "usacdec_lpc.h"
113*e5436536SAndroid Build Coastguard Worker #include "FDK_trigFcts.h"
114*e5436536SAndroid Build Coastguard Worker 
115*e5436536SAndroid Build Coastguard Worker #include "ac_arith_coder.h"
116*e5436536SAndroid Build Coastguard Worker 
117*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcr.h"
118*e5436536SAndroid Build Coastguard Worker #include "rvlc.h"
119*e5436536SAndroid Build Coastguard Worker 
120*e5436536SAndroid Build Coastguard Worker #if defined(__arm__)
121*e5436536SAndroid Build Coastguard Worker #include "arm/block_arm.cpp"
122*e5436536SAndroid Build Coastguard Worker #endif
123*e5436536SAndroid Build Coastguard Worker 
124*e5436536SAndroid Build Coastguard Worker /*!
125*e5436536SAndroid Build Coastguard Worker   \brief Read escape sequence of codeword
126*e5436536SAndroid Build Coastguard Worker 
127*e5436536SAndroid Build Coastguard Worker   The function reads the escape sequence from the bitstream,
128*e5436536SAndroid Build Coastguard Worker   if the absolute value of the quantized coefficient has the
129*e5436536SAndroid Build Coastguard Worker   value 16.
130*e5436536SAndroid Build Coastguard Worker   A limitation is implemented to maximal 21 bits according to
131*e5436536SAndroid Build Coastguard Worker   ISO/IEC 14496-3:2009(E) 4.6.3.3.
132*e5436536SAndroid Build Coastguard Worker   This limits the escape prefix to a maximum of eight 1's.
133*e5436536SAndroid Build Coastguard Worker   If more than eight 1's are read, MAX_QUANTIZED_VALUE + 1 is
134*e5436536SAndroid Build Coastguard Worker   returned, independent of the sign of parameter q.
135*e5436536SAndroid Build Coastguard Worker 
136*e5436536SAndroid Build Coastguard Worker   \return  quantized coefficient
137*e5436536SAndroid Build Coastguard Worker */
CBlock_GetEscape(HANDLE_FDK_BITSTREAM bs,const LONG q)138*e5436536SAndroid Build Coastguard Worker LONG CBlock_GetEscape(HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */
139*e5436536SAndroid Build Coastguard Worker                       const LONG q)            /*!< quantized coefficient */
140*e5436536SAndroid Build Coastguard Worker {
141*e5436536SAndroid Build Coastguard Worker   if (fAbs(q) != 16) return (q);
142*e5436536SAndroid Build Coastguard Worker 
143*e5436536SAndroid Build Coastguard Worker   LONG i, off;
144*e5436536SAndroid Build Coastguard Worker   for (i = 4; i < 13; i++) {
145*e5436536SAndroid Build Coastguard Worker     if (FDKreadBit(bs) == 0) break;
146*e5436536SAndroid Build Coastguard Worker   }
147*e5436536SAndroid Build Coastguard Worker 
148*e5436536SAndroid Build Coastguard Worker   if (i == 13) return (MAX_QUANTIZED_VALUE + 1);
149*e5436536SAndroid Build Coastguard Worker 
150*e5436536SAndroid Build Coastguard Worker   off = FDKreadBits(bs, i);
151*e5436536SAndroid Build Coastguard Worker   i = off + (1 << i);
152*e5436536SAndroid Build Coastguard Worker 
153*e5436536SAndroid Build Coastguard Worker   if (q < 0) i = -i;
154*e5436536SAndroid Build Coastguard Worker 
155*e5436536SAndroid Build Coastguard Worker   return i;
156*e5436536SAndroid Build Coastguard Worker }
157*e5436536SAndroid Build Coastguard Worker 
CBlock_ReadScaleFactorData(CAacDecoderChannelInfo * pAacDecoderChannelInfo,HANDLE_FDK_BITSTREAM bs,UINT flags)158*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR CBlock_ReadScaleFactorData(
159*e5436536SAndroid Build Coastguard Worker     CAacDecoderChannelInfo *pAacDecoderChannelInfo, HANDLE_FDK_BITSTREAM bs,
160*e5436536SAndroid Build Coastguard Worker     UINT flags) {
161*e5436536SAndroid Build Coastguard Worker   int temp;
162*e5436536SAndroid Build Coastguard Worker   int band;
163*e5436536SAndroid Build Coastguard Worker   int group;
164*e5436536SAndroid Build Coastguard Worker   int position = 0; /* accu for intensity delta coding */
165*e5436536SAndroid Build Coastguard Worker   int factor = pAacDecoderChannelInfo->pDynData->RawDataInfo
166*e5436536SAndroid Build Coastguard Worker                    .GlobalGain; /* accu for scale factor delta coding */
167*e5436536SAndroid Build Coastguard Worker   UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
168*e5436536SAndroid Build Coastguard Worker   SHORT *pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
169*e5436536SAndroid Build Coastguard Worker   const CodeBookDescription *hcb = &AACcodeBookDescriptionTable[BOOKSCL];
170*e5436536SAndroid Build Coastguard Worker 
171*e5436536SAndroid Build Coastguard Worker   const USHORT(*CodeBook)[HuffmanEntries] = hcb->CodeBook;
172*e5436536SAndroid Build Coastguard Worker 
173*e5436536SAndroid Build Coastguard Worker   int ScaleFactorBandsTransmitted =
174*e5436536SAndroid Build Coastguard Worker       GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
175*e5436536SAndroid Build Coastguard Worker   for (group = 0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
176*e5436536SAndroid Build Coastguard Worker        group++) {
177*e5436536SAndroid Build Coastguard Worker     for (band = 0; band < ScaleFactorBandsTransmitted; band++) {
178*e5436536SAndroid Build Coastguard Worker       switch (pCodeBook[band]) {
179*e5436536SAndroid Build Coastguard Worker         case ZERO_HCB: /* zero book */
180*e5436536SAndroid Build Coastguard Worker           pScaleFactor[band] = 0;
181*e5436536SAndroid Build Coastguard Worker           break;
182*e5436536SAndroid Build Coastguard Worker 
183*e5436536SAndroid Build Coastguard Worker         default: /* decode scale factor */
184*e5436536SAndroid Build Coastguard Worker           if (!((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) && band == 0 &&
185*e5436536SAndroid Build Coastguard Worker                 group == 0)) {
186*e5436536SAndroid Build Coastguard Worker             temp = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
187*e5436536SAndroid Build Coastguard Worker             factor += temp - 60; /* MIDFAC 1.5 dB */
188*e5436536SAndroid Build Coastguard Worker           }
189*e5436536SAndroid Build Coastguard Worker           pScaleFactor[band] = factor - 100;
190*e5436536SAndroid Build Coastguard Worker           break;
191*e5436536SAndroid Build Coastguard Worker 
192*e5436536SAndroid Build Coastguard Worker         case INTENSITY_HCB: /* intensity steering */
193*e5436536SAndroid Build Coastguard Worker         case INTENSITY_HCB2:
194*e5436536SAndroid Build Coastguard Worker           temp = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
195*e5436536SAndroid Build Coastguard Worker           position += temp - 60;
196*e5436536SAndroid Build Coastguard Worker           pScaleFactor[band] = position - 100;
197*e5436536SAndroid Build Coastguard Worker           break;
198*e5436536SAndroid Build Coastguard Worker 
199*e5436536SAndroid Build Coastguard Worker         case NOISE_HCB: /* PNS */
200*e5436536SAndroid Build Coastguard Worker           if (flags & (AC_MPEGD_RES | AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
201*e5436536SAndroid Build Coastguard Worker             return AAC_DEC_PARSE_ERROR;
202*e5436536SAndroid Build Coastguard Worker           }
203*e5436536SAndroid Build Coastguard Worker           CPns_Read(&pAacDecoderChannelInfo->data.aac.PnsData, bs, hcb,
204*e5436536SAndroid Build Coastguard Worker                     pAacDecoderChannelInfo->pDynData->aScaleFactor,
205*e5436536SAndroid Build Coastguard Worker                     pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain,
206*e5436536SAndroid Build Coastguard Worker                     band, group);
207*e5436536SAndroid Build Coastguard Worker           break;
208*e5436536SAndroid Build Coastguard Worker       }
209*e5436536SAndroid Build Coastguard Worker     }
210*e5436536SAndroid Build Coastguard Worker     pCodeBook += 16;
211*e5436536SAndroid Build Coastguard Worker     pScaleFactor += 16;
212*e5436536SAndroid Build Coastguard Worker   }
213*e5436536SAndroid Build Coastguard Worker 
214*e5436536SAndroid Build Coastguard Worker   return AAC_DEC_OK;
215*e5436536SAndroid Build Coastguard Worker }
216*e5436536SAndroid Build Coastguard Worker 
CBlock_ScaleSpectralData(CAacDecoderChannelInfo * pAacDecoderChannelInfo,UCHAR maxSfbs,SamplingRateInfo * pSamplingRateInfo)217*e5436536SAndroid Build Coastguard Worker void CBlock_ScaleSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
218*e5436536SAndroid Build Coastguard Worker                               UCHAR maxSfbs,
219*e5436536SAndroid Build Coastguard Worker                               SamplingRateInfo *pSamplingRateInfo) {
220*e5436536SAndroid Build Coastguard Worker   int band;
221*e5436536SAndroid Build Coastguard Worker   int window;
222*e5436536SAndroid Build Coastguard Worker   const SHORT *RESTRICT pSfbScale = pAacDecoderChannelInfo->pDynData->aSfbScale;
223*e5436536SAndroid Build Coastguard Worker   SHORT *RESTRICT pSpecScale = pAacDecoderChannelInfo->specScale;
224*e5436536SAndroid Build Coastguard Worker   int groupwin, group;
225*e5436536SAndroid Build Coastguard Worker   const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(
226*e5436536SAndroid Build Coastguard Worker       &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
227*e5436536SAndroid Build Coastguard Worker   SPECTRAL_PTR RESTRICT pSpectralCoefficient =
228*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pSpectralCoefficient;
229*e5436536SAndroid Build Coastguard Worker 
230*e5436536SAndroid Build Coastguard Worker   FDKmemclear(pSpecScale, 8 * sizeof(SHORT));
231*e5436536SAndroid Build Coastguard Worker 
232*e5436536SAndroid Build Coastguard Worker   for (window = 0, group = 0;
233*e5436536SAndroid Build Coastguard Worker        group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++) {
234*e5436536SAndroid Build Coastguard Worker     for (groupwin = 0; groupwin < GetWindowGroupLength(
235*e5436536SAndroid Build Coastguard Worker                                       &pAacDecoderChannelInfo->icsInfo, group);
236*e5436536SAndroid Build Coastguard Worker          groupwin++, window++) {
237*e5436536SAndroid Build Coastguard Worker       int SpecScale_window = pSpecScale[window];
238*e5436536SAndroid Build Coastguard Worker       FIXP_DBL *pSpectrum = SPEC(pSpectralCoefficient, window,
239*e5436536SAndroid Build Coastguard Worker                                  pAacDecoderChannelInfo->granuleLength);
240*e5436536SAndroid Build Coastguard Worker 
241*e5436536SAndroid Build Coastguard Worker       /* find scaling for current window */
242*e5436536SAndroid Build Coastguard Worker       for (band = 0; band < maxSfbs; band++) {
243*e5436536SAndroid Build Coastguard Worker         SpecScale_window =
244*e5436536SAndroid Build Coastguard Worker             fMax(SpecScale_window, (int)pSfbScale[window * 16 + band]);
245*e5436536SAndroid Build Coastguard Worker       }
246*e5436536SAndroid Build Coastguard Worker 
247*e5436536SAndroid Build Coastguard Worker       if (pAacDecoderChannelInfo->pDynData->TnsData.Active &&
248*e5436536SAndroid Build Coastguard Worker           pAacDecoderChannelInfo->pDynData->TnsData.NumberOfFilters[window] >
249*e5436536SAndroid Build Coastguard Worker               0) {
250*e5436536SAndroid Build Coastguard Worker         int filter_index, SpecScale_window_tns;
251*e5436536SAndroid Build Coastguard Worker         int tns_start, tns_stop;
252*e5436536SAndroid Build Coastguard Worker 
253*e5436536SAndroid Build Coastguard Worker         /* Find max scale of TNS bands */
254*e5436536SAndroid Build Coastguard Worker         SpecScale_window_tns = 0;
255*e5436536SAndroid Build Coastguard Worker         tns_start = GetMaximumTnsBands(&pAacDecoderChannelInfo->icsInfo,
256*e5436536SAndroid Build Coastguard Worker                                        pSamplingRateInfo->samplingRateIndex);
257*e5436536SAndroid Build Coastguard Worker         tns_stop = 0;
258*e5436536SAndroid Build Coastguard Worker         for (filter_index = 0;
259*e5436536SAndroid Build Coastguard Worker              filter_index < (int)pAacDecoderChannelInfo->pDynData->TnsData
260*e5436536SAndroid Build Coastguard Worker                                 .NumberOfFilters[window];
261*e5436536SAndroid Build Coastguard Worker              filter_index++) {
262*e5436536SAndroid Build Coastguard Worker           for (band = pAacDecoderChannelInfo->pDynData->TnsData
263*e5436536SAndroid Build Coastguard Worker                           .Filter[window][filter_index]
264*e5436536SAndroid Build Coastguard Worker                           .StartBand;
265*e5436536SAndroid Build Coastguard Worker                band < pAacDecoderChannelInfo->pDynData->TnsData
266*e5436536SAndroid Build Coastguard Worker                           .Filter[window][filter_index]
267*e5436536SAndroid Build Coastguard Worker                           .StopBand;
268*e5436536SAndroid Build Coastguard Worker                band++) {
269*e5436536SAndroid Build Coastguard Worker             SpecScale_window_tns =
270*e5436536SAndroid Build Coastguard Worker                 fMax(SpecScale_window_tns, (int)pSfbScale[window * 16 + band]);
271*e5436536SAndroid Build Coastguard Worker           }
272*e5436536SAndroid Build Coastguard Worker           /* Find TNS line boundaries for all TNS filters */
273*e5436536SAndroid Build Coastguard Worker           tns_start =
274*e5436536SAndroid Build Coastguard Worker               fMin(tns_start, (int)pAacDecoderChannelInfo->pDynData->TnsData
275*e5436536SAndroid Build Coastguard Worker                                   .Filter[window][filter_index]
276*e5436536SAndroid Build Coastguard Worker                                   .StartBand);
277*e5436536SAndroid Build Coastguard Worker           tns_stop =
278*e5436536SAndroid Build Coastguard Worker               fMax(tns_stop, (int)pAacDecoderChannelInfo->pDynData->TnsData
279*e5436536SAndroid Build Coastguard Worker                                  .Filter[window][filter_index]
280*e5436536SAndroid Build Coastguard Worker                                  .StopBand);
281*e5436536SAndroid Build Coastguard Worker         }
282*e5436536SAndroid Build Coastguard Worker         SpecScale_window_tns = SpecScale_window_tns +
283*e5436536SAndroid Build Coastguard Worker                                pAacDecoderChannelInfo->pDynData->TnsData.GainLd;
284*e5436536SAndroid Build Coastguard Worker         FDK_ASSERT(tns_stop >= tns_start);
285*e5436536SAndroid Build Coastguard Worker         /* Consider existing headroom of all MDCT lines inside the TNS bands. */
286*e5436536SAndroid Build Coastguard Worker         SpecScale_window_tns -=
287*e5436536SAndroid Build Coastguard Worker             getScalefactor(pSpectrum + BandOffsets[tns_start],
288*e5436536SAndroid Build Coastguard Worker                            BandOffsets[tns_stop] - BandOffsets[tns_start]);
289*e5436536SAndroid Build Coastguard Worker         if (SpecScale_window <= 17) {
290*e5436536SAndroid Build Coastguard Worker           SpecScale_window_tns++;
291*e5436536SAndroid Build Coastguard Worker         }
292*e5436536SAndroid Build Coastguard Worker         /* Add enough mantissa head room such that the spectrum is still
293*e5436536SAndroid Build Coastguard Worker            representable after applying TNS. */
294*e5436536SAndroid Build Coastguard Worker         SpecScale_window = fMax(SpecScale_window, SpecScale_window_tns);
295*e5436536SAndroid Build Coastguard Worker       }
296*e5436536SAndroid Build Coastguard Worker 
297*e5436536SAndroid Build Coastguard Worker       /* store scaling of current window */
298*e5436536SAndroid Build Coastguard Worker       pSpecScale[window] = SpecScale_window;
299*e5436536SAndroid Build Coastguard Worker 
300*e5436536SAndroid Build Coastguard Worker #ifdef FUNCTION_CBlock_ScaleSpectralData_func1
301*e5436536SAndroid Build Coastguard Worker 
302*e5436536SAndroid Build Coastguard Worker       CBlock_ScaleSpectralData_func1(pSpectrum, maxSfbs, BandOffsets,
303*e5436536SAndroid Build Coastguard Worker                                      SpecScale_window, pSfbScale, window);
304*e5436536SAndroid Build Coastguard Worker 
305*e5436536SAndroid Build Coastguard Worker #else  /* FUNCTION_CBlock_ScaleSpectralData_func1 */
306*e5436536SAndroid Build Coastguard Worker       for (band = 0; band < maxSfbs; band++) {
307*e5436536SAndroid Build Coastguard Worker         int scale = fMin(DFRACT_BITS - 1,
308*e5436536SAndroid Build Coastguard Worker                          SpecScale_window - pSfbScale[window * 16 + band]);
309*e5436536SAndroid Build Coastguard Worker         if (scale) {
310*e5436536SAndroid Build Coastguard Worker           FDK_ASSERT(scale > 0);
311*e5436536SAndroid Build Coastguard Worker 
312*e5436536SAndroid Build Coastguard Worker           /* following relation can be used for optimizations:
313*e5436536SAndroid Build Coastguard Worker            * (BandOffsets[i]%4) == 0 for all i */
314*e5436536SAndroid Build Coastguard Worker           int max_index = BandOffsets[band + 1];
315*e5436536SAndroid Build Coastguard Worker           DWORD_ALIGNED(pSpectrum);
316*e5436536SAndroid Build Coastguard Worker           for (int index = BandOffsets[band]; index < max_index; index++) {
317*e5436536SAndroid Build Coastguard Worker             pSpectrum[index] >>= scale;
318*e5436536SAndroid Build Coastguard Worker           }
319*e5436536SAndroid Build Coastguard Worker         }
320*e5436536SAndroid Build Coastguard Worker       }
321*e5436536SAndroid Build Coastguard Worker #endif /* FUNCTION_CBlock_ScaleSpectralData_func1 */
322*e5436536SAndroid Build Coastguard Worker     }
323*e5436536SAndroid Build Coastguard Worker   }
324*e5436536SAndroid Build Coastguard Worker }
325*e5436536SAndroid Build Coastguard Worker 
CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs,CAacDecoderChannelInfo * pAacDecoderChannelInfo,const SamplingRateInfo * pSamplingRateInfo,const UINT flags)326*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR CBlock_ReadSectionData(
327*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_BITSTREAM bs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
328*e5436536SAndroid Build Coastguard Worker     const SamplingRateInfo *pSamplingRateInfo, const UINT flags) {
329*e5436536SAndroid Build Coastguard Worker   int top, band;
330*e5436536SAndroid Build Coastguard Worker   int sect_len, sect_len_incr;
331*e5436536SAndroid Build Coastguard Worker   int group;
332*e5436536SAndroid Build Coastguard Worker   UCHAR sect_cb;
333*e5436536SAndroid Build Coastguard Worker   UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
334*e5436536SAndroid Build Coastguard Worker   /* HCR input (long) */
335*e5436536SAndroid Build Coastguard Worker   SHORT *pNumLinesInSec =
336*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pDynData->specificTo.aac.aNumLineInSec4Hcr;
337*e5436536SAndroid Build Coastguard Worker   int numLinesInSecIdx = 0;
338*e5436536SAndroid Build Coastguard Worker   UCHAR *pHcrCodeBook =
339*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pDynData->specificTo.aac.aCodeBooks4Hcr;
340*e5436536SAndroid Build Coastguard Worker   const SHORT *BandOffsets = GetScaleFactorBandOffsets(
341*e5436536SAndroid Build Coastguard Worker       &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
342*e5436536SAndroid Build Coastguard Worker   pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection = 0;
343*e5436536SAndroid Build Coastguard Worker   AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
344*e5436536SAndroid Build Coastguard Worker 
345*e5436536SAndroid Build Coastguard Worker   FDKmemclear(pCodeBook, sizeof(UCHAR) * (8 * 16));
346*e5436536SAndroid Build Coastguard Worker 
347*e5436536SAndroid Build Coastguard Worker   const int nbits =
348*e5436536SAndroid Build Coastguard Worker       (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) == 1) ? 5 : 3;
349*e5436536SAndroid Build Coastguard Worker 
350*e5436536SAndroid Build Coastguard Worker   int sect_esc_val = (1 << nbits) - 1;
351*e5436536SAndroid Build Coastguard Worker 
352*e5436536SAndroid Build Coastguard Worker   UCHAR ScaleFactorBandsTransmitted =
353*e5436536SAndroid Build Coastguard Worker       GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
354*e5436536SAndroid Build Coastguard Worker   for (group = 0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
355*e5436536SAndroid Build Coastguard Worker        group++) {
356*e5436536SAndroid Build Coastguard Worker     for (band = 0; band < ScaleFactorBandsTransmitted;) {
357*e5436536SAndroid Build Coastguard Worker       sect_len = 0;
358*e5436536SAndroid Build Coastguard Worker       if (flags & AC_ER_VCB11) {
359*e5436536SAndroid Build Coastguard Worker         sect_cb = (UCHAR)FDKreadBits(bs, 5);
360*e5436536SAndroid Build Coastguard Worker       } else
361*e5436536SAndroid Build Coastguard Worker         sect_cb = (UCHAR)FDKreadBits(bs, 4);
362*e5436536SAndroid Build Coastguard Worker 
363*e5436536SAndroid Build Coastguard Worker       if (((flags & AC_ER_VCB11) == 0) || (sect_cb < 11) ||
364*e5436536SAndroid Build Coastguard Worker           ((sect_cb > 11) && (sect_cb < 16))) {
365*e5436536SAndroid Build Coastguard Worker         sect_len_incr = FDKreadBits(bs, nbits);
366*e5436536SAndroid Build Coastguard Worker         while (sect_len_incr == sect_esc_val) {
367*e5436536SAndroid Build Coastguard Worker           sect_len += sect_esc_val;
368*e5436536SAndroid Build Coastguard Worker           sect_len_incr = FDKreadBits(bs, nbits);
369*e5436536SAndroid Build Coastguard Worker         }
370*e5436536SAndroid Build Coastguard Worker       } else {
371*e5436536SAndroid Build Coastguard Worker         sect_len_incr = 1;
372*e5436536SAndroid Build Coastguard Worker       }
373*e5436536SAndroid Build Coastguard Worker 
374*e5436536SAndroid Build Coastguard Worker       sect_len += sect_len_incr;
375*e5436536SAndroid Build Coastguard Worker 
376*e5436536SAndroid Build Coastguard Worker       top = band + sect_len;
377*e5436536SAndroid Build Coastguard Worker 
378*e5436536SAndroid Build Coastguard Worker       if (flags & AC_ER_HCR) {
379*e5436536SAndroid Build Coastguard Worker         /* HCR input (long) -- collecting sideinfo (for HCR-_long_ only) */
380*e5436536SAndroid Build Coastguard Worker         if (numLinesInSecIdx >= MAX_SFB_HCR) {
381*e5436536SAndroid Build Coastguard Worker           return AAC_DEC_PARSE_ERROR;
382*e5436536SAndroid Build Coastguard Worker         }
383*e5436536SAndroid Build Coastguard Worker         if (top > (int)GetNumberOfScaleFactorBands(
384*e5436536SAndroid Build Coastguard Worker                       &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo)) {
385*e5436536SAndroid Build Coastguard Worker           return AAC_DEC_PARSE_ERROR;
386*e5436536SAndroid Build Coastguard Worker         }
387*e5436536SAndroid Build Coastguard Worker         pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
388*e5436536SAndroid Build Coastguard Worker         numLinesInSecIdx++;
389*e5436536SAndroid Build Coastguard Worker         if (sect_cb == BOOKSCL) {
390*e5436536SAndroid Build Coastguard Worker           return AAC_DEC_INVALID_CODE_BOOK;
391*e5436536SAndroid Build Coastguard Worker         } else {
392*e5436536SAndroid Build Coastguard Worker           *pHcrCodeBook++ = sect_cb;
393*e5436536SAndroid Build Coastguard Worker         }
394*e5436536SAndroid Build Coastguard Worker         pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection++;
395*e5436536SAndroid Build Coastguard Worker       }
396*e5436536SAndroid Build Coastguard Worker 
397*e5436536SAndroid Build Coastguard Worker       /* Check spectral line limits */
398*e5436536SAndroid Build Coastguard Worker       if (IsLongBlock(&(pAacDecoderChannelInfo->icsInfo))) {
399*e5436536SAndroid Build Coastguard Worker         if (top > 64) {
400*e5436536SAndroid Build Coastguard Worker           return AAC_DEC_DECODE_FRAME_ERROR;
401*e5436536SAndroid Build Coastguard Worker         }
402*e5436536SAndroid Build Coastguard Worker       } else { /* short block */
403*e5436536SAndroid Build Coastguard Worker         if (top + group * 16 > (8 * 16)) {
404*e5436536SAndroid Build Coastguard Worker           return AAC_DEC_DECODE_FRAME_ERROR;
405*e5436536SAndroid Build Coastguard Worker         }
406*e5436536SAndroid Build Coastguard Worker       }
407*e5436536SAndroid Build Coastguard Worker 
408*e5436536SAndroid Build Coastguard Worker       /* Check if decoded codebook index is feasible */
409*e5436536SAndroid Build Coastguard Worker       if ((sect_cb == BOOKSCL) ||
410*e5436536SAndroid Build Coastguard Worker           ((sect_cb == INTENSITY_HCB || sect_cb == INTENSITY_HCB2) &&
411*e5436536SAndroid Build Coastguard Worker            pAacDecoderChannelInfo->pDynData->RawDataInfo.CommonWindow == 0)) {
412*e5436536SAndroid Build Coastguard Worker         return AAC_DEC_INVALID_CODE_BOOK;
413*e5436536SAndroid Build Coastguard Worker       }
414*e5436536SAndroid Build Coastguard Worker 
415*e5436536SAndroid Build Coastguard Worker       /* Store codebook index */
416*e5436536SAndroid Build Coastguard Worker       for (; band < top; band++) {
417*e5436536SAndroid Build Coastguard Worker         pCodeBook[group * 16 + band] = sect_cb;
418*e5436536SAndroid Build Coastguard Worker       }
419*e5436536SAndroid Build Coastguard Worker     }
420*e5436536SAndroid Build Coastguard Worker   }
421*e5436536SAndroid Build Coastguard Worker 
422*e5436536SAndroid Build Coastguard Worker   return ErrorStatus;
423*e5436536SAndroid Build Coastguard Worker }
424*e5436536SAndroid Build Coastguard Worker 
425*e5436536SAndroid Build Coastguard Worker /* mso: provides a faster way to i-quantize a whole band in one go */
426*e5436536SAndroid Build Coastguard Worker 
427*e5436536SAndroid Build Coastguard Worker /**
428*e5436536SAndroid Build Coastguard Worker  * \brief inverse quantize one sfb. Each value of the sfb is processed according
429*e5436536SAndroid Build Coastguard Worker  * to the formula: spectrum[i] = Sign(spectrum[i]) * Matissa(spectrum[i])^(4/3)
430*e5436536SAndroid Build Coastguard Worker  * * 2^(lsb/4).
431*e5436536SAndroid Build Coastguard Worker  * \param spectrum pointer to first line of the sfb to be inverse quantized.
432*e5436536SAndroid Build Coastguard Worker  * \param noLines number of lines belonging to the sfb.
433*e5436536SAndroid Build Coastguard Worker  * \param lsb last 2 bits of the scale factor of the sfb.
434*e5436536SAndroid Build Coastguard Worker  * \param scale max allowed shift scale for the sfb.
435*e5436536SAndroid Build Coastguard Worker  */
InverseQuantizeBand(FIXP_DBL * RESTRICT spectrum,const FIXP_DBL * RESTRICT InverseQuantTabler,const FIXP_DBL * RESTRICT MantissaTabler,const SCHAR * RESTRICT ExponentTabler,INT noLines,INT scale)436*e5436536SAndroid Build Coastguard Worker static inline void InverseQuantizeBand(
437*e5436536SAndroid Build Coastguard Worker     FIXP_DBL *RESTRICT spectrum, const FIXP_DBL *RESTRICT InverseQuantTabler,
438*e5436536SAndroid Build Coastguard Worker     const FIXP_DBL *RESTRICT MantissaTabler,
439*e5436536SAndroid Build Coastguard Worker     const SCHAR *RESTRICT ExponentTabler, INT noLines, INT scale) {
440*e5436536SAndroid Build Coastguard Worker   scale = scale + 1; /* +1 to compensate fMultDiv2 shift-right in loop */
441*e5436536SAndroid Build Coastguard Worker 
442*e5436536SAndroid Build Coastguard Worker   FIXP_DBL *RESTRICT ptr = spectrum;
443*e5436536SAndroid Build Coastguard Worker   FIXP_DBL signedValue;
444*e5436536SAndroid Build Coastguard Worker 
445*e5436536SAndroid Build Coastguard Worker   for (INT i = noLines; i--;) {
446*e5436536SAndroid Build Coastguard Worker     if ((signedValue = *ptr++) != FL2FXCONST_DBL(0)) {
447*e5436536SAndroid Build Coastguard Worker       FIXP_DBL value = fAbs(signedValue);
448*e5436536SAndroid Build Coastguard Worker       UINT freeBits = CntLeadingZeros(value);
449*e5436536SAndroid Build Coastguard Worker       UINT exponent = 32 - freeBits;
450*e5436536SAndroid Build Coastguard Worker 
451*e5436536SAndroid Build Coastguard Worker       UINT x = (UINT)(LONG)value << (INT)freeBits;
452*e5436536SAndroid Build Coastguard Worker       x <<= 1; /* shift out sign bit to avoid masking later on */
453*e5436536SAndroid Build Coastguard Worker       UINT tableIndex = x >> 24;
454*e5436536SAndroid Build Coastguard Worker       x = (x >> 20) & 0x0F;
455*e5436536SAndroid Build Coastguard Worker 
456*e5436536SAndroid Build Coastguard Worker       UINT r0 = (UINT)(LONG)InverseQuantTabler[tableIndex + 0];
457*e5436536SAndroid Build Coastguard Worker       UINT r1 = (UINT)(LONG)InverseQuantTabler[tableIndex + 1];
458*e5436536SAndroid Build Coastguard Worker       UINT temp = (r1 - r0) * x + (r0 << 4);
459*e5436536SAndroid Build Coastguard Worker 
460*e5436536SAndroid Build Coastguard Worker       value = fMultDiv2((FIXP_DBL)temp, MantissaTabler[exponent]);
461*e5436536SAndroid Build Coastguard Worker 
462*e5436536SAndroid Build Coastguard Worker       /* + 1 compensates fMultDiv2() */
463*e5436536SAndroid Build Coastguard Worker       scaleValueInPlace(&value, scale + ExponentTabler[exponent]);
464*e5436536SAndroid Build Coastguard Worker 
465*e5436536SAndroid Build Coastguard Worker       signedValue = (signedValue < (FIXP_DBL)0) ? -value : value;
466*e5436536SAndroid Build Coastguard Worker       ptr[-1] = signedValue;
467*e5436536SAndroid Build Coastguard Worker     }
468*e5436536SAndroid Build Coastguard Worker   }
469*e5436536SAndroid Build Coastguard Worker }
470*e5436536SAndroid Build Coastguard Worker 
maxabs_D(const FIXP_DBL * pSpectralCoefficient,const int noLines)471*e5436536SAndroid Build Coastguard Worker static inline FIXP_DBL maxabs_D(const FIXP_DBL *pSpectralCoefficient,
472*e5436536SAndroid Build Coastguard Worker                                 const int noLines) {
473*e5436536SAndroid Build Coastguard Worker   /* Find max spectral line value of the current sfb */
474*e5436536SAndroid Build Coastguard Worker   FIXP_DBL locMax = (FIXP_DBL)0;
475*e5436536SAndroid Build Coastguard Worker   int i;
476*e5436536SAndroid Build Coastguard Worker 
477*e5436536SAndroid Build Coastguard Worker   DWORD_ALIGNED(pSpectralCoefficient);
478*e5436536SAndroid Build Coastguard Worker 
479*e5436536SAndroid Build Coastguard Worker   for (i = noLines; i-- > 0;) {
480*e5436536SAndroid Build Coastguard Worker     /* Expensive memory access */
481*e5436536SAndroid Build Coastguard Worker     locMax = fMax(fixp_abs(pSpectralCoefficient[i]), locMax);
482*e5436536SAndroid Build Coastguard Worker   }
483*e5436536SAndroid Build Coastguard Worker 
484*e5436536SAndroid Build Coastguard Worker   return locMax;
485*e5436536SAndroid Build Coastguard Worker }
486*e5436536SAndroid Build Coastguard Worker 
CBlock_InverseQuantizeSpectralData(CAacDecoderChannelInfo * pAacDecoderChannelInfo,SamplingRateInfo * pSamplingRateInfo,UCHAR * band_is_noise,UCHAR active_band_search)487*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(
488*e5436536SAndroid Build Coastguard Worker     CAacDecoderChannelInfo *pAacDecoderChannelInfo,
489*e5436536SAndroid Build Coastguard Worker     SamplingRateInfo *pSamplingRateInfo, UCHAR *band_is_noise,
490*e5436536SAndroid Build Coastguard Worker     UCHAR active_band_search) {
491*e5436536SAndroid Build Coastguard Worker   int window, group, groupwin, band;
492*e5436536SAndroid Build Coastguard Worker   int ScaleFactorBandsTransmitted =
493*e5436536SAndroid Build Coastguard Worker       GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
494*e5436536SAndroid Build Coastguard Worker   UCHAR *RESTRICT pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
495*e5436536SAndroid Build Coastguard Worker   SHORT *RESTRICT pSfbScale = pAacDecoderChannelInfo->pDynData->aSfbScale;
496*e5436536SAndroid Build Coastguard Worker   SHORT *RESTRICT pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
497*e5436536SAndroid Build Coastguard Worker   const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(
498*e5436536SAndroid Build Coastguard Worker       &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
499*e5436536SAndroid Build Coastguard Worker   const SHORT total_bands =
500*e5436536SAndroid Build Coastguard Worker       GetScaleFactorBandsTotal(&pAacDecoderChannelInfo->icsInfo);
501*e5436536SAndroid Build Coastguard Worker 
502*e5436536SAndroid Build Coastguard Worker   FDKmemclear(pAacDecoderChannelInfo->pDynData->aSfbScale,
503*e5436536SAndroid Build Coastguard Worker               (8 * 16) * sizeof(SHORT));
504*e5436536SAndroid Build Coastguard Worker 
505*e5436536SAndroid Build Coastguard Worker   for (window = 0, group = 0;
506*e5436536SAndroid Build Coastguard Worker        group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++) {
507*e5436536SAndroid Build Coastguard Worker     for (groupwin = 0; groupwin < GetWindowGroupLength(
508*e5436536SAndroid Build Coastguard Worker                                       &pAacDecoderChannelInfo->icsInfo, group);
509*e5436536SAndroid Build Coastguard Worker          groupwin++, window++) {
510*e5436536SAndroid Build Coastguard Worker       /* inverse quantization */
511*e5436536SAndroid Build Coastguard Worker       for (band = 0; band < ScaleFactorBandsTransmitted; band++) {
512*e5436536SAndroid Build Coastguard Worker         FIXP_DBL *pSpectralCoefficient =
513*e5436536SAndroid Build Coastguard Worker             SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, window,
514*e5436536SAndroid Build Coastguard Worker                  pAacDecoderChannelInfo->granuleLength) +
515*e5436536SAndroid Build Coastguard Worker             BandOffsets[band];
516*e5436536SAndroid Build Coastguard Worker         FIXP_DBL locMax;
517*e5436536SAndroid Build Coastguard Worker 
518*e5436536SAndroid Build Coastguard Worker         const int noLines = BandOffsets[band + 1] - BandOffsets[band];
519*e5436536SAndroid Build Coastguard Worker         const int bnds = group * 16 + band;
520*e5436536SAndroid Build Coastguard Worker 
521*e5436536SAndroid Build Coastguard Worker         if ((pCodeBook[bnds] == ZERO_HCB) ||
522*e5436536SAndroid Build Coastguard Worker             (pCodeBook[bnds] == INTENSITY_HCB) ||
523*e5436536SAndroid Build Coastguard Worker             (pCodeBook[bnds] == INTENSITY_HCB2))
524*e5436536SAndroid Build Coastguard Worker           continue;
525*e5436536SAndroid Build Coastguard Worker 
526*e5436536SAndroid Build Coastguard Worker         if (pCodeBook[bnds] == NOISE_HCB) {
527*e5436536SAndroid Build Coastguard Worker           /* Leave headroom for PNS values. + 1 because ceil(log2(2^(0.25*3))) =
528*e5436536SAndroid Build Coastguard Worker              1, worst case of additional headroom required because of the
529*e5436536SAndroid Build Coastguard Worker              scalefactor. */
530*e5436536SAndroid Build Coastguard Worker           pSfbScale[window * 16 + band] = (pScaleFactor[bnds] >> 2) + 1;
531*e5436536SAndroid Build Coastguard Worker           continue;
532*e5436536SAndroid Build Coastguard Worker         }
533*e5436536SAndroid Build Coastguard Worker 
534*e5436536SAndroid Build Coastguard Worker         locMax = maxabs_D(pSpectralCoefficient, noLines);
535*e5436536SAndroid Build Coastguard Worker 
536*e5436536SAndroid Build Coastguard Worker         if (active_band_search) {
537*e5436536SAndroid Build Coastguard Worker           if (locMax != FIXP_DBL(0)) {
538*e5436536SAndroid Build Coastguard Worker             band_is_noise[group * 16 + band] = 0;
539*e5436536SAndroid Build Coastguard Worker           }
540*e5436536SAndroid Build Coastguard Worker         }
541*e5436536SAndroid Build Coastguard Worker 
542*e5436536SAndroid Build Coastguard Worker         /* Cheap robustness improvement - Do not remove!!! */
543*e5436536SAndroid Build Coastguard Worker         if (fixp_abs(locMax) > (FIXP_DBL)MAX_QUANTIZED_VALUE) {
544*e5436536SAndroid Build Coastguard Worker           return AAC_DEC_PARSE_ERROR;
545*e5436536SAndroid Build Coastguard Worker         }
546*e5436536SAndroid Build Coastguard Worker 
547*e5436536SAndroid Build Coastguard Worker         /* Added by Youliy Ninov:
548*e5436536SAndroid Build Coastguard Worker         The inverse quantization operation is given by (ISO/IEC 14496-3:2009(E))
549*e5436536SAndroid Build Coastguard Worker         by:
550*e5436536SAndroid Build Coastguard Worker 
551*e5436536SAndroid Build Coastguard Worker         x_invquant=Sign(x_quant). abs(x_quant)^(4/3)
552*e5436536SAndroid Build Coastguard Worker 
553*e5436536SAndroid Build Coastguard Worker         We apply a gain, derived from the scale factor for the particular sfb,
554*e5436536SAndroid Build Coastguard Worker         according to the following function:
555*e5436536SAndroid Build Coastguard Worker 
556*e5436536SAndroid Build Coastguard Worker         gain=2^(0.25*ScaleFactor)
557*e5436536SAndroid Build Coastguard Worker 
558*e5436536SAndroid Build Coastguard Worker         So, after scaling we have:
559*e5436536SAndroid Build Coastguard Worker 
560*e5436536SAndroid Build Coastguard Worker         x_rescale=gain*x_invquant=Sign(x_quant)*2^(0.25*ScaleFactor)*abs(s_quant)^(4/3)
561*e5436536SAndroid Build Coastguard Worker 
562*e5436536SAndroid Build Coastguard Worker         We could represent the ScaleFactor as:
563*e5436536SAndroid Build Coastguard Worker 
564*e5436536SAndroid Build Coastguard Worker         ScaleFactor= (ScaleFactor >> 2)*4 + ScaleFactor %4
565*e5436536SAndroid Build Coastguard Worker 
566*e5436536SAndroid Build Coastguard Worker         When we substitute it we get:
567*e5436536SAndroid Build Coastguard Worker 
568*e5436536SAndroid Build Coastguard Worker         x_rescale=Sign(x_quant)*2^(ScaleFactor>>2)* (
569*e5436536SAndroid Build Coastguard Worker         2^(0.25*(ScaleFactor%4))*abs(s_quant)^(4/3))
570*e5436536SAndroid Build Coastguard Worker 
571*e5436536SAndroid Build Coastguard Worker         When we set: msb=(ScaleFactor>>2) and lsb=(ScaleFactor%4), we obtain:
572*e5436536SAndroid Build Coastguard Worker 
573*e5436536SAndroid Build Coastguard Worker         x_rescale=Sign(x_quant)*(2^msb)* ( 2^(lsb/4)*abs(s_quant)^(4/3))
574*e5436536SAndroid Build Coastguard Worker 
575*e5436536SAndroid Build Coastguard Worker         The rescaled output can be represented by:
576*e5436536SAndroid Build Coastguard Worker            mantissa : Sign(x_quant)*( 2^(lsb/4)*abs(s_quant)^(4/3))
577*e5436536SAndroid Build Coastguard Worker            exponent :(2^msb)
578*e5436536SAndroid Build Coastguard Worker 
579*e5436536SAndroid Build Coastguard Worker         */
580*e5436536SAndroid Build Coastguard Worker 
581*e5436536SAndroid Build Coastguard Worker         int msb = pScaleFactor[bnds] >> 2;
582*e5436536SAndroid Build Coastguard Worker 
583*e5436536SAndroid Build Coastguard Worker         /* Inverse quantize band only if it is not empty */
584*e5436536SAndroid Build Coastguard Worker         if (locMax != FIXP_DBL(0)) {
585*e5436536SAndroid Build Coastguard Worker           int lsb = pScaleFactor[bnds] & 0x03;
586*e5436536SAndroid Build Coastguard Worker 
587*e5436536SAndroid Build Coastguard Worker           int scale = EvaluatePower43(&locMax, lsb);
588*e5436536SAndroid Build Coastguard Worker 
589*e5436536SAndroid Build Coastguard Worker           scale = CntLeadingZeros(locMax) - scale - 2;
590*e5436536SAndroid Build Coastguard Worker 
591*e5436536SAndroid Build Coastguard Worker           pSfbScale[window * 16 + band] = msb - scale;
592*e5436536SAndroid Build Coastguard Worker           InverseQuantizeBand(pSpectralCoefficient, InverseQuantTable,
593*e5436536SAndroid Build Coastguard Worker                               MantissaTable[lsb], ExponentTable[lsb], noLines,
594*e5436536SAndroid Build Coastguard Worker                               scale);
595*e5436536SAndroid Build Coastguard Worker         } else {
596*e5436536SAndroid Build Coastguard Worker           pSfbScale[window * 16 + band] = msb;
597*e5436536SAndroid Build Coastguard Worker         }
598*e5436536SAndroid Build Coastguard Worker 
599*e5436536SAndroid Build Coastguard Worker       } /* for (band=0; band < ScaleFactorBandsTransmitted; band++) */
600*e5436536SAndroid Build Coastguard Worker 
601*e5436536SAndroid Build Coastguard Worker       /* Make sure the array is cleared to the end */
602*e5436536SAndroid Build Coastguard Worker       SHORT start_clear = BandOffsets[ScaleFactorBandsTransmitted];
603*e5436536SAndroid Build Coastguard Worker       SHORT end_clear = BandOffsets[total_bands];
604*e5436536SAndroid Build Coastguard Worker       int diff_clear = (int)(end_clear - start_clear);
605*e5436536SAndroid Build Coastguard Worker       FIXP_DBL *pSpectralCoefficient =
606*e5436536SAndroid Build Coastguard Worker           SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, window,
607*e5436536SAndroid Build Coastguard Worker                pAacDecoderChannelInfo->granuleLength) +
608*e5436536SAndroid Build Coastguard Worker           start_clear;
609*e5436536SAndroid Build Coastguard Worker       FDKmemclear(pSpectralCoefficient, diff_clear * sizeof(FIXP_DBL));
610*e5436536SAndroid Build Coastguard Worker 
611*e5436536SAndroid Build Coastguard Worker     } /* for (groupwin=0; groupwin <
612*e5436536SAndroid Build Coastguard Worker          GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group);
613*e5436536SAndroid Build Coastguard Worker          groupwin++, window++) */
614*e5436536SAndroid Build Coastguard Worker   }   /* for (window=0, group=0; group <
615*e5436536SAndroid Build Coastguard Worker          GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)*/
616*e5436536SAndroid Build Coastguard Worker 
617*e5436536SAndroid Build Coastguard Worker   return AAC_DEC_OK;
618*e5436536SAndroid Build Coastguard Worker }
619*e5436536SAndroid Build Coastguard Worker 
CBlock_ReadSpectralData(HANDLE_FDK_BITSTREAM bs,CAacDecoderChannelInfo * pAacDecoderChannelInfo,const SamplingRateInfo * pSamplingRateInfo,const UINT flags)620*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR CBlock_ReadSpectralData(
621*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_BITSTREAM bs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
622*e5436536SAndroid Build Coastguard Worker     const SamplingRateInfo *pSamplingRateInfo, const UINT flags) {
623*e5436536SAndroid Build Coastguard Worker   int index, i;
624*e5436536SAndroid Build Coastguard Worker   const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(
625*e5436536SAndroid Build Coastguard Worker       &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
626*e5436536SAndroid Build Coastguard Worker 
627*e5436536SAndroid Build Coastguard Worker   SPECTRAL_PTR pSpectralCoefficient =
628*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pSpectralCoefficient;
629*e5436536SAndroid Build Coastguard Worker 
630*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(BandOffsets != NULL);
631*e5436536SAndroid Build Coastguard Worker 
632*e5436536SAndroid Build Coastguard Worker   FDKmemclear(pSpectralCoefficient, sizeof(SPECTRUM));
633*e5436536SAndroid Build Coastguard Worker 
634*e5436536SAndroid Build Coastguard Worker   if ((flags & AC_ER_HCR) == 0) {
635*e5436536SAndroid Build Coastguard Worker     int group;
636*e5436536SAndroid Build Coastguard Worker     int groupoffset;
637*e5436536SAndroid Build Coastguard Worker     UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
638*e5436536SAndroid Build Coastguard Worker     int ScaleFactorBandsTransmitted =
639*e5436536SAndroid Build Coastguard Worker         GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
640*e5436536SAndroid Build Coastguard Worker     int granuleLength = pAacDecoderChannelInfo->granuleLength;
641*e5436536SAndroid Build Coastguard Worker 
642*e5436536SAndroid Build Coastguard Worker     groupoffset = 0;
643*e5436536SAndroid Build Coastguard Worker 
644*e5436536SAndroid Build Coastguard Worker     /* plain huffman decoder  short */
645*e5436536SAndroid Build Coastguard Worker     int max_group = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
646*e5436536SAndroid Build Coastguard Worker 
647*e5436536SAndroid Build Coastguard Worker     for (group = 0; group < max_group; group++) {
648*e5436536SAndroid Build Coastguard Worker       int max_groupwin =
649*e5436536SAndroid Build Coastguard Worker           GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
650*e5436536SAndroid Build Coastguard Worker       int band;
651*e5436536SAndroid Build Coastguard Worker 
652*e5436536SAndroid Build Coastguard Worker       int bnds = group * 16;
653*e5436536SAndroid Build Coastguard Worker 
654*e5436536SAndroid Build Coastguard Worker       int bandOffset1 = BandOffsets[0];
655*e5436536SAndroid Build Coastguard Worker       for (band = 0; band < ScaleFactorBandsTransmitted; band++, bnds++) {
656*e5436536SAndroid Build Coastguard Worker         UCHAR currentCB = pCodeBook[bnds];
657*e5436536SAndroid Build Coastguard Worker         int bandOffset0 = bandOffset1;
658*e5436536SAndroid Build Coastguard Worker         bandOffset1 = BandOffsets[band + 1];
659*e5436536SAndroid Build Coastguard Worker 
660*e5436536SAndroid Build Coastguard Worker         /* patch to run plain-huffman-decoder with vcb11 input codebooks
661*e5436536SAndroid Build Coastguard Worker          * (LAV-checking might be possible below using the virtual cb and a
662*e5436536SAndroid Build Coastguard Worker          * LAV-table) */
663*e5436536SAndroid Build Coastguard Worker         if ((currentCB >= 16) && (currentCB <= 31)) {
664*e5436536SAndroid Build Coastguard Worker           pCodeBook[bnds] = currentCB = 11;
665*e5436536SAndroid Build Coastguard Worker         }
666*e5436536SAndroid Build Coastguard Worker         if (((currentCB != ZERO_HCB) && (currentCB != NOISE_HCB) &&
667*e5436536SAndroid Build Coastguard Worker              (currentCB != INTENSITY_HCB) && (currentCB != INTENSITY_HCB2))) {
668*e5436536SAndroid Build Coastguard Worker           const CodeBookDescription *hcb =
669*e5436536SAndroid Build Coastguard Worker               &AACcodeBookDescriptionTable[currentCB];
670*e5436536SAndroid Build Coastguard Worker           int step = hcb->Dimension;
671*e5436536SAndroid Build Coastguard Worker           int offset = hcb->Offset;
672*e5436536SAndroid Build Coastguard Worker           int bits = hcb->numBits;
673*e5436536SAndroid Build Coastguard Worker           int mask = (1 << bits) - 1;
674*e5436536SAndroid Build Coastguard Worker           const USHORT(*CodeBook)[HuffmanEntries] = hcb->CodeBook;
675*e5436536SAndroid Build Coastguard Worker           int groupwin;
676*e5436536SAndroid Build Coastguard Worker 
677*e5436536SAndroid Build Coastguard Worker           FIXP_DBL *mdctSpectrum =
678*e5436536SAndroid Build Coastguard Worker               &pSpectralCoefficient[groupoffset * granuleLength];
679*e5436536SAndroid Build Coastguard Worker 
680*e5436536SAndroid Build Coastguard Worker           if (offset == 0) {
681*e5436536SAndroid Build Coastguard Worker             for (groupwin = 0; groupwin < max_groupwin; groupwin++) {
682*e5436536SAndroid Build Coastguard Worker               for (index = bandOffset0; index < bandOffset1; index += step) {
683*e5436536SAndroid Build Coastguard Worker                 int idx = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
684*e5436536SAndroid Build Coastguard Worker                 for (i = 0; i < step; i++, idx >>= bits) {
685*e5436536SAndroid Build Coastguard Worker                   FIXP_DBL tmp = (FIXP_DBL)((idx & mask) - offset);
686*e5436536SAndroid Build Coastguard Worker                   if (tmp != FIXP_DBL(0)) tmp = (FDKreadBit(bs)) ? -tmp : tmp;
687*e5436536SAndroid Build Coastguard Worker                   mdctSpectrum[index + i] = tmp;
688*e5436536SAndroid Build Coastguard Worker                 }
689*e5436536SAndroid Build Coastguard Worker 
690*e5436536SAndroid Build Coastguard Worker                 if (currentCB == ESCBOOK) {
691*e5436536SAndroid Build Coastguard Worker                   for (int j = 0; j < 2; j++)
692*e5436536SAndroid Build Coastguard Worker                     mdctSpectrum[index + j] = (FIXP_DBL)CBlock_GetEscape(
693*e5436536SAndroid Build Coastguard Worker                         bs, (LONG)mdctSpectrum[index + j]);
694*e5436536SAndroid Build Coastguard Worker                 }
695*e5436536SAndroid Build Coastguard Worker               }
696*e5436536SAndroid Build Coastguard Worker               mdctSpectrum += granuleLength;
697*e5436536SAndroid Build Coastguard Worker             }
698*e5436536SAndroid Build Coastguard Worker           } else {
699*e5436536SAndroid Build Coastguard Worker             for (groupwin = 0; groupwin < max_groupwin; groupwin++) {
700*e5436536SAndroid Build Coastguard Worker               for (index = bandOffset0; index < bandOffset1; index += step) {
701*e5436536SAndroid Build Coastguard Worker                 int idx = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
702*e5436536SAndroid Build Coastguard Worker                 for (i = 0; i < step; i++, idx >>= bits) {
703*e5436536SAndroid Build Coastguard Worker                   mdctSpectrum[index + i] = (FIXP_DBL)((idx & mask) - offset);
704*e5436536SAndroid Build Coastguard Worker                 }
705*e5436536SAndroid Build Coastguard Worker                 if (currentCB == ESCBOOK) {
706*e5436536SAndroid Build Coastguard Worker                   for (int j = 0; j < 2; j++)
707*e5436536SAndroid Build Coastguard Worker                     mdctSpectrum[index + j] = (FIXP_DBL)CBlock_GetEscape(
708*e5436536SAndroid Build Coastguard Worker                         bs, (LONG)mdctSpectrum[index + j]);
709*e5436536SAndroid Build Coastguard Worker                 }
710*e5436536SAndroid Build Coastguard Worker               }
711*e5436536SAndroid Build Coastguard Worker               mdctSpectrum += granuleLength;
712*e5436536SAndroid Build Coastguard Worker             }
713*e5436536SAndroid Build Coastguard Worker           }
714*e5436536SAndroid Build Coastguard Worker         }
715*e5436536SAndroid Build Coastguard Worker       }
716*e5436536SAndroid Build Coastguard Worker       groupoffset += max_groupwin;
717*e5436536SAndroid Build Coastguard Worker     }
718*e5436536SAndroid Build Coastguard Worker     /* plain huffman decoding (short) finished */
719*e5436536SAndroid Build Coastguard Worker   }
720*e5436536SAndroid Build Coastguard Worker 
721*e5436536SAndroid Build Coastguard Worker   /* HCR - Huffman Codeword Reordering  short */
722*e5436536SAndroid Build Coastguard Worker   else /* if ( flags & AC_ER_HCR ) */
723*e5436536SAndroid Build Coastguard Worker 
724*e5436536SAndroid Build Coastguard Worker   {
725*e5436536SAndroid Build Coastguard Worker     H_HCR_INFO hHcr = &pAacDecoderChannelInfo->pComData->overlay.aac.erHcrInfo;
726*e5436536SAndroid Build Coastguard Worker 
727*e5436536SAndroid Build Coastguard Worker     int hcrStatus = 0;
728*e5436536SAndroid Build Coastguard Worker 
729*e5436536SAndroid Build Coastguard Worker     /* advanced Huffman decoding starts here (HCR decoding :) */
730*e5436536SAndroid Build Coastguard Worker     if (pAacDecoderChannelInfo->pDynData->specificTo.aac
731*e5436536SAndroid Build Coastguard Worker             .lenOfReorderedSpectralData != 0) {
732*e5436536SAndroid Build Coastguard Worker       /* HCR initialization short */
733*e5436536SAndroid Build Coastguard Worker       hcrStatus = HcrInit(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);
734*e5436536SAndroid Build Coastguard Worker 
735*e5436536SAndroid Build Coastguard Worker       if (hcrStatus != 0) {
736*e5436536SAndroid Build Coastguard Worker         return AAC_DEC_DECODE_FRAME_ERROR;
737*e5436536SAndroid Build Coastguard Worker       }
738*e5436536SAndroid Build Coastguard Worker 
739*e5436536SAndroid Build Coastguard Worker       /* HCR decoding short */
740*e5436536SAndroid Build Coastguard Worker       hcrStatus =
741*e5436536SAndroid Build Coastguard Worker           HcrDecoder(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);
742*e5436536SAndroid Build Coastguard Worker 
743*e5436536SAndroid Build Coastguard Worker       if (hcrStatus != 0) {
744*e5436536SAndroid Build Coastguard Worker #if HCR_ERROR_CONCEALMENT
745*e5436536SAndroid Build Coastguard Worker         HcrMuteErroneousLines(hHcr);
746*e5436536SAndroid Build Coastguard Worker #else
747*e5436536SAndroid Build Coastguard Worker         return AAC_DEC_DECODE_FRAME_ERROR;
748*e5436536SAndroid Build Coastguard Worker #endif /* HCR_ERROR_CONCEALMENT */
749*e5436536SAndroid Build Coastguard Worker       }
750*e5436536SAndroid Build Coastguard Worker 
751*e5436536SAndroid Build Coastguard Worker       FDKpushFor(bs, pAacDecoderChannelInfo->pDynData->specificTo.aac
752*e5436536SAndroid Build Coastguard Worker                          .lenOfReorderedSpectralData);
753*e5436536SAndroid Build Coastguard Worker     }
754*e5436536SAndroid Build Coastguard Worker   }
755*e5436536SAndroid Build Coastguard Worker   /* HCR - Huffman Codeword Reordering short finished */
756*e5436536SAndroid Build Coastguard Worker 
757*e5436536SAndroid Build Coastguard Worker   if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) &&
758*e5436536SAndroid Build Coastguard Worker       !(flags & (AC_ELD | AC_SCALABLE))) {
759*e5436536SAndroid Build Coastguard Worker     /* apply pulse data */
760*e5436536SAndroid Build Coastguard Worker     CPulseData_Apply(
761*e5436536SAndroid Build Coastguard Worker         &pAacDecoderChannelInfo->pDynData->specificTo.aac.PulseData,
762*e5436536SAndroid Build Coastguard Worker         GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo,
763*e5436536SAndroid Build Coastguard Worker                                   pSamplingRateInfo),
764*e5436536SAndroid Build Coastguard Worker         SPEC_LONG(pSpectralCoefficient));
765*e5436536SAndroid Build Coastguard Worker   }
766*e5436536SAndroid Build Coastguard Worker 
767*e5436536SAndroid Build Coastguard Worker   return AAC_DEC_OK;
768*e5436536SAndroid Build Coastguard Worker }
769*e5436536SAndroid Build Coastguard Worker 
770*e5436536SAndroid Build Coastguard Worker static const FIXP_SGL noise_level_tab[8] = {
771*e5436536SAndroid Build Coastguard Worker     /* FDKpow(2, (float)(noise_level-14)/3.0f) * 2; (*2 to compensate for
772*e5436536SAndroid Build Coastguard Worker        fMultDiv2) noise_level_tab(noise_level==0) == 0 by definition
773*e5436536SAndroid Build Coastguard Worker     */
774*e5436536SAndroid Build Coastguard Worker     FX_DBL2FXCONST_SGL(0x00000000 /*0x0a145173*/),
775*e5436536SAndroid Build Coastguard Worker     FX_DBL2FXCONST_SGL(0x0cb2ff5e),
776*e5436536SAndroid Build Coastguard Worker     FX_DBL2FXCONST_SGL(0x10000000),
777*e5436536SAndroid Build Coastguard Worker     FX_DBL2FXCONST_SGL(0x1428a2e7),
778*e5436536SAndroid Build Coastguard Worker     FX_DBL2FXCONST_SGL(0x1965febd),
779*e5436536SAndroid Build Coastguard Worker     FX_DBL2FXCONST_SGL(0x20000000),
780*e5436536SAndroid Build Coastguard Worker     FX_DBL2FXCONST_SGL(0x28514606),
781*e5436536SAndroid Build Coastguard Worker     FX_DBL2FXCONST_SGL(0x32cbfd33)};
782*e5436536SAndroid Build Coastguard Worker 
CBlock_ApplyNoise(CAacDecoderChannelInfo * pAacDecoderChannelInfo,SamplingRateInfo * pSamplingRateInfo,ULONG * nfRandomSeed,UCHAR * band_is_noise)783*e5436536SAndroid Build Coastguard Worker void CBlock_ApplyNoise(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
784*e5436536SAndroid Build Coastguard Worker                        SamplingRateInfo *pSamplingRateInfo, ULONG *nfRandomSeed,
785*e5436536SAndroid Build Coastguard Worker                        UCHAR *band_is_noise) {
786*e5436536SAndroid Build Coastguard Worker   const SHORT *swb_offset = GetScaleFactorBandOffsets(
787*e5436536SAndroid Build Coastguard Worker       &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
788*e5436536SAndroid Build Coastguard Worker   int g, win, gwin, sfb, noiseFillingStartOffset, nfStartOffset_sfb;
789*e5436536SAndroid Build Coastguard Worker 
790*e5436536SAndroid Build Coastguard Worker   /* Obtain noise level and scale factor offset. */
791*e5436536SAndroid Build Coastguard Worker   int noise_level = pAacDecoderChannelInfo->pDynData->specificTo.usac
792*e5436536SAndroid Build Coastguard Worker                         .fd_noise_level_and_offset >>
793*e5436536SAndroid Build Coastguard Worker                     5;
794*e5436536SAndroid Build Coastguard Worker   const FIXP_SGL noiseVal_pos = noise_level_tab[noise_level];
795*e5436536SAndroid Build Coastguard Worker 
796*e5436536SAndroid Build Coastguard Worker   /* noise_offset can change even when noise_level=0. Neccesary for IGF stereo
797*e5436536SAndroid Build Coastguard Worker    * filling */
798*e5436536SAndroid Build Coastguard Worker   const int noise_offset = (pAacDecoderChannelInfo->pDynData->specificTo.usac
799*e5436536SAndroid Build Coastguard Worker                                 .fd_noise_level_and_offset &
800*e5436536SAndroid Build Coastguard Worker                             0x1f) -
801*e5436536SAndroid Build Coastguard Worker                            16;
802*e5436536SAndroid Build Coastguard Worker 
803*e5436536SAndroid Build Coastguard Worker   int max_sfb =
804*e5436536SAndroid Build Coastguard Worker       GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
805*e5436536SAndroid Build Coastguard Worker 
806*e5436536SAndroid Build Coastguard Worker   noiseFillingStartOffset =
807*e5436536SAndroid Build Coastguard Worker       (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT)
808*e5436536SAndroid Build Coastguard Worker           ? 20
809*e5436536SAndroid Build Coastguard Worker           : 160;
810*e5436536SAndroid Build Coastguard Worker   if (pAacDecoderChannelInfo->granuleLength == 96) {
811*e5436536SAndroid Build Coastguard Worker     noiseFillingStartOffset =
812*e5436536SAndroid Build Coastguard Worker         (3 * noiseFillingStartOffset) /
813*e5436536SAndroid Build Coastguard Worker         4; /* scale offset with 3/4 for coreCoderFrameLength == 768 */
814*e5436536SAndroid Build Coastguard Worker   }
815*e5436536SAndroid Build Coastguard Worker 
816*e5436536SAndroid Build Coastguard Worker   /* determine sfb from where on noise filling is applied */
817*e5436536SAndroid Build Coastguard Worker   for (sfb = 0; swb_offset[sfb] < noiseFillingStartOffset; sfb++)
818*e5436536SAndroid Build Coastguard Worker     ;
819*e5436536SAndroid Build Coastguard Worker   nfStartOffset_sfb = sfb;
820*e5436536SAndroid Build Coastguard Worker 
821*e5436536SAndroid Build Coastguard Worker   /* if (noise_level!=0) */
822*e5436536SAndroid Build Coastguard Worker   {
823*e5436536SAndroid Build Coastguard Worker     for (g = 0, win = 0; g < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
824*e5436536SAndroid Build Coastguard Worker          g++) {
825*e5436536SAndroid Build Coastguard Worker       int windowGroupLength =
826*e5436536SAndroid Build Coastguard Worker           GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, g);
827*e5436536SAndroid Build Coastguard Worker       for (sfb = nfStartOffset_sfb; sfb < max_sfb; sfb++) {
828*e5436536SAndroid Build Coastguard Worker         int bin_start = swb_offset[sfb];
829*e5436536SAndroid Build Coastguard Worker         int bin_stop = swb_offset[sfb + 1];
830*e5436536SAndroid Build Coastguard Worker 
831*e5436536SAndroid Build Coastguard Worker         int flagN = band_is_noise[g * 16 + sfb];
832*e5436536SAndroid Build Coastguard Worker 
833*e5436536SAndroid Build Coastguard Worker         /* if all bins of one sfb in one window group are zero modify the scale
834*e5436536SAndroid Build Coastguard Worker          * factor by noise_offset */
835*e5436536SAndroid Build Coastguard Worker         if (flagN) {
836*e5436536SAndroid Build Coastguard Worker           /* Change scaling factors for empty signal bands */
837*e5436536SAndroid Build Coastguard Worker           pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] +=
838*e5436536SAndroid Build Coastguard Worker               noise_offset;
839*e5436536SAndroid Build Coastguard Worker           /* scale factor "sf" implied gain "g" is g = 2^(sf/4) */
840*e5436536SAndroid Build Coastguard Worker           for (gwin = 0; gwin < windowGroupLength; gwin++) {
841*e5436536SAndroid Build Coastguard Worker             pAacDecoderChannelInfo->pDynData
842*e5436536SAndroid Build Coastguard Worker                 ->aSfbScale[(win + gwin) * 16 + sfb] += (noise_offset >> 2);
843*e5436536SAndroid Build Coastguard Worker           }
844*e5436536SAndroid Build Coastguard Worker         }
845*e5436536SAndroid Build Coastguard Worker 
846*e5436536SAndroid Build Coastguard Worker         ULONG seed = *nfRandomSeed;
847*e5436536SAndroid Build Coastguard Worker         /* + 1 because exponent of MantissaTable[lsb][0] is always 1. */
848*e5436536SAndroid Build Coastguard Worker         int scale =
849*e5436536SAndroid Build Coastguard Worker             (pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] >>
850*e5436536SAndroid Build Coastguard Worker              2) +
851*e5436536SAndroid Build Coastguard Worker             1;
852*e5436536SAndroid Build Coastguard Worker         int lsb =
853*e5436536SAndroid Build Coastguard Worker             pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] & 3;
854*e5436536SAndroid Build Coastguard Worker         FIXP_DBL mantissa = MantissaTable[lsb][0];
855*e5436536SAndroid Build Coastguard Worker 
856*e5436536SAndroid Build Coastguard Worker         for (gwin = 0; gwin < windowGroupLength; gwin++) {
857*e5436536SAndroid Build Coastguard Worker           FIXP_DBL *pSpec =
858*e5436536SAndroid Build Coastguard Worker               SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, win + gwin,
859*e5436536SAndroid Build Coastguard Worker                    pAacDecoderChannelInfo->granuleLength);
860*e5436536SAndroid Build Coastguard Worker 
861*e5436536SAndroid Build Coastguard Worker           int scale1 = scale - pAacDecoderChannelInfo->pDynData
862*e5436536SAndroid Build Coastguard Worker                                    ->aSfbScale[(win + gwin) * 16 + sfb];
863*e5436536SAndroid Build Coastguard Worker           FIXP_DBL scaled_noiseVal_pos =
864*e5436536SAndroid Build Coastguard Worker               scaleValue(fMultDiv2(noiseVal_pos, mantissa), scale1);
865*e5436536SAndroid Build Coastguard Worker           FIXP_DBL scaled_noiseVal_neg = -scaled_noiseVal_pos;
866*e5436536SAndroid Build Coastguard Worker 
867*e5436536SAndroid Build Coastguard Worker           /* If the whole band is zero, just fill without checking */
868*e5436536SAndroid Build Coastguard Worker           if (flagN) {
869*e5436536SAndroid Build Coastguard Worker             for (int bin = bin_start; bin < bin_stop; bin++) {
870*e5436536SAndroid Build Coastguard Worker               seed = (ULONG)(
871*e5436536SAndroid Build Coastguard Worker                   (UINT64)seed * 69069 +
872*e5436536SAndroid Build Coastguard Worker                   5); /* Inlined: UsacRandomSign - origin in usacdec_lpd.h */
873*e5436536SAndroid Build Coastguard Worker               pSpec[bin] =
874*e5436536SAndroid Build Coastguard Worker                   (seed & 0x10000) ? scaled_noiseVal_neg : scaled_noiseVal_pos;
875*e5436536SAndroid Build Coastguard Worker             } /* for (bin...) */
876*e5436536SAndroid Build Coastguard Worker           }
877*e5436536SAndroid Build Coastguard Worker           /*If band is sparsely filled, check for 0 and fill */
878*e5436536SAndroid Build Coastguard Worker           else {
879*e5436536SAndroid Build Coastguard Worker             for (int bin = bin_start; bin < bin_stop; bin++) {
880*e5436536SAndroid Build Coastguard Worker               if (pSpec[bin] == (FIXP_DBL)0) {
881*e5436536SAndroid Build Coastguard Worker                 seed = (ULONG)(
882*e5436536SAndroid Build Coastguard Worker                     (UINT64)seed * 69069 +
883*e5436536SAndroid Build Coastguard Worker                     5); /* Inlined: UsacRandomSign - origin in usacdec_lpd.h */
884*e5436536SAndroid Build Coastguard Worker                 pSpec[bin] = (seed & 0x10000) ? scaled_noiseVal_neg
885*e5436536SAndroid Build Coastguard Worker                                               : scaled_noiseVal_pos;
886*e5436536SAndroid Build Coastguard Worker               }
887*e5436536SAndroid Build Coastguard Worker             } /* for (bin...) */
888*e5436536SAndroid Build Coastguard Worker           }
889*e5436536SAndroid Build Coastguard Worker 
890*e5436536SAndroid Build Coastguard Worker         } /* for (gwin...) */
891*e5436536SAndroid Build Coastguard Worker         *nfRandomSeed = seed;
892*e5436536SAndroid Build Coastguard Worker       } /* for (sfb...) */
893*e5436536SAndroid Build Coastguard Worker       win += windowGroupLength;
894*e5436536SAndroid Build Coastguard Worker     } /* for (g...) */
895*e5436536SAndroid Build Coastguard Worker 
896*e5436536SAndroid Build Coastguard Worker   } /* ... */
897*e5436536SAndroid Build Coastguard Worker }
898*e5436536SAndroid Build Coastguard Worker 
CBlock_ReadAcSpectralData(HANDLE_FDK_BITSTREAM hBs,CAacDecoderChannelInfo * pAacDecoderChannelInfo,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,const SamplingRateInfo * pSamplingRateInfo,const UINT frame_length,const UINT flags)899*e5436536SAndroid Build Coastguard Worker AAC_DECODER_ERROR CBlock_ReadAcSpectralData(
900*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
901*e5436536SAndroid Build Coastguard Worker     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
902*e5436536SAndroid Build Coastguard Worker     const SamplingRateInfo *pSamplingRateInfo, const UINT frame_length,
903*e5436536SAndroid Build Coastguard Worker     const UINT flags) {
904*e5436536SAndroid Build Coastguard Worker   AAC_DECODER_ERROR errorAAC = AAC_DEC_OK;
905*e5436536SAndroid Build Coastguard Worker   ARITH_CODING_ERROR error = ARITH_CODER_OK;
906*e5436536SAndroid Build Coastguard Worker   int arith_reset_flag, lg, numWin, win, winLen;
907*e5436536SAndroid Build Coastguard Worker   const SHORT *RESTRICT BandOffsets;
908*e5436536SAndroid Build Coastguard Worker 
909*e5436536SAndroid Build Coastguard Worker   /* number of transmitted spectral coefficients */
910*e5436536SAndroid Build Coastguard Worker   BandOffsets = GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo,
911*e5436536SAndroid Build Coastguard Worker                                           pSamplingRateInfo);
912*e5436536SAndroid Build Coastguard Worker   lg = BandOffsets[GetScaleFactorBandsTransmitted(
913*e5436536SAndroid Build Coastguard Worker       &pAacDecoderChannelInfo->icsInfo)];
914*e5436536SAndroid Build Coastguard Worker 
915*e5436536SAndroid Build Coastguard Worker   numWin = GetWindowsPerFrame(&pAacDecoderChannelInfo->icsInfo);
916*e5436536SAndroid Build Coastguard Worker   winLen = (IsLongBlock(&pAacDecoderChannelInfo->icsInfo))
917*e5436536SAndroid Build Coastguard Worker                ? (int)frame_length
918*e5436536SAndroid Build Coastguard Worker                : (int)frame_length / numWin;
919*e5436536SAndroid Build Coastguard Worker 
920*e5436536SAndroid Build Coastguard Worker   if (flags & AC_INDEP) {
921*e5436536SAndroid Build Coastguard Worker     arith_reset_flag = 1;
922*e5436536SAndroid Build Coastguard Worker   } else {
923*e5436536SAndroid Build Coastguard Worker     arith_reset_flag = (USHORT)FDKreadBits(hBs, 1);
924*e5436536SAndroid Build Coastguard Worker   }
925*e5436536SAndroid Build Coastguard Worker 
926*e5436536SAndroid Build Coastguard Worker   for (win = 0; win < numWin; win++) {
927*e5436536SAndroid Build Coastguard Worker     error =
928*e5436536SAndroid Build Coastguard Worker         CArco_DecodeArithData(pAacDecoderStaticChannelInfo->hArCo, hBs,
929*e5436536SAndroid Build Coastguard Worker                               SPEC(pAacDecoderChannelInfo->pSpectralCoefficient,
930*e5436536SAndroid Build Coastguard Worker                                    win, pAacDecoderChannelInfo->granuleLength),
931*e5436536SAndroid Build Coastguard Worker                               lg, winLen, arith_reset_flag && (win == 0));
932*e5436536SAndroid Build Coastguard Worker     if (error != ARITH_CODER_OK) {
933*e5436536SAndroid Build Coastguard Worker       goto bail;
934*e5436536SAndroid Build Coastguard Worker     }
935*e5436536SAndroid Build Coastguard Worker   }
936*e5436536SAndroid Build Coastguard Worker 
937*e5436536SAndroid Build Coastguard Worker bail:
938*e5436536SAndroid Build Coastguard Worker   if (error == ARITH_CODER_ERROR) {
939*e5436536SAndroid Build Coastguard Worker     errorAAC = AAC_DEC_PARSE_ERROR;
940*e5436536SAndroid Build Coastguard Worker   }
941*e5436536SAndroid Build Coastguard Worker 
942*e5436536SAndroid Build Coastguard Worker   return errorAAC;
943*e5436536SAndroid Build Coastguard Worker }
944*e5436536SAndroid Build Coastguard Worker 
ApplyTools(CAacDecoderChannelInfo * pAacDecoderChannelInfo[],const SamplingRateInfo * pSamplingRateInfo,const UINT flags,const UINT elFlags,const int channel,const int common_window)945*e5436536SAndroid Build Coastguard Worker void ApplyTools(CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
946*e5436536SAndroid Build Coastguard Worker                 const SamplingRateInfo *pSamplingRateInfo, const UINT flags,
947*e5436536SAndroid Build Coastguard Worker                 const UINT elFlags, const int channel,
948*e5436536SAndroid Build Coastguard Worker                 const int common_window) {
949*e5436536SAndroid Build Coastguard Worker   if (!(flags & (AC_USAC | AC_RSVD50 | AC_MPEGD_RES | AC_RSV603DA))) {
950*e5436536SAndroid Build Coastguard Worker     CPns_Apply(&pAacDecoderChannelInfo[channel]->data.aac.PnsData,
951*e5436536SAndroid Build Coastguard Worker                &pAacDecoderChannelInfo[channel]->icsInfo,
952*e5436536SAndroid Build Coastguard Worker                pAacDecoderChannelInfo[channel]->pSpectralCoefficient,
953*e5436536SAndroid Build Coastguard Worker                pAacDecoderChannelInfo[channel]->specScale,
954*e5436536SAndroid Build Coastguard Worker                pAacDecoderChannelInfo[channel]->pDynData->aScaleFactor,
955*e5436536SAndroid Build Coastguard Worker                pSamplingRateInfo,
956*e5436536SAndroid Build Coastguard Worker                pAacDecoderChannelInfo[channel]->granuleLength, channel);
957*e5436536SAndroid Build Coastguard Worker   }
958*e5436536SAndroid Build Coastguard Worker 
959*e5436536SAndroid Build Coastguard Worker   UCHAR nbands =
960*e5436536SAndroid Build Coastguard Worker       GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[channel]->icsInfo);
961*e5436536SAndroid Build Coastguard Worker 
962*e5436536SAndroid Build Coastguard Worker   CTns_Apply(&pAacDecoderChannelInfo[channel]->pDynData->TnsData,
963*e5436536SAndroid Build Coastguard Worker              &pAacDecoderChannelInfo[channel]->icsInfo,
964*e5436536SAndroid Build Coastguard Worker              pAacDecoderChannelInfo[channel]->pSpectralCoefficient,
965*e5436536SAndroid Build Coastguard Worker              pSamplingRateInfo, pAacDecoderChannelInfo[channel]->granuleLength,
966*e5436536SAndroid Build Coastguard Worker              nbands, (elFlags & AC_EL_ENHANCED_NOISE) ? 1 : 0, flags);
967*e5436536SAndroid Build Coastguard Worker }
968*e5436536SAndroid Build Coastguard Worker 
getWindow2Nr(int length,int shape)969*e5436536SAndroid Build Coastguard Worker static int getWindow2Nr(int length, int shape) {
970*e5436536SAndroid Build Coastguard Worker   int nr = 0;
971*e5436536SAndroid Build Coastguard Worker 
972*e5436536SAndroid Build Coastguard Worker   if (shape == 2) {
973*e5436536SAndroid Build Coastguard Worker     /* Low Overlap, 3/4 zeroed */
974*e5436536SAndroid Build Coastguard Worker     nr = (length * 3) >> 2;
975*e5436536SAndroid Build Coastguard Worker   }
976*e5436536SAndroid Build Coastguard Worker 
977*e5436536SAndroid Build Coastguard Worker   return nr;
978*e5436536SAndroid Build Coastguard Worker }
979*e5436536SAndroid Build Coastguard Worker 
get_gain(const FIXP_DBL * x,const FIXP_DBL * y,int n)980*e5436536SAndroid Build Coastguard Worker FIXP_DBL get_gain(const FIXP_DBL *x, const FIXP_DBL *y, int n) {
981*e5436536SAndroid Build Coastguard Worker   FIXP_DBL corr = (FIXP_DBL)0;
982*e5436536SAndroid Build Coastguard Worker   FIXP_DBL ener = (FIXP_DBL)1;
983*e5436536SAndroid Build Coastguard Worker 
984*e5436536SAndroid Build Coastguard Worker   int headroom_x = getScalefactor(x, n);
985*e5436536SAndroid Build Coastguard Worker   int headroom_y = getScalefactor(y, n);
986*e5436536SAndroid Build Coastguard Worker 
987*e5436536SAndroid Build Coastguard Worker   /*Calculate the normalization necessary due to addition*/
988*e5436536SAndroid Build Coastguard Worker   /* Check for power of two /special case */
989*e5436536SAndroid Build Coastguard Worker   INT width_shift = (INT)(fNormz((FIXP_DBL)n));
990*e5436536SAndroid Build Coastguard Worker   /* Get the number of bits necessary minus one, because we need one sign bit
991*e5436536SAndroid Build Coastguard Worker    * only */
992*e5436536SAndroid Build Coastguard Worker   width_shift = 31 - width_shift;
993*e5436536SAndroid Build Coastguard Worker 
994*e5436536SAndroid Build Coastguard Worker   for (int i = 0; i < n; i++) {
995*e5436536SAndroid Build Coastguard Worker     corr +=
996*e5436536SAndroid Build Coastguard Worker         fMultDiv2((x[i] << headroom_x), (y[i] << headroom_y)) >> width_shift;
997*e5436536SAndroid Build Coastguard Worker     ener += fPow2Div2((y[i] << headroom_y)) >> width_shift;
998*e5436536SAndroid Build Coastguard Worker   }
999*e5436536SAndroid Build Coastguard Worker 
1000*e5436536SAndroid Build Coastguard Worker   int exp_corr = (17 - headroom_x) + (17 - headroom_y) + width_shift + 1;
1001*e5436536SAndroid Build Coastguard Worker   int exp_ener = ((17 - headroom_y) << 1) + width_shift + 1;
1002*e5436536SAndroid Build Coastguard Worker 
1003*e5436536SAndroid Build Coastguard Worker   int temp_exp = 0;
1004*e5436536SAndroid Build Coastguard Worker   FIXP_DBL output = fDivNormSigned(corr, ener, &temp_exp);
1005*e5436536SAndroid Build Coastguard Worker 
1006*e5436536SAndroid Build Coastguard Worker   int output_exp = (exp_corr - exp_ener) + temp_exp;
1007*e5436536SAndroid Build Coastguard Worker 
1008*e5436536SAndroid Build Coastguard Worker   INT output_shift = 17 - output_exp;
1009*e5436536SAndroid Build Coastguard Worker   output_shift = fMin(output_shift, 31);
1010*e5436536SAndroid Build Coastguard Worker 
1011*e5436536SAndroid Build Coastguard Worker   output = scaleValue(output, -output_shift);
1012*e5436536SAndroid Build Coastguard Worker 
1013*e5436536SAndroid Build Coastguard Worker   return output;
1014*e5436536SAndroid Build Coastguard Worker }
1015*e5436536SAndroid Build Coastguard Worker 
CBlock_FrequencyToTime(CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,CAacDecoderChannelInfo * pAacDecoderChannelInfo,PCM_DEC outSamples[],const SHORT frameLen,const int frameOk,FIXP_DBL * pWorkBuffer1,const INT aacOutDataHeadroom,UINT elFlags,INT elCh)1016*e5436536SAndroid Build Coastguard Worker void CBlock_FrequencyToTime(
1017*e5436536SAndroid Build Coastguard Worker     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
1018*e5436536SAndroid Build Coastguard Worker     CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
1019*e5436536SAndroid Build Coastguard Worker     const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1,
1020*e5436536SAndroid Build Coastguard Worker     const INT aacOutDataHeadroom, UINT elFlags, INT elCh) {
1021*e5436536SAndroid Build Coastguard Worker   int fr, fl, tl, nSpec;
1022*e5436536SAndroid Build Coastguard Worker 
1023*e5436536SAndroid Build Coastguard Worker #if defined(FDK_ASSERT_ENABLE)
1024*e5436536SAndroid Build Coastguard Worker   LONG nSamples;
1025*e5436536SAndroid Build Coastguard Worker #endif
1026*e5436536SAndroid Build Coastguard Worker 
1027*e5436536SAndroid Build Coastguard Worker   /* Determine left slope length (fl), right slope length (fr) and transform
1028*e5436536SAndroid Build Coastguard Worker      length (tl). USAC: The slope length may mismatch with the previous frame in
1029*e5436536SAndroid Build Coastguard Worker      case of LPD / FD transitions. The adjustment is handled by the imdct
1030*e5436536SAndroid Build Coastguard Worker      implementation.
1031*e5436536SAndroid Build Coastguard Worker   */
1032*e5436536SAndroid Build Coastguard Worker   tl = frameLen;
1033*e5436536SAndroid Build Coastguard Worker   nSpec = 1;
1034*e5436536SAndroid Build Coastguard Worker 
1035*e5436536SAndroid Build Coastguard Worker   switch (pAacDecoderChannelInfo->icsInfo.WindowSequence) {
1036*e5436536SAndroid Build Coastguard Worker     default:
1037*e5436536SAndroid Build Coastguard Worker     case BLOCK_LONG:
1038*e5436536SAndroid Build Coastguard Worker       fl = frameLen;
1039*e5436536SAndroid Build Coastguard Worker       fr = frameLen -
1040*e5436536SAndroid Build Coastguard Worker            getWindow2Nr(frameLen,
1041*e5436536SAndroid Build Coastguard Worker                         GetWindowShape(&pAacDecoderChannelInfo->icsInfo));
1042*e5436536SAndroid Build Coastguard Worker       /* New startup needs differentiation between sine shape and low overlap
1043*e5436536SAndroid Build Coastguard Worker          shape. This is a special case for the LD-AAC transformation windows,
1044*e5436536SAndroid Build Coastguard Worker          because the slope length can be different while using the same window
1045*e5436536SAndroid Build Coastguard Worker          sequence. */
1046*e5436536SAndroid Build Coastguard Worker       if (pAacDecoderStaticChannelInfo->IMdct.prev_tl == 0) {
1047*e5436536SAndroid Build Coastguard Worker         fl = fr;
1048*e5436536SAndroid Build Coastguard Worker       }
1049*e5436536SAndroid Build Coastguard Worker       break;
1050*e5436536SAndroid Build Coastguard Worker     case BLOCK_STOP:
1051*e5436536SAndroid Build Coastguard Worker       fl = frameLen >> 3;
1052*e5436536SAndroid Build Coastguard Worker       fr = frameLen;
1053*e5436536SAndroid Build Coastguard Worker       break;
1054*e5436536SAndroid Build Coastguard Worker     case BLOCK_START: /* or StopStartSequence */
1055*e5436536SAndroid Build Coastguard Worker       fl = frameLen;
1056*e5436536SAndroid Build Coastguard Worker       fr = frameLen >> 3;
1057*e5436536SAndroid Build Coastguard Worker       break;
1058*e5436536SAndroid Build Coastguard Worker     case BLOCK_SHORT:
1059*e5436536SAndroid Build Coastguard Worker       fl = fr = frameLen >> 3;
1060*e5436536SAndroid Build Coastguard Worker       tl >>= 3;
1061*e5436536SAndroid Build Coastguard Worker       nSpec = 8;
1062*e5436536SAndroid Build Coastguard Worker       break;
1063*e5436536SAndroid Build Coastguard Worker   }
1064*e5436536SAndroid Build Coastguard Worker 
1065*e5436536SAndroid Build Coastguard Worker   {
1066*e5436536SAndroid Build Coastguard Worker     int last_frame_lost = pAacDecoderStaticChannelInfo->last_lpc_lost;
1067*e5436536SAndroid Build Coastguard Worker 
1068*e5436536SAndroid Build Coastguard Worker     if (pAacDecoderStaticChannelInfo->last_core_mode == LPD) {
1069*e5436536SAndroid Build Coastguard Worker       INT fac_FB = 1;
1070*e5436536SAndroid Build Coastguard Worker       if (elFlags & AC_EL_FULLBANDLPD) {
1071*e5436536SAndroid Build Coastguard Worker         fac_FB = 2;
1072*e5436536SAndroid Build Coastguard Worker       }
1073*e5436536SAndroid Build Coastguard Worker 
1074*e5436536SAndroid Build Coastguard Worker       FIXP_DBL *synth;
1075*e5436536SAndroid Build Coastguard Worker 
1076*e5436536SAndroid Build Coastguard Worker       /* Keep some free space at the beginning of the buffer. To be used for
1077*e5436536SAndroid Build Coastguard Worker        * past data */
1078*e5436536SAndroid Build Coastguard Worker       if (!(elFlags & AC_EL_LPDSTEREOIDX)) {
1079*e5436536SAndroid Build Coastguard Worker         synth = pWorkBuffer1 + ((PIT_MAX_MAX - (1 * L_SUBFR)) * fac_FB);
1080*e5436536SAndroid Build Coastguard Worker       } else {
1081*e5436536SAndroid Build Coastguard Worker         synth = pWorkBuffer1 + PIT_MAX_MAX * fac_FB;
1082*e5436536SAndroid Build Coastguard Worker       }
1083*e5436536SAndroid Build Coastguard Worker 
1084*e5436536SAndroid Build Coastguard Worker       int fac_length =
1085*e5436536SAndroid Build Coastguard Worker           (pAacDecoderChannelInfo->icsInfo.WindowSequence == BLOCK_SHORT)
1086*e5436536SAndroid Build Coastguard Worker               ? (frameLen >> 4)
1087*e5436536SAndroid Build Coastguard Worker               : (frameLen >> 3);
1088*e5436536SAndroid Build Coastguard Worker 
1089*e5436536SAndroid Build Coastguard Worker       INT pitch[NB_SUBFR_SUPERFR + SYN_SFD];
1090*e5436536SAndroid Build Coastguard Worker       FIXP_DBL pit_gain[NB_SUBFR_SUPERFR + SYN_SFD];
1091*e5436536SAndroid Build Coastguard Worker 
1092*e5436536SAndroid Build Coastguard Worker       int nbDiv = (elFlags & AC_EL_FULLBANDLPD) ? 2 : 4;
1093*e5436536SAndroid Build Coastguard Worker       int lFrame = (elFlags & AC_EL_FULLBANDLPD) ? frameLen / 2 : frameLen;
1094*e5436536SAndroid Build Coastguard Worker       int nbSubfr =
1095*e5436536SAndroid Build Coastguard Worker           lFrame / (nbDiv * L_SUBFR); /* number of subframes per division */
1096*e5436536SAndroid Build Coastguard Worker       int LpdSfd = (nbDiv * nbSubfr) >> 1;
1097*e5436536SAndroid Build Coastguard Worker       int SynSfd = LpdSfd - BPF_SFD;
1098*e5436536SAndroid Build Coastguard Worker 
1099*e5436536SAndroid Build Coastguard Worker       FDKmemclear(
1100*e5436536SAndroid Build Coastguard Worker           pitch,
1101*e5436536SAndroid Build Coastguard Worker           sizeof(
1102*e5436536SAndroid Build Coastguard Worker               pitch));  // added to prevent ferret errors in bass_pf_1sf_delay
1103*e5436536SAndroid Build Coastguard Worker       FDKmemclear(pit_gain, sizeof(pit_gain));
1104*e5436536SAndroid Build Coastguard Worker 
1105*e5436536SAndroid Build Coastguard Worker       /* FAC case */
1106*e5436536SAndroid Build Coastguard Worker       if (pAacDecoderStaticChannelInfo->last_lpd_mode == 0 ||
1107*e5436536SAndroid Build Coastguard Worker           pAacDecoderStaticChannelInfo->last_lpd_mode == 4) {
1108*e5436536SAndroid Build Coastguard Worker         FIXP_DBL fac_buf[LFAC];
1109*e5436536SAndroid Build Coastguard Worker         FIXP_LPC *A = pAacDecoderChannelInfo->data.usac.lp_coeff[0];
1110*e5436536SAndroid Build Coastguard Worker 
1111*e5436536SAndroid Build Coastguard Worker         if (!frameOk || last_frame_lost ||
1112*e5436536SAndroid Build Coastguard Worker             (pAacDecoderChannelInfo->data.usac.fac_data[0] == NULL)) {
1113*e5436536SAndroid Build Coastguard Worker           FDKmemclear(fac_buf,
1114*e5436536SAndroid Build Coastguard Worker                       pAacDecoderChannelInfo->granuleLength * sizeof(FIXP_DBL));
1115*e5436536SAndroid Build Coastguard Worker           pAacDecoderChannelInfo->data.usac.fac_data[0] = fac_buf;
1116*e5436536SAndroid Build Coastguard Worker           pAacDecoderChannelInfo->data.usac.fac_data_e[0] = 0;
1117*e5436536SAndroid Build Coastguard Worker         }
1118*e5436536SAndroid Build Coastguard Worker 
1119*e5436536SAndroid Build Coastguard Worker         INT A_exp; /* linear prediction coefficients exponent */
1120*e5436536SAndroid Build Coastguard Worker         {
1121*e5436536SAndroid Build Coastguard Worker           for (int i = 0; i < M_LP_FILTER_ORDER; i++) {
1122*e5436536SAndroid Build Coastguard Worker             A[i] = FX_DBL2FX_LPC(fixp_cos(
1123*e5436536SAndroid Build Coastguard Worker                 fMult(pAacDecoderStaticChannelInfo->lpc4_lsf[i],
1124*e5436536SAndroid Build Coastguard Worker                       FL2FXCONST_SGL((1 << LSPARG_SCALE) * M_PI / 6400.0)),
1125*e5436536SAndroid Build Coastguard Worker                 LSF_SCALE - LSPARG_SCALE));
1126*e5436536SAndroid Build Coastguard Worker           }
1127*e5436536SAndroid Build Coastguard Worker 
1128*e5436536SAndroid Build Coastguard Worker           E_LPC_f_lsp_a_conversion(A, A, &A_exp);
1129*e5436536SAndroid Build Coastguard Worker         }
1130*e5436536SAndroid Build Coastguard Worker 
1131*e5436536SAndroid Build Coastguard Worker #if defined(FDK_ASSERT_ENABLE)
1132*e5436536SAndroid Build Coastguard Worker         nSamples =
1133*e5436536SAndroid Build Coastguard Worker #endif
1134*e5436536SAndroid Build Coastguard Worker             CLpd_FAC_Acelp2Mdct(
1135*e5436536SAndroid Build Coastguard Worker                 &pAacDecoderStaticChannelInfo->IMdct, synth,
1136*e5436536SAndroid Build Coastguard Worker                 SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
1137*e5436536SAndroid Build Coastguard Worker                 pAacDecoderChannelInfo->specScale, nSpec,
1138*e5436536SAndroid Build Coastguard Worker                 pAacDecoderChannelInfo->data.usac.fac_data[0],
1139*e5436536SAndroid Build Coastguard Worker                 pAacDecoderChannelInfo->data.usac.fac_data_e[0], fac_length,
1140*e5436536SAndroid Build Coastguard Worker                 frameLen, tl,
1141*e5436536SAndroid Build Coastguard Worker                 FDKgetWindowSlope(
1142*e5436536SAndroid Build Coastguard Worker                     fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
1143*e5436536SAndroid Build Coastguard Worker                 fr, A, A_exp, &pAacDecoderStaticChannelInfo->acelp,
1144*e5436536SAndroid Build Coastguard Worker                 (FIXP_DBL)0, /* FAC gain has already been applied. */
1145*e5436536SAndroid Build Coastguard Worker                 (last_frame_lost || !frameOk), 1,
1146*e5436536SAndroid Build Coastguard Worker                 pAacDecoderStaticChannelInfo->last_lpd_mode, 0,
1147*e5436536SAndroid Build Coastguard Worker                 pAacDecoderChannelInfo->currAliasingSymmetry);
1148*e5436536SAndroid Build Coastguard Worker 
1149*e5436536SAndroid Build Coastguard Worker       } else {
1150*e5436536SAndroid Build Coastguard Worker #if defined(FDK_ASSERT_ENABLE)
1151*e5436536SAndroid Build Coastguard Worker         nSamples =
1152*e5436536SAndroid Build Coastguard Worker #endif
1153*e5436536SAndroid Build Coastguard Worker             imlt_block(
1154*e5436536SAndroid Build Coastguard Worker                 &pAacDecoderStaticChannelInfo->IMdct, synth,
1155*e5436536SAndroid Build Coastguard Worker                 SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
1156*e5436536SAndroid Build Coastguard Worker                 pAacDecoderChannelInfo->specScale, nSpec, frameLen, tl,
1157*e5436536SAndroid Build Coastguard Worker                 FDKgetWindowSlope(
1158*e5436536SAndroid Build Coastguard Worker                     fl, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
1159*e5436536SAndroid Build Coastguard Worker                 fl,
1160*e5436536SAndroid Build Coastguard Worker                 FDKgetWindowSlope(
1161*e5436536SAndroid Build Coastguard Worker                     fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
1162*e5436536SAndroid Build Coastguard Worker                 fr, (FIXP_DBL)0,
1163*e5436536SAndroid Build Coastguard Worker                 pAacDecoderChannelInfo->currAliasingSymmetry
1164*e5436536SAndroid Build Coastguard Worker                     ? MLT_FLAG_CURR_ALIAS_SYMMETRY
1165*e5436536SAndroid Build Coastguard Worker                     : 0);
1166*e5436536SAndroid Build Coastguard Worker       }
1167*e5436536SAndroid Build Coastguard Worker       FDK_ASSERT(nSamples == frameLen);
1168*e5436536SAndroid Build Coastguard Worker 
1169*e5436536SAndroid Build Coastguard Worker       /* The "if" clause is entered both for fullbandLpd mono and
1170*e5436536SAndroid Build Coastguard Worker        * non-fullbandLpd*. The "else"-> just for fullbandLpd stereo*/
1171*e5436536SAndroid Build Coastguard Worker       if (!(elFlags & AC_EL_LPDSTEREOIDX)) {
1172*e5436536SAndroid Build Coastguard Worker         FDKmemcpy(pitch, pAacDecoderStaticChannelInfo->old_T_pf,
1173*e5436536SAndroid Build Coastguard Worker                   SynSfd * sizeof(INT));
1174*e5436536SAndroid Build Coastguard Worker         FDKmemcpy(pit_gain, pAacDecoderStaticChannelInfo->old_gain_pf,
1175*e5436536SAndroid Build Coastguard Worker                   SynSfd * sizeof(FIXP_DBL));
1176*e5436536SAndroid Build Coastguard Worker 
1177*e5436536SAndroid Build Coastguard Worker         for (int i = SynSfd; i < LpdSfd + 3; i++) {
1178*e5436536SAndroid Build Coastguard Worker           pitch[i] = L_SUBFR;
1179*e5436536SAndroid Build Coastguard Worker           pit_gain[i] = (FIXP_DBL)0;
1180*e5436536SAndroid Build Coastguard Worker         }
1181*e5436536SAndroid Build Coastguard Worker 
1182*e5436536SAndroid Build Coastguard Worker         if (pAacDecoderStaticChannelInfo->last_lpd_mode == 0) {
1183*e5436536SAndroid Build Coastguard Worker           pitch[SynSfd] = pitch[SynSfd - 1];
1184*e5436536SAndroid Build Coastguard Worker           pit_gain[SynSfd] = pit_gain[SynSfd - 1];
1185*e5436536SAndroid Build Coastguard Worker           if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) {
1186*e5436536SAndroid Build Coastguard Worker             pitch[SynSfd + 1] = pitch[SynSfd];
1187*e5436536SAndroid Build Coastguard Worker             pit_gain[SynSfd + 1] = pit_gain[SynSfd];
1188*e5436536SAndroid Build Coastguard Worker           }
1189*e5436536SAndroid Build Coastguard Worker         }
1190*e5436536SAndroid Build Coastguard Worker 
1191*e5436536SAndroid Build Coastguard Worker         /* Copy old data to the beginning of the buffer */
1192*e5436536SAndroid Build Coastguard Worker         {
1193*e5436536SAndroid Build Coastguard Worker           FDKmemcpy(
1194*e5436536SAndroid Build Coastguard Worker               pWorkBuffer1, pAacDecoderStaticChannelInfo->old_synth,
1195*e5436536SAndroid Build Coastguard Worker               ((PIT_MAX_MAX - (1 * L_SUBFR)) * fac_FB) * sizeof(FIXP_DBL));
1196*e5436536SAndroid Build Coastguard Worker         }
1197*e5436536SAndroid Build Coastguard Worker 
1198*e5436536SAndroid Build Coastguard Worker         FIXP_DBL *p2_synth = pWorkBuffer1 + (PIT_MAX_MAX * fac_FB);
1199*e5436536SAndroid Build Coastguard Worker 
1200*e5436536SAndroid Build Coastguard Worker         /* recalculate pitch gain to allow postfilering on FAC area */
1201*e5436536SAndroid Build Coastguard Worker         for (int i = 0; i < SynSfd + 2; i++) {
1202*e5436536SAndroid Build Coastguard Worker           int T = pitch[i];
1203*e5436536SAndroid Build Coastguard Worker           FIXP_DBL gain = pit_gain[i];
1204*e5436536SAndroid Build Coastguard Worker 
1205*e5436536SAndroid Build Coastguard Worker           if (gain > (FIXP_DBL)0) {
1206*e5436536SAndroid Build Coastguard Worker             gain = get_gain(&p2_synth[i * L_SUBFR * fac_FB],
1207*e5436536SAndroid Build Coastguard Worker                             &p2_synth[(i * L_SUBFR * fac_FB) - fac_FB * T],
1208*e5436536SAndroid Build Coastguard Worker                             L_SUBFR * fac_FB);
1209*e5436536SAndroid Build Coastguard Worker             pit_gain[i] = gain;
1210*e5436536SAndroid Build Coastguard Worker           }
1211*e5436536SAndroid Build Coastguard Worker         }
1212*e5436536SAndroid Build Coastguard Worker 
1213*e5436536SAndroid Build Coastguard Worker         bass_pf_1sf_delay(p2_synth, pitch, pit_gain, frameLen,
1214*e5436536SAndroid Build Coastguard Worker                           (LpdSfd + 2) * L_SUBFR + BPF_SFD * L_SUBFR,
1215*e5436536SAndroid Build Coastguard Worker                           frameLen - (LpdSfd + 4) * L_SUBFR, outSamples,
1216*e5436536SAndroid Build Coastguard Worker                           aacOutDataHeadroom,
1217*e5436536SAndroid Build Coastguard Worker                           pAacDecoderStaticChannelInfo->mem_bpf);
1218*e5436536SAndroid Build Coastguard Worker       }
1219*e5436536SAndroid Build Coastguard Worker 
1220*e5436536SAndroid Build Coastguard Worker     } else /* last_core_mode was not LPD */
1221*e5436536SAndroid Build Coastguard Worker     {
1222*e5436536SAndroid Build Coastguard Worker       FIXP_DBL *tmp =
1223*e5436536SAndroid Build Coastguard Worker           pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1->mdctOutTemp;
1224*e5436536SAndroid Build Coastguard Worker #if defined(FDK_ASSERT_ENABLE)
1225*e5436536SAndroid Build Coastguard Worker       nSamples =
1226*e5436536SAndroid Build Coastguard Worker #endif
1227*e5436536SAndroid Build Coastguard Worker           imlt_block(&pAacDecoderStaticChannelInfo->IMdct, tmp,
1228*e5436536SAndroid Build Coastguard Worker                      SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
1229*e5436536SAndroid Build Coastguard Worker                      pAacDecoderChannelInfo->specScale, nSpec, frameLen, tl,
1230*e5436536SAndroid Build Coastguard Worker                      FDKgetWindowSlope(
1231*e5436536SAndroid Build Coastguard Worker                          fl, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
1232*e5436536SAndroid Build Coastguard Worker                      fl,
1233*e5436536SAndroid Build Coastguard Worker                      FDKgetWindowSlope(
1234*e5436536SAndroid Build Coastguard Worker                          fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
1235*e5436536SAndroid Build Coastguard Worker                      fr, (FIXP_DBL)0,
1236*e5436536SAndroid Build Coastguard Worker                      pAacDecoderChannelInfo->currAliasingSymmetry
1237*e5436536SAndroid Build Coastguard Worker                          ? MLT_FLAG_CURR_ALIAS_SYMMETRY
1238*e5436536SAndroid Build Coastguard Worker                          : 0);
1239*e5436536SAndroid Build Coastguard Worker 
1240*e5436536SAndroid Build Coastguard Worker       scaleValuesSaturate(outSamples, tmp, frameLen,
1241*e5436536SAndroid Build Coastguard Worker                           MDCT_OUT_HEADROOM - aacOutDataHeadroom);
1242*e5436536SAndroid Build Coastguard Worker     }
1243*e5436536SAndroid Build Coastguard Worker   }
1244*e5436536SAndroid Build Coastguard Worker 
1245*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(nSamples == frameLen);
1246*e5436536SAndroid Build Coastguard Worker 
1247*e5436536SAndroid Build Coastguard Worker   pAacDecoderStaticChannelInfo->last_core_mode =
1248*e5436536SAndroid Build Coastguard Worker       (pAacDecoderChannelInfo->icsInfo.WindowSequence == BLOCK_SHORT) ? FD_SHORT
1249*e5436536SAndroid Build Coastguard Worker                                                                       : FD_LONG;
1250*e5436536SAndroid Build Coastguard Worker   pAacDecoderStaticChannelInfo->last_lpd_mode = 255;
1251*e5436536SAndroid Build Coastguard Worker }
1252*e5436536SAndroid Build Coastguard Worker 
1253*e5436536SAndroid Build Coastguard Worker #include "ldfiltbank.h"
CBlock_FrequencyToTimeLowDelay(CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo,CAacDecoderChannelInfo * pAacDecoderChannelInfo,PCM_DEC outSamples[],const short frameLen)1254*e5436536SAndroid Build Coastguard Worker void CBlock_FrequencyToTimeLowDelay(
1255*e5436536SAndroid Build Coastguard Worker     CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
1256*e5436536SAndroid Build Coastguard Worker     CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[],
1257*e5436536SAndroid Build Coastguard Worker     const short frameLen) {
1258*e5436536SAndroid Build Coastguard Worker   InvMdctTransformLowDelay_fdk(
1259*e5436536SAndroid Build Coastguard Worker       SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
1260*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->specScale[0], outSamples,
1261*e5436536SAndroid Build Coastguard Worker       pAacDecoderStaticChannelInfo->pOverlapBuffer, frameLen);
1262*e5436536SAndroid Build Coastguard Worker }
1263