• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6 
7  1.    INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18 
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28 
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33 
34 2.    COPYRIGHT LICENSE
35 
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39 
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42 
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48 
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51 
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54 
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60 
61 3.    NO PATENT LICENSE
62 
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67 
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70 
71 4.    DISCLAIMER
72 
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83 
84 5.    CONTACT INFORMATION
85 
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90 
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94 
95 /**************************** SBR decoder library ******************************
96 
97    Author(s):
98 
99    Description:
100 
101 *******************************************************************************/
102 
103 /*!
104   \file
105   \brief  Low Power Profile Transposer
106   This module provides the transposer. The main entry point is lppTransposer().
107   The function generates high frequency content by copying data from the low
108   band (provided by core codec) into the high band. This process is also
109   referred to as "patching". The function also implements spectral whitening by
110   means of inverse filtering based on LPC coefficients.
111 
112   Together with the QMF filterbank the transposer can be tested using a supplied
113   test program. See main_audio.cpp for details. This module does use fractional
114   arithmetic and the accuracy of the computations has an impact on the overall
115   sound quality. The module also needs to take into account the different
116   scaling of spectral data.
117 
118   \sa lppTransposer(), main_audio.cpp, sbr_scale.h, \ref documentationOverview
119 */
120 
121 #ifdef __ANDROID__
122 #include "log/log.h"
123 #endif
124 
125 #include "lpp_tran.h"
126 
127 #include "sbr_ram.h"
128 #include "sbr_rom.h"
129 
130 #include "genericStds.h"
131 #include "autocorr2nd.h"
132 
133 #include "HFgen_preFlat.h"
134 
135 #define LPC_SCALE_FACTOR 2
136 
137 /*!
138  *
139  * \brief Get bandwidth expansion factor from filtering level
140  *
141  * Returns a filter parameter (bandwidth expansion factor) depending on
142  * the desired filtering level signalled in the bitstream.
143  * When switching the filtering level from LOW to OFF, an additional
144  * level is being inserted to achieve a smooth transition.
145  */
146 
mapInvfMode(INVF_MODE mode,INVF_MODE prevMode,WHITENING_FACTORS whFactors)147 static FIXP_DBL mapInvfMode(INVF_MODE mode, INVF_MODE prevMode,
148                             WHITENING_FACTORS whFactors) {
149   switch (mode) {
150     case INVF_LOW_LEVEL:
151       if (prevMode == INVF_OFF)
152         return whFactors.transitionLevel;
153       else
154         return whFactors.lowLevel;
155 
156     case INVF_MID_LEVEL:
157       return whFactors.midLevel;
158 
159     case INVF_HIGH_LEVEL:
160       return whFactors.highLevel;
161 
162     default:
163       if (prevMode == INVF_LOW_LEVEL)
164         return whFactors.transitionLevel;
165       else
166         return whFactors.off;
167   }
168 }
169 
170 /*!
171  *
172  * \brief Perform inverse filtering level emphasis
173  *
174  * Retrieve bandwidth expansion factor and apply smoothing for each filter band
175  *
176  */
177 
inverseFilteringLevelEmphasis(HANDLE_SBR_LPP_TRANS hLppTrans,UCHAR nInvfBands,INVF_MODE * sbr_invf_mode,INVF_MODE * sbr_invf_mode_prev,FIXP_DBL * bwVector)178 static void inverseFilteringLevelEmphasis(
179     HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer  */
180     UCHAR nInvfBands,              /*!< Number of bands for inverse filtering */
181     INVF_MODE *sbr_invf_mode,      /*!< Current inverse filtering modes */
182     INVF_MODE *sbr_invf_mode_prev, /*!< Previous inverse filtering modes */
183     FIXP_DBL *bwVector             /*!< Resulting filtering levels */
184 ) {
185   for (int i = 0; i < nInvfBands; i++) {
186     FIXP_DBL accu;
187     FIXP_DBL bwTmp = mapInvfMode(sbr_invf_mode[i], sbr_invf_mode_prev[i],
188                                  hLppTrans->pSettings->whFactors);
189 
190     if (bwTmp < hLppTrans->bwVectorOld[i]) {
191       accu = fMultDiv2(FL2FXCONST_DBL(0.75f), bwTmp) +
192              fMultDiv2(FL2FXCONST_DBL(0.25f), hLppTrans->bwVectorOld[i]);
193     } else {
194       accu = fMultDiv2(FL2FXCONST_DBL(0.90625f), bwTmp) +
195              fMultDiv2(FL2FXCONST_DBL(0.09375f), hLppTrans->bwVectorOld[i]);
196     }
197 
198     if (accu<FL2FXCONST_DBL(0.015625f)>> 1) {
199       bwVector[i] = FL2FXCONST_DBL(0.0f);
200     } else {
201       bwVector[i] = fixMin(accu << 1, FL2FXCONST_DBL(0.99609375f));
202     }
203   }
204 }
205 
206 /* Resulting autocorrelation determinant exponent */
207 #define ACDET_EXP \
208   (2 * (DFRACT_BITS + sbrScaleFactor->lb_scale + 10 - ac.det_scale))
209 #define AC_EXP (-sbrScaleFactor->lb_scale + LPC_SCALE_FACTOR)
210 #define ALPHA_EXP (-sbrScaleFactor->lb_scale + LPC_SCALE_FACTOR + 1)
211 /* Resulting transposed QMF values exponent 16 bit normalized samplebits
212  * assumed. */
213 #define QMFOUT_EXP ((SAMPLE_BITS - 15) - sbrScaleFactor->lb_scale)
214 
calc_qmfBufferReal(FIXP_DBL ** qmfBufferReal,const FIXP_DBL * const lowBandReal,const int startSample,const int stopSample,const UCHAR hiBand,const int dynamicScale,const FIXP_SGL a0r,const FIXP_SGL a1r)215 static inline void calc_qmfBufferReal(FIXP_DBL **qmfBufferReal,
216                                       const FIXP_DBL *const lowBandReal,
217                                       const int startSample,
218                                       const int stopSample, const UCHAR hiBand,
219                                       const int dynamicScale,
220                                       const FIXP_SGL a0r, const FIXP_SGL a1r) {
221   const int dynscale = fixMax(0, dynamicScale - 1) + 1;
222   const int rescale = -fixMin(0, dynamicScale - 1) + 1;
223   const int descale =
224       fixMin(DFRACT_BITS - 1, LPC_SCALE_FACTOR + dynamicScale + rescale);
225 
226   for (int i = 0; i < stopSample - startSample; i++) {
227     FIXP_DBL accu;
228 
229     accu = fMultDiv2(a1r, lowBandReal[i]) + fMultDiv2(a0r, lowBandReal[i + 1]);
230     accu = (lowBandReal[i + 2] >> descale) + (accu >> dynscale);
231 
232     qmfBufferReal[i + startSample][hiBand] =
233         SATURATE_LEFT_SHIFT(accu, rescale, DFRACT_BITS);
234   }
235 }
236 
237 /*!
238  *
239  * \brief Perform transposition by patching of subband samples.
240  * This function serves as the main entry point into the module. The function
241  * determines the areas for the patching process (these are the source range as
242  * well as the target range) and implements spectral whitening by means of
243  * inverse filtering. The function autoCorrelation2nd() is an auxiliary function
244  * for calculating the LPC coefficients for the filtering.  The actual
245  * calculation of the LPC coefficients and the implementation of the filtering
246  * are done as part of lppTransposer().
247  *
248  * Note that the filtering is done on all available QMF subsamples, whereas the
249  * patching is only done on those QMF subsamples that will be used in the next
250  * QMF synthesis. The filtering is also implemented before the patching includes
251  * further dependencies on parameters from the SBR data.
252  *
253  */
254 
lppTransposer(HANDLE_SBR_LPP_TRANS hLppTrans,QMF_SCALE_FACTOR * sbrScaleFactor,FIXP_DBL ** qmfBufferReal,FIXP_DBL * degreeAlias,FIXP_DBL ** qmfBufferImag,const int useLP,const int fPreWhitening,const int v_k_master0,const int timeStep,const int firstSlotOffs,const int lastSlotOffs,const int nInvfBands,INVF_MODE * sbr_invf_mode,INVF_MODE * sbr_invf_mode_prev)255 void lppTransposer(
256     HANDLE_SBR_LPP_TRANS hLppTrans,   /*!< Handle of lpp transposer  */
257     QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */
258     FIXP_DBL **qmfBufferReal, /*!< Pointer to pointer to real part of subband
259                                  samples (source) */
260 
261     FIXP_DBL *degreeAlias,    /*!< Vector for results of aliasing estimation */
262     FIXP_DBL **qmfBufferImag, /*!< Pointer to pointer to imaginary part of
263                                  subband samples (source) */
264     const int useLP, const int fPreWhitening, const int v_k_master0,
265     const int timeStep,       /*!< Time step of envelope */
266     const int firstSlotOffs,  /*!< Start position in time */
267     const int lastSlotOffs,   /*!< Number of overlap-slots into next frame */
268     const int nInvfBands,     /*!< Number of bands for inverse filtering */
269     INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */
270     INVF_MODE *sbr_invf_mode_prev /*!< Previous inverse filtering modes */
271 ) {
272   INT bwIndex[MAX_NUM_PATCHES];
273   FIXP_DBL bwVector[MAX_NUM_PATCHES]; /*!< pole moving factors */
274   FIXP_DBL preWhiteningGains[(64) / 2];
275   int preWhiteningGains_exp[(64) / 2];
276 
277   int i;
278   int loBand, start, stop;
279   TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
280   PATCH_PARAM *patchParam = pSettings->patchParam;
281   int patch;
282 
283   FIXP_SGL alphar[LPC_ORDER], a0r, a1r;
284   FIXP_SGL alphai[LPC_ORDER], a0i = 0, a1i = 0;
285   FIXP_SGL bw = FL2FXCONST_SGL(0.0f);
286 
287   int autoCorrLength;
288 
289   FIXP_DBL k1, k1_below = 0, k1_below2 = 0;
290 
291   ACORR_COEFS ac;
292   int startSample;
293   int stopSample;
294   int stopSampleClear;
295 
296   int comLowBandScale;
297   int ovLowBandShift;
298   int lowBandShift;
299   /*  int ovHighBandShift;*/
300 
301   alphai[0] = FL2FXCONST_SGL(0.0f);
302   alphai[1] = FL2FXCONST_SGL(0.0f);
303 
304   startSample = firstSlotOffs * timeStep;
305   stopSample = pSettings->nCols + lastSlotOffs * timeStep;
306   FDK_ASSERT((lastSlotOffs * timeStep) <= pSettings->overlap);
307 
308   inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode,
309                                 sbr_invf_mode_prev, bwVector);
310 
311   stopSampleClear = stopSample;
312 
313   autoCorrLength = pSettings->nCols + pSettings->overlap;
314 
315   if (pSettings->noOfPatches > 0) {
316     /* Set upper subbands to zero:
317        This is required in case that the patches do not cover the complete
318        highband (because the last patch would be too short). Possible
319        optimization: Clearing bands up to usb would be sufficient here. */
320     int targetStopBand =
321         patchParam[pSettings->noOfPatches - 1].targetStartBand +
322         patchParam[pSettings->noOfPatches - 1].numBandsInPatch;
323 
324     int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL);
325 
326     if (!useLP) {
327       for (i = startSample; i < stopSampleClear; i++) {
328         FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
329         FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize);
330       }
331     } else {
332       for (i = startSample; i < stopSampleClear; i++) {
333         FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
334       }
335     }
336   }
337 #ifdef __ANDROID__
338   else {
339     // Safetynet logging
340     android_errorWriteLog(0x534e4554, "112160868");
341   }
342 #endif
343 
344   /* init bwIndex for each patch */
345   FDKmemclear(bwIndex, sizeof(bwIndex));
346 
347   /*
348     Calc common low band scale factor
349   */
350   comLowBandScale =
351       fixMin(sbrScaleFactor->ov_lb_scale, sbrScaleFactor->lb_scale);
352 
353   ovLowBandShift = sbrScaleFactor->ov_lb_scale - comLowBandScale;
354   lowBandShift = sbrScaleFactor->lb_scale - comLowBandScale;
355   /*  ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/
356 
357   if (fPreWhitening) {
358     sbrDecoder_calculateGainVec(
359         qmfBufferReal, qmfBufferImag,
360         DFRACT_BITS - 1 - 16 -
361             sbrScaleFactor->ov_lb_scale, /* convert scale to exponent */
362         DFRACT_BITS - 1 - 16 -
363             sbrScaleFactor->lb_scale, /* convert scale to exponent */
364         pSettings->overlap, preWhiteningGains, preWhiteningGains_exp,
365         v_k_master0, startSample, stopSample);
366   }
367 
368   /* outer loop over bands to do analysis only once for each band */
369 
370   if (!useLP) {
371     start = pSettings->lbStartPatching;
372     stop = pSettings->lbStopPatching;
373   } else {
374     start = fixMax(1, pSettings->lbStartPatching - 2);
375     stop = patchParam[0].targetStartBand;
376   }
377 
378   for (loBand = start; loBand < stop; loBand++) {
379     FIXP_DBL lowBandReal[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
380     FIXP_DBL *plowBandReal = lowBandReal;
381     FIXP_DBL **pqmfBufferReal =
382         qmfBufferReal + firstSlotOffs * timeStep /* + pSettings->overlap */;
383     FIXP_DBL lowBandImag[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
384     FIXP_DBL *plowBandImag = lowBandImag;
385     FIXP_DBL **pqmfBufferImag =
386         qmfBufferImag + firstSlotOffs * timeStep /* + pSettings->overlap */;
387     int resetLPCCoeffs = 0;
388     int dynamicScale = DFRACT_BITS - 1 - LPC_SCALE_FACTOR;
389     int acDetScale = 0; /* scaling of autocorrelation determinant */
390 
391     for (i = 0;
392          i < LPC_ORDER + firstSlotOffs * timeStep /*+pSettings->overlap*/;
393          i++) {
394       *plowBandReal++ = hLppTrans->lpcFilterStatesRealLegSBR[i][loBand];
395       if (!useLP)
396         *plowBandImag++ = hLppTrans->lpcFilterStatesImagLegSBR[i][loBand];
397     }
398 
399     /*
400       Take old slope length qmf slot source values out of (overlap)qmf buffer
401     */
402     if (!useLP) {
403       for (i = 0;
404            i < pSettings->nCols + pSettings->overlap - firstSlotOffs * timeStep;
405            i++) {
406         *plowBandReal++ = (*pqmfBufferReal++)[loBand];
407         *plowBandImag++ = (*pqmfBufferImag++)[loBand];
408       }
409     } else {
410       /* pSettings->overlap is always even */
411       FDK_ASSERT((pSettings->overlap & 1) == 0);
412       for (i = 0; i < ((pSettings->nCols + pSettings->overlap -
413                         firstSlotOffs * timeStep) >>
414                        1);
415            i++) {
416         *plowBandReal++ = (*pqmfBufferReal++)[loBand];
417         *plowBandReal++ = (*pqmfBufferReal++)[loBand];
418       }
419       if (pSettings->nCols & 1) {
420         *plowBandReal++ = (*pqmfBufferReal++)[loBand];
421       }
422     }
423 
424     /*
425       Determine dynamic scaling value.
426      */
427     dynamicScale =
428         fixMin(dynamicScale,
429                getScalefactor(lowBandReal, LPC_ORDER + pSettings->overlap) +
430                    ovLowBandShift);
431     dynamicScale =
432         fixMin(dynamicScale,
433                getScalefactor(&lowBandReal[LPC_ORDER + pSettings->overlap],
434                               pSettings->nCols) +
435                    lowBandShift);
436     if (!useLP) {
437       dynamicScale =
438           fixMin(dynamicScale,
439                  getScalefactor(lowBandImag, LPC_ORDER + pSettings->overlap) +
440                      ovLowBandShift);
441       dynamicScale =
442           fixMin(dynamicScale,
443                  getScalefactor(&lowBandImag[LPC_ORDER + pSettings->overlap],
444                                 pSettings->nCols) +
445                      lowBandShift);
446     }
447 
448     if (dynamicScale == 0) {
449       /* In this special case the available headroom bits as well as
450          ovLowBandShift and lowBandShift are zero. The spectrum is limited to
451          prevent -1.0, so negative values for dynamicScale can be avoided. */
452       for (i = 0; i < (LPC_ORDER + pSettings->overlap + pSettings->nCols);
453            i++) {
454         lowBandReal[i] = fixMax(lowBandReal[i], (FIXP_DBL)0x80000001);
455       }
456       if (!useLP) {
457         for (i = 0; i < (LPC_ORDER + pSettings->overlap + pSettings->nCols);
458              i++) {
459           lowBandImag[i] = fixMax(lowBandImag[i], (FIXP_DBL)0x80000001);
460         }
461       }
462     } else {
463       dynamicScale =
464           fixMax(0, dynamicScale -
465                         1); /* one additional bit headroom to prevent -1.0 */
466     }
467 
468     /*
469       Scale temporal QMF buffer.
470      */
471     scaleValues(&lowBandReal[0], LPC_ORDER + pSettings->overlap,
472                 dynamicScale - ovLowBandShift);
473     scaleValues(&lowBandReal[LPC_ORDER + pSettings->overlap], pSettings->nCols,
474                 dynamicScale - lowBandShift);
475 
476     if (!useLP) {
477       scaleValues(&lowBandImag[0], LPC_ORDER + pSettings->overlap,
478                   dynamicScale - ovLowBandShift);
479       scaleValues(&lowBandImag[LPC_ORDER + pSettings->overlap],
480                   pSettings->nCols, dynamicScale - lowBandShift);
481     }
482 
483     if (!useLP) {
484       acDetScale += autoCorr2nd_cplx(&ac, lowBandReal + LPC_ORDER,
485                                      lowBandImag + LPC_ORDER, autoCorrLength);
486     } else {
487       acDetScale +=
488           autoCorr2nd_real(&ac, lowBandReal + LPC_ORDER, autoCorrLength);
489     }
490 
491     /* Examine dynamic of determinant in autocorrelation. */
492     acDetScale += 2 * (comLowBandScale + dynamicScale);
493     acDetScale *= 2;            /* two times reflection coefficent scaling */
494     acDetScale += ac.det_scale; /* ac scaling of determinant */
495 
496     /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */
497     if (acDetScale > 126) {
498       resetLPCCoeffs = 1;
499     }
500 
501     alphar[1] = FL2FXCONST_SGL(0.0f);
502     if (!useLP) alphai[1] = FL2FXCONST_SGL(0.0f);
503 
504     if (ac.det != FL2FXCONST_DBL(0.0f)) {
505       FIXP_DBL tmp, absTmp, absDet;
506 
507       absDet = fixp_abs(ac.det);
508 
509       if (!useLP) {
510         tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) -
511               ((fMultDiv2(ac.r01i, ac.r12i) + fMultDiv2(ac.r02r, ac.r11r)) >>
512                (LPC_SCALE_FACTOR - 1));
513       } else {
514         tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) -
515               (fMultDiv2(ac.r02r, ac.r11r) >> (LPC_SCALE_FACTOR - 1));
516       }
517       absTmp = fixp_abs(tmp);
518 
519       /*
520         Quick check: is first filter coeff >= 1(4)
521        */
522       {
523         INT scale;
524         FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
525         scale = scale + ac.det_scale;
526 
527         if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) {
528           resetLPCCoeffs = 1;
529         } else {
530           alphar[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
531           if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
532             alphar[1] = -alphar[1];
533           }
534         }
535       }
536 
537       if (!useLP) {
538         tmp = (fMultDiv2(ac.r01i, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) +
539               ((fMultDiv2(ac.r01r, ac.r12i) -
540                 (FIXP_DBL)fMultDiv2(ac.r02i, ac.r11r)) >>
541                (LPC_SCALE_FACTOR - 1));
542 
543         absTmp = fixp_abs(tmp);
544 
545         /*
546         Quick check: is second filter coeff >= 1(4)
547         */
548         {
549           INT scale;
550           FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
551           scale = scale + ac.det_scale;
552 
553           if ((scale > 0) &&
554               (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >>
555                scale)) {
556             resetLPCCoeffs = 1;
557           } else {
558             alphai[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
559             if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
560               alphai[1] = -alphai[1];
561             }
562           }
563         }
564       }
565     }
566 
567     alphar[0] = FL2FXCONST_SGL(0.0f);
568     if (!useLP) alphai[0] = FL2FXCONST_SGL(0.0f);
569 
570     if (ac.r11r != FL2FXCONST_DBL(0.0f)) {
571       /* ac.r11r is always >=0 */
572       FIXP_DBL tmp, absTmp;
573 
574       if (!useLP) {
575         tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) +
576               (fMultDiv2(alphar[1], ac.r12r) + fMultDiv2(alphai[1], ac.r12i));
577       } else {
578         if (ac.r01r >= FL2FXCONST_DBL(0.0f))
579           tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) +
580                 fMultDiv2(alphar[1], ac.r12r);
581         else
582           tmp = -((-ac.r01r) >> (LPC_SCALE_FACTOR + 1)) +
583                 fMultDiv2(alphar[1], ac.r12r);
584       }
585 
586       absTmp = fixp_abs(tmp);
587 
588       /*
589         Quick check: is first filter coeff >= 1(4)
590       */
591 
592       if (absTmp >= (ac.r11r >> 1)) {
593         resetLPCCoeffs = 1;
594       } else {
595         INT scale;
596         FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
597         alphar[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
598 
599         if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
600           alphar[0] = -alphar[0];
601       }
602 
603       if (!useLP) {
604         tmp = (ac.r01i >> (LPC_SCALE_FACTOR + 1)) +
605               (fMultDiv2(alphai[1], ac.r12r) - fMultDiv2(alphar[1], ac.r12i));
606 
607         absTmp = fixp_abs(tmp);
608 
609         /*
610         Quick check: is second filter coeff >= 1(4)
611         */
612         if (absTmp >= (ac.r11r >> 1)) {
613           resetLPCCoeffs = 1;
614         } else {
615           INT scale;
616           FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
617           alphai[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
618           if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
619             alphai[0] = -alphai[0];
620         }
621       }
622     }
623 
624     if (!useLP) {
625       /* Now check the quadratic criteria */
626       if ((fMultDiv2(alphar[0], alphar[0]) + fMultDiv2(alphai[0], alphai[0])) >=
627           FL2FXCONST_DBL(0.5f))
628         resetLPCCoeffs = 1;
629       if ((fMultDiv2(alphar[1], alphar[1]) + fMultDiv2(alphai[1], alphai[1])) >=
630           FL2FXCONST_DBL(0.5f))
631         resetLPCCoeffs = 1;
632     }
633 
634     if (resetLPCCoeffs) {
635       alphar[0] = FL2FXCONST_SGL(0.0f);
636       alphar[1] = FL2FXCONST_SGL(0.0f);
637       if (!useLP) {
638         alphai[0] = FL2FXCONST_SGL(0.0f);
639         alphai[1] = FL2FXCONST_SGL(0.0f);
640       }
641     }
642 
643     if (useLP) {
644       /* Aliasing detection */
645       if (ac.r11r == FL2FXCONST_DBL(0.0f)) {
646         k1 = FL2FXCONST_DBL(0.0f);
647       } else {
648         if (fixp_abs(ac.r01r) >= fixp_abs(ac.r11r)) {
649           if (fMultDiv2(ac.r01r, ac.r11r) < FL2FX_DBL(0.0f)) {
650             k1 = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_SGL(1.0f)*/;
651           } else {
652             /* Since this value is squared later, it must not ever become -1.0f.
653              */
654             k1 = (FIXP_DBL)(MINVAL_DBL + 1) /*FL2FXCONST_SGL(-1.0f)*/;
655           }
656         } else {
657           INT scale;
658           FIXP_DBL result =
659               fDivNorm(fixp_abs(ac.r01r), fixp_abs(ac.r11r), &scale);
660           k1 = scaleValueSaturate(result, scale);
661 
662           if (!((ac.r01r < FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))) {
663             k1 = -k1;
664           }
665         }
666       }
667       if ((loBand > 1) && (loBand < v_k_master0)) {
668         /* Check if the gain should be locked */
669         FIXP_DBL deg =
670             /*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - fPow2(k1_below);
671         degreeAlias[loBand] = FL2FXCONST_DBL(0.0f);
672         if (((loBand & 1) == 0) && (k1 < FL2FXCONST_DBL(0.0f))) {
673           if (k1_below < FL2FXCONST_DBL(0.0f)) { /* 2-Ch Aliasing Detection */
674             degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/;
675             if (k1_below2 >
676                 FL2FXCONST_DBL(0.0f)) { /* 3-Ch Aliasing Detection */
677               degreeAlias[loBand - 1] = deg;
678             }
679           } else if (k1_below2 >
680                      FL2FXCONST_DBL(0.0f)) { /* 3-Ch Aliasing Detection */
681             degreeAlias[loBand] = deg;
682           }
683         }
684         if (((loBand & 1) == 1) && (k1 > FL2FXCONST_DBL(0.0f))) {
685           if (k1_below > FL2FXCONST_DBL(0.0f)) { /* 2-CH Aliasing Detection */
686             degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/;
687             if (k1_below2 <
688                 FL2FXCONST_DBL(0.0f)) { /* 3-CH Aliasing Detection */
689               degreeAlias[loBand - 1] = deg;
690             }
691           } else if (k1_below2 <
692                      FL2FXCONST_DBL(0.0f)) { /* 3-CH Aliasing Detection */
693             degreeAlias[loBand] = deg;
694           }
695         }
696       }
697       /* remember k1 values of the 2 QMF channels below the current channel */
698       k1_below2 = k1_below;
699       k1_below = k1;
700     }
701 
702     patch = 0;
703 
704     while (patch < pSettings->noOfPatches) { /* inner loop over every patch */
705 
706       int hiBand = loBand + patchParam[patch].targetBandOffs;
707 
708       if (loBand < patchParam[patch].sourceStartBand ||
709           loBand >= patchParam[patch].sourceStopBand
710           //|| hiBand >= hLppTrans->pSettings->noChannels
711       ) {
712         /* Lowband not in current patch - proceed */
713         patch++;
714         continue;
715       }
716 
717       FDK_ASSERT(hiBand < (64));
718 
719       /* bwIndex[patch] is already initialized with value from previous band
720        * inside this patch */
721       while (hiBand >= pSettings->bwBorders[bwIndex[patch]] &&
722              bwIndex[patch] < MAX_NUM_PATCHES - 1) {
723         bwIndex[patch]++;
724       }
725 
726       /*
727         Filter Step 2: add the left slope with the current filter to the buffer
728                        pure source values are already in there
729       */
730       bw = FX_DBL2FX_SGL(bwVector[bwIndex[patch]]);
731 
732       a0r = FX_DBL2FX_SGL(
733           fMult(bw, alphar[0])); /* Apply current bandwidth expansion factor */
734 
735       if (!useLP) a0i = FX_DBL2FX_SGL(fMult(bw, alphai[0]));
736       bw = FX_DBL2FX_SGL(fPow2(bw));
737       a1r = FX_DBL2FX_SGL(fMult(bw, alphar[1]));
738       if (!useLP) a1i = FX_DBL2FX_SGL(fMult(bw, alphai[1]));
739 
740       /*
741         Filter Step 3: insert the middle part which won't be windowed
742       */
743       if (bw <= FL2FXCONST_SGL(0.0f)) {
744         if (!useLP) {
745           int descale =
746               fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
747           for (i = startSample; i < stopSample; i++) {
748             FIXP_DBL accu1, accu2;
749             accu1 = lowBandReal[LPC_ORDER + i] >> descale;
750             accu2 = lowBandImag[LPC_ORDER + i] >> descale;
751             if (fPreWhitening) {
752               accu1 = scaleValueSaturate(
753                   fMultDiv2(accu1, preWhiteningGains[loBand]),
754                   preWhiteningGains_exp[loBand] + 1);
755               accu2 = scaleValueSaturate(
756                   fMultDiv2(accu2, preWhiteningGains[loBand]),
757                   preWhiteningGains_exp[loBand] + 1);
758             }
759             qmfBufferReal[i][hiBand] = accu1;
760             qmfBufferImag[i][hiBand] = accu2;
761           }
762         } else {
763           int descale =
764               fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
765           for (i = startSample; i < stopSample; i++) {
766             qmfBufferReal[i][hiBand] = lowBandReal[LPC_ORDER + i] >> descale;
767           }
768         }
769       } else { /* bw <= 0 */
770 
771         if (!useLP) {
772           const int dynscale = fixMax(0, dynamicScale - 2) + 1;
773           const int rescale = -fixMin(0, dynamicScale - 2) + 1;
774           const int descale = fixMin(DFRACT_BITS - 1,
775                                      LPC_SCALE_FACTOR + dynamicScale + rescale);
776 
777           for (i = startSample; i < stopSample; i++) {
778             FIXP_DBL accu1, accu2;
779 
780             accu1 = ((fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) -
781                       fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1])) >>
782                      1) +
783                     ((fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) -
784                       fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >>
785                      1);
786             accu2 = ((fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) +
787                       fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1])) >>
788                      1) +
789                     ((fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) +
790                       fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >>
791                      1);
792 
793             accu1 =
794                 (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 >> dynscale);
795             accu2 =
796                 (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 >> dynscale);
797             if (fPreWhitening) {
798               qmfBufferReal[i][hiBand] = scaleValueSaturate(
799                   fMultDiv2(accu1, preWhiteningGains[loBand]),
800                   preWhiteningGains_exp[loBand] + 1 + rescale);
801               qmfBufferImag[i][hiBand] = scaleValueSaturate(
802                   fMultDiv2(accu2, preWhiteningGains[loBand]),
803                   preWhiteningGains_exp[loBand] + 1 + rescale);
804             } else {
805               qmfBufferReal[i][hiBand] =
806                   SATURATE_LEFT_SHIFT(accu1, rescale, DFRACT_BITS);
807               qmfBufferImag[i][hiBand] =
808                   SATURATE_LEFT_SHIFT(accu2, rescale, DFRACT_BITS);
809             }
810           }
811         } else {
812           FDK_ASSERT(dynamicScale >= 0);
813           calc_qmfBufferReal(
814               qmfBufferReal, &(lowBandReal[LPC_ORDER + startSample - 2]),
815               startSample, stopSample, hiBand, dynamicScale, a0r, a1r);
816         }
817       } /* bw <= 0 */
818 
819       patch++;
820 
821     } /* inner loop over patches */
822 
823     /*
824      * store the unmodified filter coefficients if there is
825      * an overlapping envelope
826      *****************************************************************/
827 
828   } /* outer loop over bands (loBand) */
829 
830   if (useLP) {
831     for (loBand = pSettings->lbStartPatching;
832          loBand < pSettings->lbStopPatching; loBand++) {
833       patch = 0;
834       while (patch < pSettings->noOfPatches) {
835         UCHAR hiBand = loBand + patchParam[patch].targetBandOffs;
836 
837         if (loBand < patchParam[patch].sourceStartBand ||
838             loBand >= patchParam[patch].sourceStopBand ||
839             hiBand >= (64) /* Highband out of range (biterror) */
840         ) {
841           /* Lowband not in current patch or highband out of range (might be
842            * caused by biterrors)- proceed */
843           patch++;
844           continue;
845         }
846 
847         if (hiBand != patchParam[patch].targetStartBand)
848           degreeAlias[hiBand] = degreeAlias[loBand];
849 
850         patch++;
851       }
852     } /* end  for loop */
853   }
854 
855   for (i = 0; i < nInvfBands; i++) {
856     hLppTrans->bwVectorOld[i] = bwVector[i];
857   }
858 
859   /*
860     set high band scale factor
861   */
862   sbrScaleFactor->hb_scale = comLowBandScale - (LPC_SCALE_FACTOR);
863 }
864 
lppTransposerHBE(HANDLE_SBR_LPP_TRANS hLppTrans,HANDLE_HBE_TRANSPOSER hQmfTransposer,QMF_SCALE_FACTOR * sbrScaleFactor,FIXP_DBL ** qmfBufferReal,FIXP_DBL ** qmfBufferImag,const int timeStep,const int firstSlotOffs,const int lastSlotOffs,const int nInvfBands,INVF_MODE * sbr_invf_mode,INVF_MODE * sbr_invf_mode_prev)865 void lppTransposerHBE(
866     HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer  */
867     HANDLE_HBE_TRANSPOSER hQmfTransposer,
868     QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */
869     FIXP_DBL **qmfBufferReal, /*!< Pointer to pointer to real part of subband
870                                  samples (source) */
871     FIXP_DBL **qmfBufferImag, /*!< Pointer to pointer to imaginary part of
872                                  subband samples (source) */
873     const int timeStep,       /*!< Time step of envelope */
874     const int firstSlotOffs,  /*!< Start position in time */
875     const int lastSlotOffs,   /*!< Number of overlap-slots into next frame */
876     const int nInvfBands,     /*!< Number of bands for inverse filtering */
877     INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */
878     INVF_MODE *sbr_invf_mode_prev /*!< Previous inverse filtering modes */
879 ) {
880   INT bwIndex;
881   FIXP_DBL bwVector[MAX_NUM_PATCHES_HBE]; /*!< pole moving factors */
882 
883   int i;
884   int loBand, start, stop;
885   TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
886   PATCH_PARAM *patchParam = pSettings->patchParam;
887 
888   FIXP_SGL alphar[LPC_ORDER], a0r, a1r;
889   FIXP_SGL alphai[LPC_ORDER], a0i = 0, a1i = 0;
890   FIXP_SGL bw = FL2FXCONST_SGL(0.0f);
891 
892   int autoCorrLength;
893 
894   ACORR_COEFS ac;
895   int startSample;
896   int stopSample;
897   int stopSampleClear;
898 
899   int comBandScale;
900   int ovLowBandShift;
901   int lowBandShift;
902   /*  int ovHighBandShift;*/
903 
904   alphai[0] = FL2FXCONST_SGL(0.0f);
905   alphai[1] = FL2FXCONST_SGL(0.0f);
906 
907   startSample = firstSlotOffs * timeStep;
908   stopSample = pSettings->nCols + lastSlotOffs * timeStep;
909 
910   inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode,
911                                 sbr_invf_mode_prev, bwVector);
912 
913   stopSampleClear = stopSample;
914 
915   autoCorrLength = pSettings->nCols + pSettings->overlap;
916 
917   if (pSettings->noOfPatches > 0) {
918     /* Set upper subbands to zero:
919        This is required in case that the patches do not cover the complete
920        highband (because the last patch would be too short). Possible
921        optimization: Clearing bands up to usb would be sufficient here. */
922     int targetStopBand =
923         patchParam[pSettings->noOfPatches - 1].targetStartBand +
924         patchParam[pSettings->noOfPatches - 1].numBandsInPatch;
925 
926     int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL);
927 
928     for (i = startSample; i < stopSampleClear; i++) {
929       FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
930       FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize);
931     }
932   }
933 #ifdef __ANDROID__
934   else {
935     // Safetynet logging
936     android_errorWriteLog(0x534e4554, "112160868");
937   }
938 #endif
939 
940   /*
941   Calc common low band scale factor
942   */
943   comBandScale = sbrScaleFactor->hb_scale;
944 
945   ovLowBandShift = sbrScaleFactor->hb_scale - comBandScale;
946   lowBandShift = sbrScaleFactor->hb_scale - comBandScale;
947   /*  ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/
948 
949   /* outer loop over bands to do analysis only once for each band */
950 
951   start = hQmfTransposer->startBand;
952   stop = hQmfTransposer->stopBand;
953 
954   for (loBand = start; loBand < stop; loBand++) {
955     bwIndex = 0;
956 
957     FIXP_DBL lowBandReal[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
958     FIXP_DBL lowBandImag[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
959 
960     int resetLPCCoeffs = 0;
961     int dynamicScale = DFRACT_BITS - 1 - LPC_SCALE_FACTOR;
962     int acDetScale = 0; /* scaling of autocorrelation determinant */
963 
964     for (i = 0; i < LPC_ORDER; i++) {
965       lowBandReal[i] = hLppTrans->lpcFilterStatesRealHBE[i][loBand];
966       lowBandImag[i] = hLppTrans->lpcFilterStatesImagHBE[i][loBand];
967     }
968 
969     for (; i < LPC_ORDER + firstSlotOffs * timeStep; i++) {
970       lowBandReal[i] = hLppTrans->lpcFilterStatesRealHBE[i][loBand];
971       lowBandImag[i] = hLppTrans->lpcFilterStatesImagHBE[i][loBand];
972     }
973 
974     /*
975     Take old slope length qmf slot source values out of (overlap)qmf buffer
976     */
977     for (i = firstSlotOffs * timeStep;
978          i < pSettings->nCols + pSettings->overlap; i++) {
979       lowBandReal[i + LPC_ORDER] = qmfBufferReal[i][loBand];
980       lowBandImag[i + LPC_ORDER] = qmfBufferImag[i][loBand];
981     }
982 
983     /* store unmodified values to buffer */
984     for (i = 0; i < LPC_ORDER + pSettings->overlap; i++) {
985       hLppTrans->lpcFilterStatesRealHBE[i][loBand] =
986           qmfBufferReal[pSettings->nCols - LPC_ORDER + i][loBand];
987       hLppTrans->lpcFilterStatesImagHBE[i][loBand] =
988           qmfBufferImag[pSettings->nCols - LPC_ORDER + i][loBand];
989     }
990 
991     /*
992     Determine dynamic scaling value.
993     */
994     dynamicScale =
995         fixMin(dynamicScale,
996                getScalefactor(lowBandReal, LPC_ORDER + pSettings->overlap) +
997                    ovLowBandShift);
998     dynamicScale =
999         fixMin(dynamicScale,
1000                getScalefactor(&lowBandReal[LPC_ORDER + pSettings->overlap],
1001                               pSettings->nCols) +
1002                    lowBandShift);
1003     dynamicScale =
1004         fixMin(dynamicScale,
1005                getScalefactor(lowBandImag, LPC_ORDER + pSettings->overlap) +
1006                    ovLowBandShift);
1007     dynamicScale =
1008         fixMin(dynamicScale,
1009                getScalefactor(&lowBandImag[LPC_ORDER + pSettings->overlap],
1010                               pSettings->nCols) +
1011                    lowBandShift);
1012 
1013     dynamicScale =
1014         dynamicScale - 1; /* one additional bit headroom to prevent -1.0 */
1015 
1016     /*
1017     Scale temporal QMF buffer.
1018     */
1019     scaleValues(&lowBandReal[0], LPC_ORDER + pSettings->overlap,
1020                 dynamicScale - ovLowBandShift);
1021     scaleValues(&lowBandReal[LPC_ORDER + pSettings->overlap], pSettings->nCols,
1022                 dynamicScale - lowBandShift);
1023     scaleValues(&lowBandImag[0], LPC_ORDER + pSettings->overlap,
1024                 dynamicScale - ovLowBandShift);
1025     scaleValues(&lowBandImag[LPC_ORDER + pSettings->overlap], pSettings->nCols,
1026                 dynamicScale - lowBandShift);
1027 
1028     acDetScale += autoCorr2nd_cplx(&ac, lowBandReal + LPC_ORDER,
1029                                    lowBandImag + LPC_ORDER, autoCorrLength);
1030 
1031     /* Examine dynamic of determinant in autocorrelation. */
1032     acDetScale += 2 * (comBandScale + dynamicScale);
1033     acDetScale *= 2;            /* two times reflection coefficent scaling */
1034     acDetScale += ac.det_scale; /* ac scaling of determinant */
1035 
1036     /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */
1037     if (acDetScale > 126) {
1038       resetLPCCoeffs = 1;
1039     }
1040 
1041     alphar[1] = FL2FXCONST_SGL(0.0f);
1042     alphai[1] = FL2FXCONST_SGL(0.0f);
1043 
1044     if (ac.det != FL2FXCONST_DBL(0.0f)) {
1045       FIXP_DBL tmp, absTmp, absDet;
1046 
1047       absDet = fixp_abs(ac.det);
1048 
1049       tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) -
1050             ((fMultDiv2(ac.r01i, ac.r12i) + fMultDiv2(ac.r02r, ac.r11r)) >>
1051              (LPC_SCALE_FACTOR - 1));
1052       absTmp = fixp_abs(tmp);
1053 
1054       /*
1055       Quick check: is first filter coeff >= 1(4)
1056       */
1057       {
1058         INT scale;
1059         FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
1060         scale = scale + ac.det_scale;
1061 
1062         if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) {
1063           resetLPCCoeffs = 1;
1064         } else {
1065           alphar[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
1066           if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
1067             alphar[1] = -alphar[1];
1068           }
1069         }
1070       }
1071 
1072       tmp = (fMultDiv2(ac.r01i, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) +
1073             ((fMultDiv2(ac.r01r, ac.r12i) -
1074               (FIXP_DBL)fMultDiv2(ac.r02i, ac.r11r)) >>
1075              (LPC_SCALE_FACTOR - 1));
1076 
1077       absTmp = fixp_abs(tmp);
1078 
1079       /*
1080       Quick check: is second filter coeff >= 1(4)
1081       */
1082       {
1083         INT scale;
1084         FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
1085         scale = scale + ac.det_scale;
1086 
1087         if ((scale > 0) &&
1088             (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >> scale)) {
1089           resetLPCCoeffs = 1;
1090         } else {
1091           alphai[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
1092           if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
1093             alphai[1] = -alphai[1];
1094           }
1095         }
1096       }
1097     }
1098 
1099     alphar[0] = FL2FXCONST_SGL(0.0f);
1100     alphai[0] = FL2FXCONST_SGL(0.0f);
1101 
1102     if (ac.r11r != FL2FXCONST_DBL(0.0f)) {
1103       /* ac.r11r is always >=0 */
1104       FIXP_DBL tmp, absTmp;
1105 
1106       tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) +
1107             (fMultDiv2(alphar[1], ac.r12r) + fMultDiv2(alphai[1], ac.r12i));
1108 
1109       absTmp = fixp_abs(tmp);
1110 
1111       /*
1112       Quick check: is first filter coeff >= 1(4)
1113       */
1114 
1115       if (absTmp >= (ac.r11r >> 1)) {
1116         resetLPCCoeffs = 1;
1117       } else {
1118         INT scale;
1119         FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
1120         alphar[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
1121 
1122         if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
1123           alphar[0] = -alphar[0];
1124       }
1125 
1126       tmp = (ac.r01i >> (LPC_SCALE_FACTOR + 1)) +
1127             (fMultDiv2(alphai[1], ac.r12r) - fMultDiv2(alphar[1], ac.r12i));
1128 
1129       absTmp = fixp_abs(tmp);
1130 
1131       /*
1132       Quick check: is second filter coeff >= 1(4)
1133       */
1134       if (absTmp >= (ac.r11r >> 1)) {
1135         resetLPCCoeffs = 1;
1136       } else {
1137         INT scale;
1138         FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
1139         alphai[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
1140         if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) {
1141           alphai[0] = -alphai[0];
1142         }
1143       }
1144     }
1145 
1146     /* Now check the quadratic criteria */
1147     if ((fMultDiv2(alphar[0], alphar[0]) + fMultDiv2(alphai[0], alphai[0])) >=
1148         FL2FXCONST_DBL(0.5f)) {
1149       resetLPCCoeffs = 1;
1150     }
1151     if ((fMultDiv2(alphar[1], alphar[1]) + fMultDiv2(alphai[1], alphai[1])) >=
1152         FL2FXCONST_DBL(0.5f)) {
1153       resetLPCCoeffs = 1;
1154     }
1155 
1156     if (resetLPCCoeffs) {
1157       alphar[0] = FL2FXCONST_SGL(0.0f);
1158       alphar[1] = FL2FXCONST_SGL(0.0f);
1159       alphai[0] = FL2FXCONST_SGL(0.0f);
1160       alphai[1] = FL2FXCONST_SGL(0.0f);
1161     }
1162 
1163     while (bwIndex < MAX_NUM_PATCHES - 1 &&
1164            loBand >= pSettings->bwBorders[bwIndex]) {
1165       bwIndex++;
1166     }
1167 
1168     /*
1169     Filter Step 2: add the left slope with the current filter to the buffer
1170     pure source values are already in there
1171     */
1172     bw = FX_DBL2FX_SGL(bwVector[bwIndex]);
1173 
1174     a0r = FX_DBL2FX_SGL(
1175         fMult(bw, alphar[0])); /* Apply current bandwidth expansion factor */
1176     a0i = FX_DBL2FX_SGL(fMult(bw, alphai[0]));
1177     bw = FX_DBL2FX_SGL(fPow2(bw));
1178     a1r = FX_DBL2FX_SGL(fMult(bw, alphar[1]));
1179     a1i = FX_DBL2FX_SGL(fMult(bw, alphai[1]));
1180 
1181     /*
1182     Filter Step 3: insert the middle part which won't be windowed
1183     */
1184     if (bw <= FL2FXCONST_SGL(0.0f)) {
1185       int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
1186       for (i = startSample; i < stopSample; i++) {
1187         qmfBufferReal[i][loBand] = lowBandReal[LPC_ORDER + i] >> descale;
1188         qmfBufferImag[i][loBand] = lowBandImag[LPC_ORDER + i] >> descale;
1189       }
1190     } else { /* bw <= 0 */
1191 
1192       int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
1193       dynamicScale +=
1194           1; /* prevent negativ scale factor due to 'one additional bit
1195                 headroom' */
1196 
1197       for (i = startSample; i < stopSample; i++) {
1198         FIXP_DBL accu1, accu2;
1199 
1200         accu1 = (fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) -
1201                  fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1]) +
1202                  fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) -
1203                  fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >>
1204                 dynamicScale;
1205         accu2 = (fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) +
1206                  fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1]) +
1207                  fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) +
1208                  fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >>
1209                 dynamicScale;
1210 
1211         qmfBufferReal[i][loBand] =
1212             (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << (1 + 1));
1213         qmfBufferImag[i][loBand] =
1214             (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << (1 + 1));
1215       }
1216     } /* bw <= 0 */
1217 
1218     /*
1219      * store the unmodified filter coefficients if there is
1220      * an overlapping envelope
1221      *****************************************************************/
1222 
1223   } /* outer loop over bands (loBand) */
1224 
1225   for (i = 0; i < nInvfBands; i++) {
1226     hLppTrans->bwVectorOld[i] = bwVector[i];
1227   }
1228 
1229   /*
1230   set high band scale factor
1231   */
1232   sbrScaleFactor->hb_scale = comBandScale - (LPC_SCALE_FACTOR);
1233 }
1234 
1235 /*!
1236  *
1237  * \brief Initialize one low power transposer instance
1238  *
1239  *
1240  */
1241 SBR_ERROR
createLppTransposer(HANDLE_SBR_LPP_TRANS hs,TRANSPOSER_SETTINGS * pSettings,const int highBandStartSb,UCHAR * v_k_master,const int numMaster,const int usb,const int timeSlots,const int nCols,UCHAR * noiseBandTable,const int noNoiseBands,UINT fs,const int chan,const int overlap)1242 createLppTransposer(
1243     HANDLE_SBR_LPP_TRANS hs,        /*!< Handle of low power transposer  */
1244     TRANSPOSER_SETTINGS *pSettings, /*!< Pointer to settings */
1245     const int highBandStartSb,      /*!< ? */
1246     UCHAR *v_k_master,              /*!< Master table */
1247     const int numMaster,            /*!< Valid entries in master table */
1248     const int usb,                  /*!< Highband area stop subband */
1249     const int timeSlots,            /*!< Number of time slots */
1250     const int nCols,                /*!< Number of colums (codec qmf bank) */
1251     UCHAR *noiseBandTable,  /*!< Mapping of SBR noise bands to QMF bands */
1252     const int noNoiseBands, /*!< Number of noise bands */
1253     UINT fs,                /*!< Sample Frequency */
1254     const int chan,         /*!< Channel number */
1255     const int overlap) {
1256   /* FB inverse filtering settings */
1257   hs->pSettings = pSettings;
1258 
1259   pSettings->nCols = nCols;
1260   pSettings->overlap = overlap;
1261 
1262   switch (timeSlots) {
1263     case 15:
1264     case 16:
1265       break;
1266 
1267     default:
1268       return SBRDEC_UNSUPPORTED_CONFIG; /* Unimplemented */
1269   }
1270 
1271   if (chan == 0) {
1272     /* Init common data only once */
1273     hs->pSettings->nCols = nCols;
1274 
1275     return resetLppTransposer(hs, highBandStartSb, v_k_master, numMaster,
1276                               noiseBandTable, noNoiseBands, usb, fs);
1277   }
1278   return SBRDEC_OK;
1279 }
1280 
findClosestEntry(UCHAR goalSb,UCHAR * v_k_master,UCHAR numMaster,UCHAR direction)1281 static int findClosestEntry(UCHAR goalSb, UCHAR *v_k_master, UCHAR numMaster,
1282                             UCHAR direction) {
1283   int index;
1284 
1285   if (goalSb <= v_k_master[0]) return v_k_master[0];
1286 
1287   if (goalSb >= v_k_master[numMaster]) return v_k_master[numMaster];
1288 
1289   if (direction) {
1290     index = 0;
1291     while (v_k_master[index] < goalSb) {
1292       index++;
1293     }
1294   } else {
1295     index = numMaster;
1296     while (v_k_master[index] > goalSb) {
1297       index--;
1298     }
1299   }
1300 
1301   return v_k_master[index];
1302 }
1303 
1304 /*!
1305  *
1306  * \brief Reset memory for one lpp transposer instance
1307  *
1308  * \return SBRDEC_OK on success, SBRDEC_UNSUPPORTED_CONFIG on error
1309  */
1310 SBR_ERROR
resetLppTransposer(HANDLE_SBR_LPP_TRANS hLppTrans,UCHAR highBandStartSb,UCHAR * v_k_master,UCHAR numMaster,UCHAR * noiseBandTable,UCHAR noNoiseBands,UCHAR usb,UINT fs)1311 resetLppTransposer(
1312     HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer  */
1313     UCHAR highBandStartSb,          /*!< High band area: start subband */
1314     UCHAR *v_k_master,              /*!< Master table */
1315     UCHAR numMaster,                /*!< Valid entries in master table */
1316     UCHAR *noiseBandTable, /*!< Mapping of SBR noise bands to QMF bands */
1317     UCHAR noNoiseBands,    /*!< Number of noise bands */
1318     UCHAR usb,             /*!< High band area: stop subband */
1319     UINT fs                /*!< SBR output sampling frequency */
1320 ) {
1321   TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
1322   PATCH_PARAM *patchParam = pSettings->patchParam;
1323 
1324   int i, patch;
1325   int targetStopBand;
1326   int sourceStartBand;
1327   int patchDistance;
1328   int numBandsInPatch;
1329 
1330   int lsb = v_k_master[0]; /* Start subband expressed in "non-critical" sampling
1331                               terms*/
1332   int xoverOffset = highBandStartSb -
1333                     lsb; /* Calculate distance in QMF bands between k0 and kx */
1334   int startFreqHz;
1335 
1336   int desiredBorder;
1337 
1338   usb = fixMin(usb, v_k_master[numMaster]); /* Avoid endless loops (compare with
1339                                                float code). */
1340 
1341   /*
1342    * Plausibility check
1343    */
1344 
1345   if (pSettings->nCols == 64) {
1346     if (lsb < 4) {
1347       /* 4:1 SBR Requirement k0 >= 4 missed! */
1348       return SBRDEC_UNSUPPORTED_CONFIG;
1349     }
1350   } else if (lsb - SHIFT_START_SB < 4) {
1351     return SBRDEC_UNSUPPORTED_CONFIG;
1352   }
1353 
1354   /*
1355    * Initialize the patching parameter
1356    */
1357   /* ISO/IEC 14496-3 (Figure 4.48): goalSb = round( 2.048e6 / fs ) */
1358   desiredBorder = (((2048000 * 2) / fs) + 1) >> 1;
1359 
1360   desiredBorder = findClosestEntry(desiredBorder, v_k_master, numMaster,
1361                                    1); /* Adapt region to master-table */
1362 
1363   /* First patch */
1364   sourceStartBand = SHIFT_START_SB + xoverOffset;
1365   targetStopBand = lsb + xoverOffset; /* upperBand */
1366 
1367   /* Even (odd) numbered channel must be patched to even (odd) numbered channel
1368    */
1369   patch = 0;
1370   while (targetStopBand < usb) {
1371     /* Too many patches?
1372        Allow MAX_NUM_PATCHES+1 patches here.
1373        we need to check later again, since patch might be the highest patch
1374        AND contain less than 3 bands => actual number of patches will be reduced
1375        by 1.
1376     */
1377     if (patch > MAX_NUM_PATCHES) {
1378       return SBRDEC_UNSUPPORTED_CONFIG;
1379     }
1380 
1381     patchParam[patch].guardStartBand = targetStopBand;
1382     patchParam[patch].targetStartBand = targetStopBand;
1383 
1384     numBandsInPatch =
1385         desiredBorder - targetStopBand; /* Get the desired range of the patch */
1386 
1387     if (numBandsInPatch >= lsb - sourceStartBand) {
1388       /* Desired number bands are not available -> patch whole source range */
1389       patchDistance =
1390           targetStopBand - sourceStartBand; /* Get the targetOffset */
1391       patchDistance =
1392           patchDistance & ~1; /* Rounding off odd numbers and make all even */
1393       numBandsInPatch =
1394           lsb - (targetStopBand -
1395                  patchDistance); /* Update number of bands to be patched */
1396       numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch,
1397                                          v_k_master, numMaster, 0) -
1398                         targetStopBand; /* Adapt region to master-table */
1399     }
1400 
1401     if (pSettings->nCols == 64) {
1402       if (numBandsInPatch == 0 && sourceStartBand == SHIFT_START_SB) {
1403         return SBRDEC_UNSUPPORTED_CONFIG;
1404       }
1405     }
1406 
1407     /* Desired number bands are available -> get the minimal even patching
1408      * distance */
1409     patchDistance =
1410         numBandsInPatch + targetStopBand - lsb; /* Get minimal distance */
1411     patchDistance = (patchDistance + 1) &
1412                     ~1; /* Rounding up odd numbers and make all even */
1413 
1414     if (numBandsInPatch > 0) {
1415       patchParam[patch].sourceStartBand = targetStopBand - patchDistance;
1416       patchParam[patch].targetBandOffs = patchDistance;
1417       patchParam[patch].numBandsInPatch = numBandsInPatch;
1418       patchParam[patch].sourceStopBand =
1419           patchParam[patch].sourceStartBand + numBandsInPatch;
1420 
1421       targetStopBand += patchParam[patch].numBandsInPatch;
1422       patch++;
1423     }
1424 
1425     /* All patches but first */
1426     sourceStartBand = SHIFT_START_SB;
1427 
1428     /* Check if we are close to desiredBorder */
1429     if (desiredBorder - targetStopBand < 3) /* MPEG doc */
1430     {
1431       desiredBorder = usb;
1432     }
1433   }
1434 
1435   patch--;
1436 
1437   /* If highest patch contains less than three subband: skip it */
1438   if ((patch > 0) && (patchParam[patch].numBandsInPatch < 3)) {
1439     patch--;
1440     targetStopBand =
1441         patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch;
1442   }
1443 
1444   /* now check if we don't have one too many */
1445   if (patch >= MAX_NUM_PATCHES) {
1446     return SBRDEC_UNSUPPORTED_CONFIG;
1447   }
1448 
1449   pSettings->noOfPatches = patch + 1;
1450 
1451   /* Check lowest and highest source subband */
1452   pSettings->lbStartPatching = targetStopBand;
1453   pSettings->lbStopPatching = 0;
1454   for (patch = 0; patch < pSettings->noOfPatches; patch++) {
1455     pSettings->lbStartPatching =
1456         fixMin(pSettings->lbStartPatching, patchParam[patch].sourceStartBand);
1457     pSettings->lbStopPatching =
1458         fixMax(pSettings->lbStopPatching, patchParam[patch].sourceStopBand);
1459   }
1460 
1461   for (i = 0; i < noNoiseBands; i++) {
1462     pSettings->bwBorders[i] = noiseBandTable[i + 1];
1463   }
1464   for (; i < MAX_NUM_NOISE_VALUES; i++) {
1465     pSettings->bwBorders[i] = 255;
1466   }
1467 
1468   /*
1469    * Choose whitening factors
1470    */
1471 
1472   startFreqHz =
1473       ((lsb + xoverOffset) * fs) >> 7; /* Shift does a division by 2*(64) */
1474 
1475   for (i = 1; i < NUM_WHFACTOR_TABLE_ENTRIES; i++) {
1476     if (startFreqHz < FDK_sbrDecoder_sbr_whFactorsIndex[i]) break;
1477   }
1478   i--;
1479 
1480   pSettings->whFactors.off = FDK_sbrDecoder_sbr_whFactorsTable[i][0];
1481   pSettings->whFactors.transitionLevel =
1482       FDK_sbrDecoder_sbr_whFactorsTable[i][1];
1483   pSettings->whFactors.lowLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][2];
1484   pSettings->whFactors.midLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][3];
1485   pSettings->whFactors.highLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][4];
1486 
1487   return SBRDEC_OK;
1488 }
1489