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