Home | History | Annotate | Download | only in src
      1 /* -----------------------------------------------------------------------------
      2 Software License for The Fraunhofer FDK AAC Codec Library for Android
      3 
      4  Copyright  1995 - 2019 Fraunhofer-Gesellschaft zur Frderung 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 (at) 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 
    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 
    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 
    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 
    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 
    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
   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 
   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
   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