Home | History | Annotate | Download | only in src
      1 
      2 /* -----------------------------------------------------------------------------------------------------------
      3 Software License for The Fraunhofer FDK AAC Codec Library for Android
      4 
      5  Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur Frderung der angewandten Forschung e.V.
      6   All rights reserved.
      7 
      8  1.    INTRODUCTION
      9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
     10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
     11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
     14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
     15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
     16 of the MPEG specifications.
     17 
     18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
     19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
     20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
     21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
     22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
     23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
     24 
     25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
     26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
     27 applications information and documentation.
     28 
     29 2.    COPYRIGHT LICENSE
     30 
     31 Redistribution and use in source and binary forms, with or without modification, are permitted without
     32 payment of copyright license fees provided that you satisfy the following conditions:
     33 
     34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
     35 your modifications thereto in source code form.
     36 
     37 You must retain the complete text of this software license in the documentation and/or other materials
     38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
     39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
     40 modifications thereto to recipients of copies in binary form.
     41 
     42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
     43 prior written permission.
     44 
     45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
     46 software or your modifications thereto.
     47 
     48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
     49 and the date of any change. For modified versions of the FDK AAC Codec, the term
     50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
     51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
     52 
     53 3.    NO PATENT LICENSE
     54 
     55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
     56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
     57 respect to this software.
     58 
     59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
     60 by appropriate patent licenses.
     61 
     62 4.    DISCLAIMER
     63 
     64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
     65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
     66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
     68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
     69 or business interruption, however caused and on any theory of liability, whether in contract, strict
     70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
     71 advised of the possibility of such damage.
     72 
     73 5.    CONTACT INFORMATION
     74 
     75 Fraunhofer Institute for Integrated Circuits IIS
     76 Attention: Audio and Multimedia Departments - FDK AAC LL
     77 Am Wolfsmantel 33
     78 91058 Erlangen, Germany
     79 
     80 www.iis.fraunhofer.de/amm
     81 amm-info (at) iis.fraunhofer.de
     82 ----------------------------------------------------------------------------------------------------------- */
     83 
     84 /*!
     85   \file
     86   \brief  Low Power Profile Transposer,
     87   This module provides the transposer. The main entry point is lppTransposer(). The function generates
     88   high frequency content by copying data from the low band (provided by core codec) into the high band.
     89   This process is also referred to as "patching". The function also implements spectral whitening by means of
     90   inverse filtering based on LPC coefficients.
     91 
     92   Together with the QMF filterbank the transposer can be tested using a supplied test program. See main_audio.cpp for details.
     93   This module does use fractional arithmetic and the accuracy of the computations has an impact on the overall sound quality.
     94   The module also needs to take into account the different scaling of spectral data.
     95 
     96   \sa lppTransposer(), main_audio.cpp, sbr_scale.h, \ref documentationOverview
     97 */
     98 
     99 #include "lpp_tran.h"
    100 
    101 #include "sbr_ram.h"
    102 #include "sbr_rom.h"
    103 
    104 #include "genericStds.h"
    105 #include "autocorr2nd.h"
    106 
    107 
    108 
    109 #if defined(__arm__)
    110 #include "arm/lpp_tran_arm.cpp"
    111 #endif
    112 
    113 
    114 
    115 #define LPC_SCALE_FACTOR  2
    116 
    117 
    118 /*!
    119  *
    120  * \brief Get bandwidth expansion factor from filtering level
    121  *
    122  * Returns a filter parameter (bandwidth expansion factor) depending on
    123  * the desired filtering level signalled in the bitstream.
    124  * When switching the filtering level from LOW to OFF, an additional
    125  * level is being inserted to achieve a smooth transition.
    126  */
    127 
    128 #ifndef FUNCTION_mapInvfMode
    129 static FIXP_DBL
    130 mapInvfMode (INVF_MODE mode,
    131              INVF_MODE prevMode,
    132              WHITENING_FACTORS whFactors)
    133 {
    134   switch (mode) {
    135   case INVF_LOW_LEVEL:
    136     if(prevMode == INVF_OFF)
    137       return whFactors.transitionLevel;
    138     else
    139       return whFactors.lowLevel;
    140 
    141   case INVF_MID_LEVEL:
    142     return whFactors.midLevel;
    143 
    144   case INVF_HIGH_LEVEL:
    145     return whFactors.highLevel;
    146 
    147   default:
    148     if(prevMode == INVF_LOW_LEVEL)
    149       return whFactors.transitionLevel;
    150     else
    151       return whFactors.off;
    152   }
    153 }
    154 #endif /* #ifndef FUNCTION_mapInvfMode */
    155 
    156 /*!
    157  *
    158  * \brief Perform inverse filtering level emphasis
    159  *
    160  * Retrieve bandwidth expansion factor and apply smoothing for each filter band
    161  *
    162  */
    163 
    164 #ifndef FUNCTION_inverseFilteringLevelEmphasis
    165 static void
    166 inverseFilteringLevelEmphasis(HANDLE_SBR_LPP_TRANS hLppTrans,/*!< Handle of lpp transposer  */
    167                               UCHAR nInvfBands,              /*!< Number of bands for inverse filtering */
    168                               INVF_MODE *sbr_invf_mode,      /*!< Current inverse filtering modes */
    169                               INVF_MODE *sbr_invf_mode_prev, /*!< Previous inverse filtering modes */
    170                               FIXP_DBL * bwVector            /*!< Resulting filtering levels */
    171                               )
    172 {
    173   for(int i = 0; i < nInvfBands; i++) {
    174     FIXP_DBL accu;
    175     FIXP_DBL bwTmp = mapInvfMode (sbr_invf_mode[i],
    176                                   sbr_invf_mode_prev[i],
    177                                   hLppTrans->pSettings->whFactors);
    178 
    179     if(bwTmp < hLppTrans->bwVectorOld[i]) {
    180       accu = fMultDiv2(FL2FXCONST_DBL(0.75f),bwTmp) +
    181              fMultDiv2(FL2FXCONST_DBL(0.25f),hLppTrans->bwVectorOld[i]);
    182     }
    183     else {
    184       accu = fMultDiv2(FL2FXCONST_DBL(0.90625f),bwTmp) +
    185              fMultDiv2(FL2FXCONST_DBL(0.09375f),hLppTrans->bwVectorOld[i]);
    186     }
    187 
    188     if (accu <  FL2FXCONST_DBL(0.015625f)>>1)
    189       bwVector[i] = FL2FXCONST_DBL(0.0f);
    190     else
    191       bwVector[i] = fixMin(accu<<1,FL2FXCONST_DBL(0.99609375f));
    192   }
    193 }
    194 #endif /* #ifndef FUNCTION_inverseFilteringLevelEmphasis */
    195 
    196 /* Resulting autocorrelation determinant exponent */
    197 #define ACDET_EXP (2*(DFRACT_BITS+sbrScaleFactor->lb_scale+10-ac.det_scale))
    198 #define AC_EXP (-sbrScaleFactor->lb_scale+LPC_SCALE_FACTOR)
    199 #define ALPHA_EXP (-sbrScaleFactor->lb_scale+LPC_SCALE_FACTOR+1)
    200 /* Resulting transposed QMF values exponent 16 bit normalized samplebits assumed. */
    201 #define QMFOUT_EXP ((SAMPLE_BITS-15)-sbrScaleFactor->lb_scale)
    202 
    203 /*!
    204  *
    205  * \brief Perform transposition by patching of subband samples.
    206  * This function serves as the main entry point into the module. The function determines the areas for the
    207  * patching process (these are the source range as well as the target range) and implements spectral whitening
    208  * by means of inverse filtering. The function autoCorrelation2nd() is an auxiliary function for calculating the
    209  * LPC coefficients for the filtering.  The actual calculation of the LPC coefficients and the implementation
    210  * of the filtering are done as part of lppTransposer().
    211  *
    212  * Note that the filtering is done on all available QMF subsamples, whereas the patching is only done on those QMF
    213  * subsamples that will be used in the next QMF synthesis. The filtering is also implemented before the patching
    214  * includes further dependencies on parameters from the SBR data.
    215  *
    216  */
    217 
    218 void lppTransposer (HANDLE_SBR_LPP_TRANS hLppTrans,    /*!< Handle of lpp transposer  */
    219                     QMF_SCALE_FACTOR  *sbrScaleFactor, /*!< Scaling factors */
    220                     FIXP_DBL **qmfBufferReal,          /*!< Pointer to pointer to real part of subband samples (source) */
    221 
    222                     FIXP_DBL *degreeAlias,             /*!< Vector for results of aliasing estimation */
    223                     FIXP_DBL **qmfBufferImag,          /*!< Pointer to pointer to imaginary part of subband samples (source) */
    224                     const int useLP,
    225                     const int timeStep,                /*!< Time step of envelope */
    226                     const int firstSlotOffs,           /*!< Start position in time */
    227                     const int lastSlotOffs,            /*!< Number of overlap-slots into next frame */
    228                     const int nInvfBands,              /*!< Number of bands for inverse filtering */
    229                     INVF_MODE *sbr_invf_mode,          /*!< Current inverse filtering modes */
    230                     INVF_MODE *sbr_invf_mode_prev      /*!< Previous inverse filtering modes */
    231                     )
    232 {
    233   INT    bwIndex[MAX_NUM_PATCHES];
    234   FIXP_DBL  bwVector[MAX_NUM_PATCHES];       /*!< pole moving factors */
    235 
    236   int    i;
    237   int    loBand, start, stop;
    238   TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
    239   PATCH_PARAM *patchParam = pSettings->patchParam;
    240   int    patch;
    241 
    242   FIXP_SGL  alphar[LPC_ORDER], a0r, a1r;
    243   FIXP_SGL  alphai[LPC_ORDER], a0i=0, a1i=0;
    244   FIXP_SGL  bw = FL2FXCONST_SGL(0.0f);
    245 
    246   int    autoCorrLength;
    247 
    248   FIXP_DBL k1, k1_below=0, k1_below2=0;
    249 
    250   ACORR_COEFS ac;
    251   int    startSample;
    252   int    stopSample;
    253   int    stopSampleClear;
    254 
    255   int comLowBandScale;
    256   int ovLowBandShift;
    257   int lowBandShift;
    258 /*  int ovHighBandShift;*/
    259   int targetStopBand;
    260 
    261 
    262   alphai[0] = FL2FXCONST_SGL(0.0f);
    263   alphai[1] = FL2FXCONST_SGL(0.0f);
    264 
    265 
    266   startSample = firstSlotOffs * timeStep;
    267   stopSample  = pSettings->nCols + lastSlotOffs * timeStep;
    268 
    269 
    270   inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode, sbr_invf_mode_prev, bwVector);
    271 
    272   stopSampleClear = stopSample;
    273 
    274   autoCorrLength = pSettings->nCols + pSettings->overlap;
    275 
    276   /* Set upper subbands to zero:
    277      This is required in case that the patches do not cover the complete highband
    278      (because the last patch would be too short).
    279      Possible optimization: Clearing bands up to usb would be sufficient here. */
    280   targetStopBand = patchParam[pSettings->noOfPatches-1].targetStartBand
    281                  + patchParam[pSettings->noOfPatches-1].numBandsInPatch;
    282 
    283   int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL);
    284 
    285   if (!useLP) {
    286     for (i = startSample; i < stopSampleClear; i++) {
    287       FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
    288       FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize);
    289     }
    290   } else
    291   for (i = startSample; i < stopSampleClear; i++) {
    292     FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
    293   }
    294 
    295   /* init bwIndex for each patch */
    296   FDKmemclear(bwIndex, pSettings->noOfPatches*sizeof(INT));
    297 
    298   /*
    299     Calc common low band scale factor
    300   */
    301   comLowBandScale = fixMin(sbrScaleFactor->ov_lb_scale,sbrScaleFactor->lb_scale);
    302 
    303   ovLowBandShift =  sbrScaleFactor->ov_lb_scale - comLowBandScale;
    304   lowBandShift   =  sbrScaleFactor->lb_scale - comLowBandScale;
    305   /*  ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/
    306 
    307   /* outer loop over bands to do analysis only once for each band */
    308 
    309   if (!useLP) {
    310     start = pSettings->lbStartPatching;
    311     stop = pSettings->lbStopPatching;
    312   } else
    313   {
    314     start = fixMax(1, pSettings->lbStartPatching - 2);
    315     stop = patchParam[0].targetStartBand;
    316   }
    317 
    318 
    319   for ( loBand = start; loBand <  stop; loBand++ ) {
    320 
    321     FIXP_DBL  lowBandReal[(((1024)/(32))+(6))+LPC_ORDER];
    322     FIXP_DBL *plowBandReal = lowBandReal;
    323     FIXP_DBL **pqmfBufferReal = qmfBufferReal;
    324     FIXP_DBL  lowBandImag[(((1024)/(32))+(6))+LPC_ORDER];
    325     FIXP_DBL *plowBandImag = lowBandImag;
    326     FIXP_DBL **pqmfBufferImag = qmfBufferImag;
    327     int resetLPCCoeffs=0;
    328     int dynamicScale = DFRACT_BITS-1-LPC_SCALE_FACTOR;
    329     int acDetScale = 0; /* scaling of autocorrelation determinant */
    330 
    331     for(i=0;i<LPC_ORDER;i++){
    332       *plowBandReal++ = hLppTrans->lpcFilterStatesReal[i][loBand];
    333       if (!useLP)
    334         *plowBandImag++ = hLppTrans->lpcFilterStatesImag[i][loBand];
    335     }
    336 
    337     /*
    338       Take old slope length qmf slot source values out of (overlap)qmf buffer
    339     */
    340     if (!useLP) {
    341       for(i=0;i<pSettings->nCols+pSettings->overlap;i++){
    342         *plowBandReal++ = (*pqmfBufferReal++)[loBand];
    343         *plowBandImag++ = (*pqmfBufferImag++)[loBand];
    344       }
    345     } else
    346     {
    347       /* pSettings->overlap is always even */
    348       FDK_ASSERT((pSettings->overlap & 1) == 0);
    349 
    350       for(i=0;i<((pSettings->overlap+pSettings->nCols)>>1);i++) {
    351         *plowBandReal++ = (*pqmfBufferReal++)[loBand];
    352         *plowBandReal++ = (*pqmfBufferReal++)[loBand];
    353       }
    354       if (pSettings->nCols & 1) {
    355         *plowBandReal++ = (*pqmfBufferReal++)[loBand];
    356       }
    357     }
    358 
    359     /*
    360       Determine dynamic scaling value.
    361      */
    362     dynamicScale = fixMin(dynamicScale, getScalefactor(lowBandReal, LPC_ORDER+pSettings->overlap) + ovLowBandShift);
    363     dynamicScale = fixMin(dynamicScale, getScalefactor(&lowBandReal[LPC_ORDER+pSettings->overlap], pSettings->nCols) + lowBandShift);
    364     if (!useLP) {
    365       dynamicScale = fixMin(dynamicScale, getScalefactor(lowBandImag, LPC_ORDER+pSettings->overlap) + ovLowBandShift);
    366       dynamicScale = fixMin(dynamicScale, getScalefactor(&lowBandImag[LPC_ORDER+pSettings->overlap], pSettings->nCols) + lowBandShift);
    367     }
    368     dynamicScale = fixMax(0, dynamicScale-1); /* one additional bit headroom to prevent -1.0 */
    369 
    370     /*
    371       Scale temporal QMF buffer.
    372      */
    373     scaleValues(&lowBandReal[0], LPC_ORDER+pSettings->overlap, dynamicScale-ovLowBandShift);
    374     scaleValues(&lowBandReal[LPC_ORDER+pSettings->overlap], pSettings->nCols, dynamicScale-lowBandShift);
    375 
    376     if (!useLP) {
    377       scaleValues(&lowBandImag[0], LPC_ORDER+pSettings->overlap, dynamicScale-ovLowBandShift);
    378       scaleValues(&lowBandImag[LPC_ORDER+pSettings->overlap], pSettings->nCols, dynamicScale-lowBandShift);
    379     }
    380 
    381 
    382       if (!useLP) {
    383         acDetScale += autoCorr2nd_cplx(&ac, lowBandReal+LPC_ORDER, lowBandImag+LPC_ORDER, autoCorrLength);
    384       }
    385       else
    386       {
    387         acDetScale += autoCorr2nd_real(&ac, lowBandReal+LPC_ORDER, autoCorrLength);
    388       }
    389 
    390       /* Examine dynamic of determinant in autocorrelation. */
    391       acDetScale += 2*(comLowBandScale + dynamicScale);
    392       acDetScale *= 2;              /* two times reflection coefficent scaling */
    393       acDetScale += ac.det_scale;   /* ac scaling of determinant */
    394 
    395       /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */
    396       if (acDetScale>126 ) {
    397         resetLPCCoeffs = 1;
    398       }
    399 
    400 
    401     alphar[1] = FL2FXCONST_SGL(0.0f);
    402     if (!useLP)
    403       alphai[1] = FL2FXCONST_SGL(0.0f);
    404 
    405     if (ac.det != FL2FXCONST_DBL(0.0f)) {
    406       FIXP_DBL tmp,absTmp,absDet;
    407 
    408       absDet = fixp_abs(ac.det);
    409 
    410       if (!useLP) {
    411         tmp = ( fMultDiv2(ac.r01r,ac.r12r) >> (LPC_SCALE_FACTOR-1) ) -
    412               ( (fMultDiv2(ac.r01i,ac.r12i) + fMultDiv2(ac.r02r,ac.r11r)) >> (LPC_SCALE_FACTOR-1) );
    413       } else
    414       {
    415         tmp = ( fMultDiv2(ac.r01r,ac.r12r) >> (LPC_SCALE_FACTOR-1) ) -
    416               ( fMultDiv2(ac.r02r,ac.r11r) >> (LPC_SCALE_FACTOR-1) );
    417       }
    418       absTmp = fixp_abs(tmp);
    419 
    420       /*
    421         Quick check: is first filter coeff >= 1(4)
    422        */
    423       {
    424         INT scale;
    425         FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
    426         scale = scale+ac.det_scale;
    427 
    428         if ( (scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL>>scale) ) {
    429           resetLPCCoeffs = 1;
    430         }
    431         else {
    432           alphar[1] = FX_DBL2FX_SGL(scaleValue(result,scale));
    433           if((tmp<FL2FX_DBL(0.0f)) ^ (ac.det<FL2FX_DBL(0.0f))) {
    434             alphar[1] = -alphar[1];
    435           }
    436         }
    437       }
    438 
    439       if (!useLP)
    440       {
    441         tmp =  ( fMultDiv2(ac.r01i,ac.r12r) >> (LPC_SCALE_FACTOR-1) ) +
    442                ( (fMultDiv2(ac.r01r,ac.r12i) - (FIXP_DBL)fMultDiv2(ac.r02i,ac.r11r)) >> (LPC_SCALE_FACTOR-1) ) ;
    443 
    444         absTmp = fixp_abs(tmp);
    445 
    446         /*
    447         Quick check: is second filter coeff >= 1(4)
    448         */
    449         {
    450           INT scale;
    451           FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
    452           scale = scale+ac.det_scale;
    453 
    454           if ( (scale > 0) && (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL>>scale) ) {
    455             resetLPCCoeffs = 1;
    456           }
    457           else {
    458             alphai[1] = FX_DBL2FX_SGL(scaleValue(result,scale));
    459             if((tmp<FL2FX_DBL(0.0f)) ^ (ac.det<FL2FX_DBL(0.0f))) {
    460               alphai[1] = -alphai[1];
    461             }
    462           }
    463         }
    464       }
    465     }
    466 
    467     alphar[0] =  FL2FXCONST_SGL(0.0f);
    468     if (!useLP)
    469       alphai[0] = FL2FXCONST_SGL(0.0f);
    470 
    471     if ( ac.r11r != FL2FXCONST_DBL(0.0f) ) {
    472 
    473       /* ac.r11r is always >=0 */
    474       FIXP_DBL tmp,absTmp;
    475 
    476       if (!useLP) {
    477         tmp = (ac.r01r>>(LPC_SCALE_FACTOR+1)) +
    478               (fMultDiv2(alphar[1],ac.r12r) + fMultDiv2(alphai[1],ac.r12i));
    479       } else
    480       {
    481         if(ac.r01r>=FL2FXCONST_DBL(0.0f))
    482           tmp = (ac.r01r>>(LPC_SCALE_FACTOR+1)) + fMultDiv2(alphar[1],ac.r12r);
    483         else
    484           tmp = -((-ac.r01r)>>(LPC_SCALE_FACTOR+1)) + fMultDiv2(alphar[1],ac.r12r);
    485       }
    486 
    487       absTmp = fixp_abs(tmp);
    488 
    489       /*
    490         Quick check: is first filter coeff >= 1(4)
    491       */
    492 
    493       if (absTmp >= (ac.r11r>>1)) {
    494         resetLPCCoeffs=1;
    495       }
    496       else {
    497         INT scale;
    498         FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
    499         alphar[0] =  FX_DBL2FX_SGL(scaleValue(result,scale+1));
    500 
    501         if((tmp>FL2FX_DBL(0.0f)) ^ (ac.r11r<FL2FX_DBL(0.0f)))
    502           alphar[0] = -alphar[0];
    503       }
    504 
    505       if (!useLP)
    506       {
    507         tmp = (ac.r01i>>(LPC_SCALE_FACTOR+1)) +
    508               (fMultDiv2(alphai[1],ac.r12r) - fMultDiv2(alphar[1],ac.r12i));
    509 
    510         absTmp = fixp_abs(tmp);
    511 
    512         /*
    513         Quick check: is second filter coeff >= 1(4)
    514         */
    515         if (absTmp >= (ac.r11r>>1)) {
    516           resetLPCCoeffs=1;
    517         }
    518         else {
    519           INT scale;
    520           FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
    521           alphai[0] = FX_DBL2FX_SGL(scaleValue(result,scale+1));
    522           if((tmp>FL2FX_DBL(0.0f)) ^ (ac.r11r<FL2FX_DBL(0.0f)))
    523             alphai[0] = -alphai[0];
    524         }
    525       }
    526     }
    527 
    528 
    529     if (!useLP)
    530     {
    531       /* Now check the quadratic criteria */
    532       if( (fMultDiv2(alphar[0],alphar[0]) + fMultDiv2(alphai[0],alphai[0])) >= FL2FXCONST_DBL(0.5f) )
    533         resetLPCCoeffs=1;
    534       if( (fMultDiv2(alphar[1],alphar[1]) + fMultDiv2(alphai[1],alphai[1])) >= FL2FXCONST_DBL(0.5f) )
    535         resetLPCCoeffs=1;
    536     }
    537 
    538     if(resetLPCCoeffs){
    539       alphar[0] = FL2FXCONST_SGL(0.0f);
    540       alphar[1] = FL2FXCONST_SGL(0.0f);
    541       if (!useLP)
    542       {
    543         alphai[0] = FL2FXCONST_SGL(0.0f);
    544         alphai[1] = FL2FXCONST_SGL(0.0f);
    545       }
    546     }
    547 
    548     if (useLP)
    549     {
    550 
    551       /* Aliasing detection */
    552       if(ac.r11r==FL2FXCONST_DBL(0.0f)) {
    553         k1 = FL2FXCONST_DBL(0.0f);
    554       }
    555       else {
    556         if ( fixp_abs(ac.r01r) >= fixp_abs(ac.r11r) ) {
    557           if ( fMultDiv2(ac.r01r,ac.r11r) < FL2FX_DBL(0.0f)) {
    558             k1 = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_SGL(1.0f)*/;
    559           }else {
    560             /* Since this value is squared later, it must not ever become -1.0f. */
    561             k1 = (FIXP_DBL)(MINVAL_DBL+1) /*FL2FXCONST_SGL(-1.0f)*/;
    562           }
    563         }
    564         else {
    565           INT scale;
    566           FIXP_DBL result = fDivNorm(fixp_abs(ac.r01r), fixp_abs(ac.r11r), &scale);
    567           k1 = scaleValue(result,scale);
    568 
    569           if(!((ac.r01r<FL2FX_DBL(0.0f)) ^ (ac.r11r<FL2FX_DBL(0.0f)))) {
    570             k1 = -k1;
    571           }
    572         }
    573       }
    574       if(loBand > 1){
    575         /* Check if the gain should be locked */
    576         FIXP_DBL deg = /*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - fPow2(k1_below);
    577         degreeAlias[loBand] = FL2FXCONST_DBL(0.0f);
    578         if (((loBand & 1) == 0) && (k1 < FL2FXCONST_DBL(0.0f))){
    579           if (k1_below < FL2FXCONST_DBL(0.0f)) {         /* 2-Ch Aliasing Detection */
    580             degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/;
    581             if ( k1_below2 > FL2FXCONST_DBL(0.0f) ) {    /* 3-Ch Aliasing Detection */
    582               degreeAlias[loBand-1] = deg;
    583             }
    584           }
    585           else if ( k1_below2 > FL2FXCONST_DBL(0.0f) ) { /* 3-Ch Aliasing Detection */
    586             degreeAlias[loBand]   = deg;
    587           }
    588         }
    589         if (((loBand & 1) == 1) && (k1 > FL2FXCONST_DBL(0.0f))){
    590           if (k1_below > FL2FXCONST_DBL(0.0f)) {         /* 2-CH Aliasing Detection */
    591             degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/;
    592             if ( k1_below2 < FL2FXCONST_DBL(0.0f) ) {    /* 3-CH Aliasing Detection */
    593               degreeAlias[loBand-1] = deg;
    594             }
    595           }
    596           else if ( k1_below2 < FL2FXCONST_DBL(0.0f) ) { /* 3-CH Aliasing Detection */
    597             degreeAlias[loBand]   = deg;
    598           }
    599         }
    600       }
    601       /* remember k1 values of the 2 QMF channels below the current channel */
    602       k1_below2 = k1_below;
    603       k1_below = k1;
    604     }
    605 
    606     patch = 0;
    607 
    608     while ( patch < pSettings->noOfPatches ) { /* inner loop over every patch */
    609 
    610       int hiBand = loBand + patchParam[patch].targetBandOffs;
    611 
    612       if ( loBand < patchParam[patch].sourceStartBand
    613            || loBand >= patchParam[patch].sourceStopBand
    614            //|| hiBand >= hLppTrans->pSettings->noChannels
    615            ) {
    616         /* Lowband not in current patch - proceed */
    617         patch++;
    618         continue;
    619       }
    620 
    621       FDK_ASSERT( hiBand < (64) );
    622 
    623       /* bwIndex[patch] is already initialized with value from previous band inside this patch */
    624       while (hiBand >= pSettings->bwBorders[bwIndex[patch]])
    625         bwIndex[patch]++;
    626 
    627 
    628       /*
    629         Filter Step 2: add the left slope with the current filter to the buffer
    630                        pure source values are already in there
    631       */
    632       bw = FX_DBL2FX_SGL(bwVector[bwIndex[patch]]);
    633 
    634       a0r = FX_DBL2FX_SGL(fMult(bw,alphar[0])); /* Apply current bandwidth expansion factor */
    635 
    636 
    637       if (!useLP)
    638         a0i = FX_DBL2FX_SGL(fMult(bw,alphai[0]));
    639       bw =  FX_DBL2FX_SGL(fPow2(bw));
    640       a1r = FX_DBL2FX_SGL(fMult(bw,alphar[1]));
    641       if (!useLP)
    642         a1i = FX_DBL2FX_SGL(fMult(bw,alphai[1]));
    643 
    644 
    645 
    646       /*
    647         Filter Step 3: insert the middle part which won't be windowed
    648       */
    649 
    650       if ( bw <= FL2FXCONST_SGL(0.0f) ) {
    651         if (!useLP) {
    652           int descale = fixMin(DFRACT_BITS-1, (LPC_SCALE_FACTOR+dynamicScale));
    653           for(i = startSample; i < stopSample; i++ ) {
    654             qmfBufferReal[i][hiBand] = lowBandReal[LPC_ORDER+i]>>descale;
    655             qmfBufferImag[i][hiBand] = lowBandImag[LPC_ORDER+i]>>descale;
    656           }
    657         } else
    658         {
    659           int descale = fixMin(DFRACT_BITS-1, (LPC_SCALE_FACTOR+dynamicScale));
    660           for(i = startSample; i < stopSample; i++ ) {
    661             qmfBufferReal[i][hiBand] = lowBandReal[LPC_ORDER+i]>>descale;
    662           }
    663         }
    664       }
    665       else {  /* bw <= 0 */
    666 
    667         if (!useLP) {
    668           int descale = fixMin(DFRACT_BITS-1, (LPC_SCALE_FACTOR+dynamicScale));
    669 #ifdef FUNCTION_LPPTRANSPOSER_func1
    670           lppTransposer_func1(lowBandReal+LPC_ORDER+startSample,lowBandImag+LPC_ORDER+startSample,
    671                               qmfBufferReal+startSample,qmfBufferImag+startSample,
    672                               stopSample-startSample, (int) hiBand,
    673                               dynamicScale,descale,
    674                               a0r, a0i, a1r, a1i);
    675 #else
    676           for(i = startSample; i < stopSample; i++ ) {
    677             FIXP_DBL accu1, accu2;
    678 
    679             accu1 = (fMultDiv2(a0r,lowBandReal[LPC_ORDER+i-1]) - fMultDiv2(a0i,lowBandImag[LPC_ORDER+i-1]) +
    680                      fMultDiv2(a1r,lowBandReal[LPC_ORDER+i-2]) - fMultDiv2(a1i,lowBandImag[LPC_ORDER+i-2]))>>dynamicScale;
    681             accu2 = (fMultDiv2(a0i,lowBandReal[LPC_ORDER+i-1]) + fMultDiv2(a0r,lowBandImag[LPC_ORDER+i-1]) +
    682                      fMultDiv2(a1i,lowBandReal[LPC_ORDER+i-2]) + fMultDiv2(a1r,lowBandImag[LPC_ORDER+i-2]))>>dynamicScale;
    683 
    684             qmfBufferReal[i][hiBand] = (lowBandReal[LPC_ORDER+i]>>descale) + (accu1<<1);
    685             qmfBufferImag[i][hiBand] = (lowBandImag[LPC_ORDER+i]>>descale) + (accu2<<1);
    686           }
    687 #endif
    688         } else
    689         {
    690           int descale = fixMin(DFRACT_BITS-1, (LPC_SCALE_FACTOR+dynamicScale));
    691 
    692           FDK_ASSERT(dynamicScale >= 0);
    693           for(i = startSample; i < stopSample; i++ ) {
    694             FIXP_DBL accu1;
    695 
    696             accu1 = (fMultDiv2(a0r,lowBandReal[LPC_ORDER+i-1]) + fMultDiv2(a1r,lowBandReal[LPC_ORDER+i-2]))>>dynamicScale;
    697 
    698             qmfBufferReal[i][hiBand] = (lowBandReal[LPC_ORDER+i]>>descale) + (accu1<<1);
    699           }
    700         }
    701       } /* bw <= 0 */
    702 
    703       patch++;
    704 
    705     }  /* inner loop over patches */
    706 
    707      /*
    708      * store the unmodified filter coefficients if there is
    709      * an overlapping envelope
    710      *****************************************************************/
    711 
    712 
    713   }  /* outer loop over bands (loBand) */
    714 
    715   if (useLP)
    716   {
    717     for ( loBand = pSettings->lbStartPatching; loBand <  pSettings->lbStopPatching; loBand++ ) {
    718       patch = 0;
    719       while ( patch < pSettings->noOfPatches ) {
    720 
    721         UCHAR hiBand = loBand + patchParam[patch].targetBandOffs;
    722 
    723         if ( loBand < patchParam[patch].sourceStartBand
    724           || loBand >= patchParam[patch].sourceStopBand
    725           || hiBand >= (64)              /* Highband out of range (biterror) */
    726           ) {
    727           /* Lowband not in current patch or highband out of range (might be caused by biterrors)- proceed */
    728           patch++;
    729           continue;
    730         }
    731 
    732         if(hiBand != patchParam[patch].targetStartBand)
    733           degreeAlias[hiBand] = degreeAlias[loBand];
    734 
    735         patch++;
    736       }
    737     }/* end  for loop */
    738   }
    739 
    740  for (i = 0; i < nInvfBands; i++ ) {
    741    hLppTrans->bwVectorOld[i] = bwVector[i];
    742  }
    743 
    744   /*
    745     set high band scale factor
    746   */
    747   sbrScaleFactor->hb_scale = comLowBandScale-(LPC_SCALE_FACTOR);
    748 
    749 }
    750 
    751 /*!
    752  *
    753  * \brief Initialize one low power transposer instance
    754  *
    755  *
    756  */
    757 SBR_ERROR
    758 createLppTransposer (HANDLE_SBR_LPP_TRANS hs, /*!< Handle of low power transposer  */
    759                      TRANSPOSER_SETTINGS *pSettings, /*!< Pointer to settings */
    760                      const int  highBandStartSb, /*!< ? */
    761                      UCHAR *v_k_master,         /*!< Master table */
    762                      const int numMaster,       /*!< Valid entries in master table */
    763                      const int usb,             /*!< Highband area stop subband */
    764                      const int timeSlots,       /*!< Number of time slots */
    765                      const int nCols,           /*!< Number of colums (codec qmf bank) */
    766                      UCHAR *noiseBandTable,     /*!< Mapping of SBR noise bands to QMF bands */
    767                      const int  noNoiseBands,   /*!< Number of noise bands */
    768                      UINT   fs,                 /*!< Sample Frequency */
    769                      const int chan,            /*!< Channel number */
    770                      const int overlap
    771                      )
    772 {
    773   /* FB inverse filtering settings */
    774   hs->pSettings = pSettings;
    775 
    776   pSettings->nCols = nCols;
    777   pSettings->overlap = overlap;
    778 
    779   switch (timeSlots) {
    780 
    781   case 15:
    782   case 16:
    783     break;
    784 
    785   default:
    786     return SBRDEC_UNSUPPORTED_CONFIG; /* Unimplemented */
    787   }
    788 
    789   if (chan==0) {
    790     /* Init common data only once */
    791     hs->pSettings->nCols = nCols;
    792 
    793     return resetLppTransposer (hs,
    794                                highBandStartSb,
    795                                v_k_master,
    796                                numMaster,
    797                                noiseBandTable,
    798                                noNoiseBands,
    799                                usb,
    800                                fs);
    801   }
    802   return SBRDEC_OK;
    803 }
    804 
    805 
    806 static int findClosestEntry(UCHAR goalSb, UCHAR *v_k_master, UCHAR numMaster, UCHAR direction)
    807 {
    808   int index;
    809 
    810   if( goalSb <= v_k_master[0] )
    811     return v_k_master[0];
    812 
    813   if( goalSb >= v_k_master[numMaster] )
    814     return v_k_master[numMaster];
    815 
    816   if(direction) {
    817     index = 0;
    818     while( v_k_master[index] < goalSb ) {
    819       index++;
    820     }
    821   } else {
    822     index = numMaster;
    823     while( v_k_master[index] > goalSb ) {
    824       index--;
    825     }
    826   }
    827 
    828   return v_k_master[index];
    829 }
    830 
    831 
    832 /*!
    833  *
    834  * \brief Reset memory for one lpp transposer instance
    835  *
    836  * \return SBRDEC_OK on success, SBRDEC_UNSUPPORTED_CONFIG on error
    837  */
    838 SBR_ERROR
    839 resetLppTransposer (HANDLE_SBR_LPP_TRANS hLppTrans,  /*!< Handle of lpp transposer  */
    840                     UCHAR  highBandStartSb,          /*!< High band area: start subband */
    841                     UCHAR *v_k_master,               /*!< Master table */
    842                     UCHAR  numMaster,                /*!< Valid entries in master table */
    843                     UCHAR *noiseBandTable,           /*!< Mapping of SBR noise bands to QMF bands */
    844                     UCHAR  noNoiseBands,             /*!< Number of noise bands */
    845                     UCHAR  usb,                      /*!< High band area: stop subband */
    846                     UINT   fs                        /*!< SBR output sampling frequency */
    847                     )
    848 {
    849   TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
    850   PATCH_PARAM  *patchParam = pSettings->patchParam;
    851 
    852   int i, patch;
    853   int targetStopBand;
    854   int sourceStartBand;
    855   int patchDistance;
    856   int numBandsInPatch;
    857 
    858   int lsb = v_k_master[0];                 /* Start subband expressed in "non-critical" sampling terms*/
    859   int xoverOffset = highBandStartSb - lsb; /* Calculate distance in QMF bands between k0 and kx */
    860   int startFreqHz;
    861 
    862   int desiredBorder;
    863 
    864   usb = fixMin(usb, v_k_master[numMaster]); /* Avoid endless loops (compare with float code). */
    865 
    866   /*
    867    * Plausibility check
    868    */
    869 
    870   if ( lsb - SHIFT_START_SB < 4 ) {
    871     return SBRDEC_UNSUPPORTED_CONFIG;
    872   }
    873 
    874 
    875   /*
    876    * Initialize the patching parameter
    877    */
    878  desiredBorder = 21;
    879  if (fs < 92017) {
    880     desiredBorder = 23;
    881   }
    882   if (fs < 75132) {
    883     desiredBorder = 32;
    884   }
    885   if (fs < 55426) {
    886     desiredBorder = 43;
    887   }
    888   if (fs < 46009) {
    889     desiredBorder = 46;
    890   }
    891   if (fs < 35777) {
    892     desiredBorder = 64;
    893   }
    894 
    895   desiredBorder = findClosestEntry(desiredBorder, v_k_master, numMaster, 1); /* Adapt region to master-table */
    896 
    897   /* First patch */
    898   sourceStartBand = SHIFT_START_SB + xoverOffset;
    899   targetStopBand = lsb + xoverOffset; /* upperBand */
    900 
    901   /* Even (odd) numbered channel must be patched to even (odd) numbered channel */
    902   patch = 0;
    903   while(targetStopBand < usb) {
    904 
    905     /* Too many patches?
    906        Allow MAX_NUM_PATCHES+1 patches here.
    907        we need to check later again, since patch might be the highest patch
    908        AND contain less than 3 bands => actual number of patches will be reduced by 1.
    909     */
    910     if (patch > MAX_NUM_PATCHES) {
    911       return SBRDEC_UNSUPPORTED_CONFIG;
    912     }
    913 
    914     patchParam[patch].guardStartBand = targetStopBand;
    915     patchParam[patch].targetStartBand = targetStopBand;
    916 
    917     numBandsInPatch = desiredBorder - targetStopBand;                   /* Get the desired range of the patch */
    918 
    919     if ( numBandsInPatch >= lsb - sourceStartBand ) {
    920       /* Desired number bands are not available -> patch whole source range */
    921       patchDistance   = targetStopBand - sourceStartBand;        /* Get the targetOffset */
    922       patchDistance   = patchDistance & ~1;                      /* Rounding off odd numbers and make all even */
    923       numBandsInPatch = lsb - (targetStopBand - patchDistance);  /* Update number of bands to be patched */
    924       numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch, v_k_master, numMaster, 0) -
    925                         targetStopBand;  /* Adapt region to master-table */
    926     }
    927 
    928     /* Desired number bands are available -> get the minimal even patching distance */
    929     patchDistance   = numBandsInPatch + targetStopBand - lsb;  /* Get minimal distance */
    930     patchDistance   = (patchDistance + 1) & ~1;                /* Rounding up odd numbers and make all even */
    931 
    932     if (numBandsInPatch > 0) {
    933       patchParam[patch].sourceStartBand = targetStopBand - patchDistance;
    934       patchParam[patch].targetBandOffs  = patchDistance;
    935       patchParam[patch].numBandsInPatch = numBandsInPatch;
    936       patchParam[patch].sourceStopBand  = patchParam[patch].sourceStartBand + numBandsInPatch;
    937 
    938       targetStopBand += patchParam[patch].numBandsInPatch;
    939       patch++;
    940     }
    941 
    942     /* All patches but first */
    943     sourceStartBand = SHIFT_START_SB;
    944 
    945     /* Check if we are close to desiredBorder */
    946     if( desiredBorder - targetStopBand < 3)  /* MPEG doc */
    947     {
    948       desiredBorder = usb;
    949     }
    950 
    951   }
    952 
    953   patch--;
    954 
    955   /* If highest patch contains less than three subband: skip it */
    956   if ( (patch>0) && (patchParam[patch].numBandsInPatch < 3) ) {
    957     patch--;
    958     targetStopBand = patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch;
    959   }
    960 
    961   /* now check if we don't have one too many */
    962   if (patch >= MAX_NUM_PATCHES) {
    963     return SBRDEC_UNSUPPORTED_CONFIG;
    964   }
    965 
    966   pSettings->noOfPatches = patch + 1;
    967 
    968   /* Check lowest and highest source subband */
    969   pSettings->lbStartPatching = targetStopBand;
    970   pSettings->lbStopPatching  = 0;
    971   for ( patch = 0; patch < pSettings->noOfPatches; patch++ ) {
    972     pSettings->lbStartPatching = fixMin( pSettings->lbStartPatching, patchParam[patch].sourceStartBand );
    973     pSettings->lbStopPatching  = fixMax( pSettings->lbStopPatching, patchParam[patch].sourceStopBand );
    974   }
    975 
    976   for(i = 0 ; i < noNoiseBands; i++){
    977     pSettings->bwBorders[i] = noiseBandTable[i+1];
    978   }
    979 
    980   /*
    981    * Choose whitening factors
    982    */
    983 
    984   startFreqHz = ( (lsb + xoverOffset)*fs ) >> 7;  /* Shift does a division by 2*(64) */
    985 
    986   for( i = 1; i < NUM_WHFACTOR_TABLE_ENTRIES; i++ )
    987   {
    988     if( startFreqHz < FDK_sbrDecoder_sbr_whFactorsIndex[i])
    989       break;
    990   }
    991   i--;
    992 
    993   pSettings->whFactors.off = FDK_sbrDecoder_sbr_whFactorsTable[i][0];
    994   pSettings->whFactors.transitionLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][1];
    995   pSettings->whFactors.lowLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][2];
    996   pSettings->whFactors.midLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][3];
    997   pSettings->whFactors.highLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][4];
    998 
    999   return SBRDEC_OK;
   1000 }
   1001