• 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 =
1018         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       dynamicScale +=
1198           1; /* prevent negativ scale factor due to 'one additional bit
1199                 headroom' */
1200 
1201       for (i = startSample; i < stopSample; i++) {
1202         FIXP_DBL accu1, accu2;
1203 
1204         accu1 = (fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) -
1205                  fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1]) +
1206                  fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) -
1207                  fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >>
1208                 dynamicScale;
1209         accu2 = (fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) +
1210                  fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1]) +
1211                  fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) +
1212                  fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >>
1213                 dynamicScale;
1214 
1215         qmfBufferReal[i][loBand] =
1216             (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << (1 + 1));
1217         qmfBufferImag[i][loBand] =
1218             (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << (1 + 1));
1219       }
1220     } /* bw <= 0 */
1221 
1222     /*
1223      * store the unmodified filter coefficients if there is
1224      * an overlapping envelope
1225      *****************************************************************/
1226 
1227   } /* outer loop over bands (loBand) */
1228 
1229   for (i = 0; i < nInvfBands; i++) {
1230     hLppTrans->bwVectorOld[i] = bwVector[i];
1231   }
1232 
1233   /*
1234   set high band scale factor
1235   */
1236   sbrScaleFactor->hb_scale = comBandScale - (LPC_SCALE_FACTOR);
1237 }
1238 
1239 /*!
1240  *
1241  * \brief Initialize one low power transposer instance
1242  *
1243  *
1244  */
1245 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)1246 createLppTransposer(
1247     HANDLE_SBR_LPP_TRANS hs,        /*!< Handle of low power transposer  */
1248     TRANSPOSER_SETTINGS *pSettings, /*!< Pointer to settings */
1249     const int highBandStartSb,      /*!< ? */
1250     UCHAR *v_k_master,              /*!< Master table */
1251     const int numMaster,            /*!< Valid entries in master table */
1252     const int usb,                  /*!< Highband area stop subband */
1253     const int timeSlots,            /*!< Number of time slots */
1254     const int nCols,                /*!< Number of colums (codec qmf bank) */
1255     UCHAR *noiseBandTable,  /*!< Mapping of SBR noise bands to QMF bands */
1256     const int noNoiseBands, /*!< Number of noise bands */
1257     UINT fs,                /*!< Sample Frequency */
1258     const int chan,         /*!< Channel number */
1259     const int overlap) {
1260   /* FB inverse filtering settings */
1261   hs->pSettings = pSettings;
1262 
1263   pSettings->nCols = nCols;
1264   pSettings->overlap = overlap;
1265 
1266   switch (timeSlots) {
1267     case 15:
1268     case 16:
1269       break;
1270 
1271     default:
1272       return SBRDEC_UNSUPPORTED_CONFIG; /* Unimplemented */
1273   }
1274 
1275   if (chan == 0) {
1276     /* Init common data only once */
1277     hs->pSettings->nCols = nCols;
1278 
1279     return resetLppTransposer(hs, highBandStartSb, v_k_master, numMaster,
1280                               noiseBandTable, noNoiseBands, usb, fs);
1281   }
1282   return SBRDEC_OK;
1283 }
1284 
findClosestEntry(UCHAR goalSb,UCHAR * v_k_master,UCHAR numMaster,UCHAR direction)1285 static int findClosestEntry(UCHAR goalSb, UCHAR *v_k_master, UCHAR numMaster,
1286                             UCHAR direction) {
1287   int index;
1288 
1289   if (goalSb <= v_k_master[0]) return v_k_master[0];
1290 
1291   if (goalSb >= v_k_master[numMaster]) return v_k_master[numMaster];
1292 
1293   if (direction) {
1294     index = 0;
1295     while (v_k_master[index] < goalSb) {
1296       index++;
1297     }
1298   } else {
1299     index = numMaster;
1300     while (v_k_master[index] > goalSb) {
1301       index--;
1302     }
1303   }
1304 
1305   return v_k_master[index];
1306 }
1307 
1308 /*!
1309  *
1310  * \brief Reset memory for one lpp transposer instance
1311  *
1312  * \return SBRDEC_OK on success, SBRDEC_UNSUPPORTED_CONFIG on error
1313  */
1314 SBR_ERROR
resetLppTransposer(HANDLE_SBR_LPP_TRANS hLppTrans,UCHAR highBandStartSb,UCHAR * v_k_master,UCHAR numMaster,UCHAR * noiseBandTable,UCHAR noNoiseBands,UCHAR usb,UINT fs)1315 resetLppTransposer(
1316     HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer  */
1317     UCHAR highBandStartSb,          /*!< High band area: start subband */
1318     UCHAR *v_k_master,              /*!< Master table */
1319     UCHAR numMaster,                /*!< Valid entries in master table */
1320     UCHAR *noiseBandTable, /*!< Mapping of SBR noise bands to QMF bands */
1321     UCHAR noNoiseBands,    /*!< Number of noise bands */
1322     UCHAR usb,             /*!< High band area: stop subband */
1323     UINT fs                /*!< SBR output sampling frequency */
1324 ) {
1325   TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
1326   PATCH_PARAM *patchParam = pSettings->patchParam;
1327 
1328   int i, patch;
1329   int targetStopBand;
1330   int sourceStartBand;
1331   int patchDistance;
1332   int numBandsInPatch;
1333 
1334   int lsb = v_k_master[0]; /* Start subband expressed in "non-critical" sampling
1335                               terms*/
1336   int xoverOffset = highBandStartSb -
1337                     lsb; /* Calculate distance in QMF bands between k0 and kx */
1338   int startFreqHz;
1339 
1340   int desiredBorder;
1341 
1342   usb = fixMin(usb, v_k_master[numMaster]); /* Avoid endless loops (compare with
1343                                                float code). */
1344 
1345   /*
1346    * Plausibility check
1347    */
1348 
1349   if (pSettings->nCols == 64) {
1350     if (lsb < 4) {
1351       /* 4:1 SBR Requirement k0 >= 4 missed! */
1352       return SBRDEC_UNSUPPORTED_CONFIG;
1353     }
1354   } else if (lsb - SHIFT_START_SB < 4) {
1355     return SBRDEC_UNSUPPORTED_CONFIG;
1356   }
1357 
1358   /*
1359    * Initialize the patching parameter
1360    */
1361   /* ISO/IEC 14496-3 (Figure 4.48): goalSb = round( 2.048e6 / fs ) */
1362   desiredBorder = (((2048000 * 2) / fs) + 1) >> 1;
1363 
1364   desiredBorder = findClosestEntry(desiredBorder, v_k_master, numMaster,
1365                                    1); /* Adapt region to master-table */
1366 
1367   /* First patch */
1368   sourceStartBand = SHIFT_START_SB + xoverOffset;
1369   targetStopBand = lsb + xoverOffset; /* upperBand */
1370 
1371   /* Even (odd) numbered channel must be patched to even (odd) numbered channel
1372    */
1373   patch = 0;
1374   while (targetStopBand < usb) {
1375     /* Too many patches?
1376        Allow MAX_NUM_PATCHES+1 patches here.
1377        we need to check later again, since patch might be the highest patch
1378        AND contain less than 3 bands => actual number of patches will be reduced
1379        by 1.
1380     */
1381     if (patch > MAX_NUM_PATCHES) {
1382       return SBRDEC_UNSUPPORTED_CONFIG;
1383     }
1384 
1385     patchParam[patch].guardStartBand = targetStopBand;
1386     patchParam[patch].targetStartBand = targetStopBand;
1387 
1388     numBandsInPatch =
1389         desiredBorder - targetStopBand; /* Get the desired range of the patch */
1390 
1391     if (numBandsInPatch >= lsb - sourceStartBand) {
1392       /* Desired number bands are not available -> patch whole source range */
1393       patchDistance =
1394           targetStopBand - sourceStartBand; /* Get the targetOffset */
1395       patchDistance =
1396           patchDistance & ~1; /* Rounding off odd numbers and make all even */
1397       numBandsInPatch =
1398           lsb - (targetStopBand -
1399                  patchDistance); /* Update number of bands to be patched */
1400       numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch,
1401                                          v_k_master, numMaster, 0) -
1402                         targetStopBand; /* Adapt region to master-table */
1403     }
1404 
1405     if (pSettings->nCols == 64) {
1406       if (numBandsInPatch == 0 && sourceStartBand == SHIFT_START_SB) {
1407         return SBRDEC_UNSUPPORTED_CONFIG;
1408       }
1409     }
1410 
1411     /* Desired number bands are available -> get the minimal even patching
1412      * distance */
1413     patchDistance =
1414         numBandsInPatch + targetStopBand - lsb; /* Get minimal distance */
1415     patchDistance = (patchDistance + 1) &
1416                     ~1; /* Rounding up odd numbers and make all even */
1417 
1418     if (numBandsInPatch > 0) {
1419       patchParam[patch].sourceStartBand = targetStopBand - patchDistance;
1420       patchParam[patch].targetBandOffs = patchDistance;
1421       patchParam[patch].numBandsInPatch = numBandsInPatch;
1422       patchParam[patch].sourceStopBand =
1423           patchParam[patch].sourceStartBand + numBandsInPatch;
1424 
1425       targetStopBand += patchParam[patch].numBandsInPatch;
1426       patch++;
1427     }
1428 
1429     /* All patches but first */
1430     sourceStartBand = SHIFT_START_SB;
1431 
1432     /* Check if we are close to desiredBorder */
1433     if (desiredBorder - targetStopBand < 3) /* MPEG doc */
1434     {
1435       desiredBorder = usb;
1436     }
1437   }
1438 
1439   patch--;
1440 
1441   /* If highest patch contains less than three subband: skip it */
1442   if ((patch > 0) && (patchParam[patch].numBandsInPatch < 3)) {
1443     patch--;
1444     targetStopBand =
1445         patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch;
1446   }
1447 
1448   /* now check if we don't have one too many */
1449   if (patch >= MAX_NUM_PATCHES) {
1450     return SBRDEC_UNSUPPORTED_CONFIG;
1451   }
1452 
1453   pSettings->noOfPatches = patch + 1;
1454 
1455   /* Check lowest and highest source subband */
1456   pSettings->lbStartPatching = targetStopBand;
1457   pSettings->lbStopPatching = 0;
1458   for (patch = 0; patch < pSettings->noOfPatches; patch++) {
1459     pSettings->lbStartPatching =
1460         fixMin(pSettings->lbStartPatching, patchParam[patch].sourceStartBand);
1461     pSettings->lbStopPatching =
1462         fixMax(pSettings->lbStopPatching, patchParam[patch].sourceStopBand);
1463   }
1464 
1465   for (i = 0; i < noNoiseBands; i++) {
1466     pSettings->bwBorders[i] = noiseBandTable[i + 1];
1467   }
1468   for (; i < MAX_NUM_NOISE_VALUES; i++) {
1469     pSettings->bwBorders[i] = 255;
1470   }
1471 
1472   /*
1473    * Choose whitening factors
1474    */
1475 
1476   startFreqHz =
1477       ((lsb + xoverOffset) * fs) >> 7; /* Shift does a division by 2*(64) */
1478 
1479   for (i = 1; i < NUM_WHFACTOR_TABLE_ENTRIES; i++) {
1480     if (startFreqHz < FDK_sbrDecoder_sbr_whFactorsIndex[i]) break;
1481   }
1482   i--;
1483 
1484   pSettings->whFactors.off = FDK_sbrDecoder_sbr_whFactorsTable[i][0];
1485   pSettings->whFactors.transitionLevel =
1486       FDK_sbrDecoder_sbr_whFactorsTable[i][1];
1487   pSettings->whFactors.lowLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][2];
1488   pSettings->whFactors.midLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][3];
1489   pSettings->whFactors.highLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][4];
1490 
1491   return SBRDEC_OK;
1492 }
1493