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