Home | History | Annotate | Download | only in src
      1 /* -----------------------------------------------------------------------------
      2 Software License for The Fraunhofer FDK AAC Codec Library for Android
      3 
      4  Copyright  1995 - 2018 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 encoder library ******************************
     96 
     97    Author(s):
     98 
     99    Description:
    100 
    101 *******************************************************************************/
    102 
    103 #include "ton_corr.h"
    104 
    105 #include "sbrenc_ram.h"
    106 #include "sbr_misc.h"
    107 #include "genericStds.h"
    108 #include "autocorr2nd.h"
    109 
    110 #define BAND_V_SIZE 32
    111 #define NUM_V_COMBINE \
    112   8 /* Must be a divisor of 64 and fulfill the ASSERTs below */
    113 
    114 /**************************************************************************/
    115 /*!
    116   \brief Calculates the tonal to noise ration for different frequency bands
    117    and time segments.
    118 
    119    The ratio between the predicted energy (tonal energy A) and the total
    120    energy (A + B) is calculated. This is converted to the ratio between
    121    the predicted energy (tonal energy A) and the non-predictable energy
    122    (noise energy B). Hence the quota-matrix contains A/B = q/(1-q).
    123 
    124    The samples in nrgVector are scaled by 1.0/16.0
    125    The samples in pNrgVectorFreq  are scaled by 1.0/2.0
    126    The samples in quotaMatrix are scaled by RELAXATION
    127 
    128   \return none.
    129 
    130 */
    131 /**************************************************************************/
    132 
    133 void FDKsbrEnc_CalculateTonalityQuotas(
    134     HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
    135     FIXP_DBL **RESTRICT
    136         sourceBufferReal, /*!< The real part of the QMF-matrix.  */
    137     FIXP_DBL **RESTRICT
    138         sourceBufferImag, /*!< The imaginary part of the QMF-matrix. */
    139     INT usb,     /*!< upper side band, highest + 1 QMF band in the SBR range. */
    140     INT qmfScale /*!< sclefactor of QMF subsamples */
    141 ) {
    142   INT i, k, r, r2, timeIndex, autoCorrScaling;
    143 
    144   INT startIndexMatrix = hTonCorr->startIndexMatrix;
    145   INT totNoEst = hTonCorr->numberOfEstimates;
    146   INT noEstPerFrame = hTonCorr->numberOfEstimatesPerFrame;
    147   INT move = hTonCorr->move;
    148   INT noQmfChannels = hTonCorr->noQmfChannels; /* Number of Bands */
    149   INT buffLen = hTonCorr->bufferLength;        /* Number of Slots */
    150   INT stepSize = hTonCorr->stepSize;
    151   INT *pBlockLength = hTonCorr->lpcLength;
    152   INT **RESTRICT signMatrix = hTonCorr->signMatrix;
    153   FIXP_DBL *RESTRICT nrgVector = hTonCorr->nrgVector;
    154   FIXP_DBL **RESTRICT quotaMatrix = hTonCorr->quotaMatrix;
    155   FIXP_DBL *RESTRICT pNrgVectorFreq = hTonCorr->nrgVectorFreq;
    156 
    157   FIXP_DBL *realBuf;
    158   FIXP_DBL *imagBuf;
    159 
    160   FIXP_DBL alphar[2], alphai[2], fac;
    161 
    162   C_ALLOC_SCRATCH_START(ac, ACORR_COEFS, 1)
    163   C_ALLOC_SCRATCH_START(realBufRef, FIXP_DBL, 2 * BAND_V_SIZE * NUM_V_COMBINE)
    164   realBuf = realBufRef;
    165   imagBuf = realBuf + BAND_V_SIZE * NUM_V_COMBINE;
    166 
    167   FDK_ASSERT(buffLen <= BAND_V_SIZE);
    168   FDK_ASSERT(sizeof(FIXP_DBL) * NUM_V_COMBINE * BAND_V_SIZE * 2 <
    169              (1024 * sizeof(FIXP_DBL) - sizeof(ACORR_COEFS)));
    170 
    171   /*
    172    * Buffering of the quotaMatrix and the quotaMatrixTransp.
    173    *********************************************************/
    174   for (i = 0; i < move; i++) {
    175     FDKmemcpy(quotaMatrix[i], quotaMatrix[i + noEstPerFrame],
    176               noQmfChannels * sizeof(FIXP_DBL));
    177     FDKmemcpy(signMatrix[i], signMatrix[i + noEstPerFrame],
    178               noQmfChannels * sizeof(INT));
    179   }
    180 
    181   FDKmemmove(nrgVector, nrgVector + noEstPerFrame, move * sizeof(FIXP_DBL));
    182   FDKmemclear(nrgVector + startIndexMatrix,
    183               (totNoEst - startIndexMatrix) * sizeof(FIXP_DBL));
    184   FDKmemclear(pNrgVectorFreq, noQmfChannels * sizeof(FIXP_DBL));
    185 
    186   /*
    187    * Calculate the quotas for the current time steps.
    188    **************************************************/
    189 
    190   for (r = 0; r < usb; r++) {
    191     int blockLength;
    192 
    193     k = hTonCorr->nextSample; /* startSample */
    194     timeIndex = startIndexMatrix;
    195     /* Copy as many as possible Band across all Slots at once */
    196     if (realBuf != realBufRef) {
    197       realBuf -= BAND_V_SIZE;
    198       imagBuf -= BAND_V_SIZE;
    199     } else {
    200       realBuf += BAND_V_SIZE * (NUM_V_COMBINE - 1);
    201       imagBuf += BAND_V_SIZE * (NUM_V_COMBINE - 1);
    202 
    203       for (i = 0; i < buffLen; i++) {
    204         int v;
    205         FIXP_DBL *ptr;
    206         ptr = realBuf + i;
    207         for (v = 0; v < NUM_V_COMBINE; v++) {
    208           ptr[0] = sourceBufferReal[i][r + v];
    209           ptr[0 + BAND_V_SIZE * NUM_V_COMBINE] = sourceBufferImag[i][r + v];
    210           ptr -= BAND_V_SIZE;
    211         }
    212       }
    213     }
    214 
    215     blockLength = pBlockLength[0];
    216 
    217     while (k <= buffLen - blockLength) {
    218       autoCorrScaling = fixMin(
    219           getScalefactor(&realBuf[k - LPC_ORDER], LPC_ORDER + blockLength),
    220           getScalefactor(&imagBuf[k - LPC_ORDER], LPC_ORDER + blockLength));
    221       autoCorrScaling = fixMax(0, autoCorrScaling - 1);
    222 
    223       scaleValues(&realBuf[k - LPC_ORDER], LPC_ORDER + blockLength,
    224                   autoCorrScaling);
    225       scaleValues(&imagBuf[k - LPC_ORDER], LPC_ORDER + blockLength,
    226                   autoCorrScaling);
    227 
    228       autoCorrScaling <<= 1; /* consider qmf buffer scaling twice */
    229       autoCorrScaling +=
    230           autoCorr2nd_cplx(ac, realBuf + k, imagBuf + k, blockLength);
    231 
    232       if (ac->det == FL2FXCONST_DBL(0.0f)) {
    233         alphar[1] = alphai[1] = FL2FXCONST_DBL(0.0f);
    234 
    235         alphar[0] = (ac->r01r) >> 2;
    236         alphai[0] = (ac->r01i) >> 2;
    237 
    238         fac = fMultDiv2(ac->r00r, ac->r11r) >> 1;
    239       } else {
    240         alphar[1] = (fMultDiv2(ac->r01r, ac->r12r) >> 1) -
    241                     (fMultDiv2(ac->r01i, ac->r12i) >> 1) -
    242                     (fMultDiv2(ac->r02r, ac->r11r) >> 1);
    243         alphai[1] = (fMultDiv2(ac->r01i, ac->r12r) >> 1) +
    244                     (fMultDiv2(ac->r01r, ac->r12i) >> 1) -
    245                     (fMultDiv2(ac->r02i, ac->r11r) >> 1);
    246 
    247         alphar[0] = (fMultDiv2(ac->r01r, ac->det) >> (ac->det_scale + 1)) +
    248                     fMult(alphar[1], ac->r12r) + fMult(alphai[1], ac->r12i);
    249         alphai[0] = (fMultDiv2(ac->r01i, ac->det) >> (ac->det_scale + 1)) +
    250                     fMult(alphai[1], ac->r12r) - fMult(alphar[1], ac->r12i);
    251 
    252         fac = fMultDiv2(ac->r00r, fMult(ac->det, ac->r11r)) >>
    253               (ac->det_scale + 1);
    254       }
    255 
    256       if (fac == FL2FXCONST_DBL(0.0f)) {
    257         quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f);
    258         signMatrix[timeIndex][r] = 0;
    259       } else {
    260         /* quotaMatrix is scaled with the factor RELAXATION
    261            parse RELAXATION in fractional part and shift factor: 1/(1/0.524288 *
    262            2^RELAXATION_SHIFT) */
    263         FIXP_DBL tmp, num, denom;
    264         INT numShift, denomShift, commonShift;
    265         INT sign;
    266 
    267         num = fMultDiv2(alphar[0], ac->r01r) + fMultDiv2(alphai[0], ac->r01i) -
    268               fMultDiv2(alphar[1], fMult(ac->r02r, ac->r11r)) -
    269               fMultDiv2(alphai[1], fMult(ac->r02i, ac->r11r));
    270         num = fixp_abs(num);
    271 
    272         denom = (fac >> 1) +
    273                 (fMultDiv2(fac, RELAXATION_FRACT) >> RELAXATION_SHIFT) - num;
    274         denom = fixp_abs(denom);
    275 
    276         num = fMult(num, RELAXATION_FRACT);
    277 
    278         numShift = CountLeadingBits(num) - 2;
    279         num = scaleValue(num, numShift);
    280 
    281         denomShift = CountLeadingBits(denom);
    282         denom = (FIXP_DBL)denom << denomShift;
    283 
    284         if ((num > FL2FXCONST_DBL(0.0f)) && (denom != FL2FXCONST_DBL(0.0f))) {
    285           commonShift =
    286               fixMin(numShift - denomShift + RELAXATION_SHIFT, DFRACT_BITS - 1);
    287           if (commonShift < 0) {
    288             commonShift = -commonShift;
    289             tmp = schur_div(num, denom, 16);
    290             commonShift = fixMin(commonShift, CountLeadingBits(tmp));
    291             quotaMatrix[timeIndex][r] = tmp << commonShift;
    292           } else {
    293             quotaMatrix[timeIndex][r] =
    294                 schur_div(num, denom, 16) >> commonShift;
    295           }
    296         } else {
    297           quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f);
    298         }
    299 
    300         if (ac->r11r != FL2FXCONST_DBL(0.0f)) {
    301           if (((ac->r01r >= FL2FXCONST_DBL(0.0f)) &&
    302                (ac->r11r >= FL2FXCONST_DBL(0.0f))) ||
    303               ((ac->r01r < FL2FXCONST_DBL(0.0f)) &&
    304                (ac->r11r < FL2FXCONST_DBL(0.0f)))) {
    305             sign = 1;
    306           } else {
    307             sign = -1;
    308           }
    309         } else {
    310           sign = 1;
    311         }
    312 
    313         if (sign < 0) {
    314           r2 = r; /* (INT) pow(-1, band); */
    315         } else {
    316           r2 = r + 1; /* (INT) pow(-1, band+1); */
    317         }
    318         signMatrix[timeIndex][r] = 1 - 2 * (r2 & 0x1);
    319       }
    320 
    321       nrgVector[timeIndex] +=
    322           ((ac->r00r) >>
    323            fixMin(DFRACT_BITS - 1,
    324                   (2 * qmfScale + autoCorrScaling + SCALE_NRGVEC)));
    325       /* pNrgVectorFreq[r] finally has to be divided by noEstPerFrame, replaced
    326        * division by shifting with one */
    327       pNrgVectorFreq[r] =
    328           pNrgVectorFreq[r] +
    329           ((ac->r00r) >>
    330            fixMin(DFRACT_BITS - 1,
    331                   (2 * qmfScale + autoCorrScaling + SCALE_NRGVEC)));
    332 
    333       blockLength = pBlockLength[1];
    334       k += stepSize;
    335       timeIndex++;
    336     }
    337   }
    338 
    339   C_ALLOC_SCRATCH_END(realBufRef, FIXP_DBL, 2 * BAND_V_SIZE * NUM_V_COMBINE)
    340   C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1)
    341 }
    342 
    343 /**************************************************************************/
    344 /*!
    345   \brief Extracts the parameters required in the decoder to obtain the
    346   correct tonal to noise ratio after SBR.
    347 
    348   Estimates the tonal to noise ratio of the original signal (using LPC).
    349   Predicts the tonal to noise ration of the SBR signal (in the decoder) by
    350   patching the tonal to noise ratio values similar to the patching of the
    351   lowband in the decoder. Given the tonal to noise ratio of the original
    352   and the SBR signal, it estimates the required amount of inverse filtering,
    353   additional noise as well as any additional sines.
    354 
    355   \return none.
    356 
    357 */
    358 /**************************************************************************/
    359 void FDKsbrEnc_TonCorrParamExtr(
    360     HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
    361     INVF_MODE *infVec, /*!< Vector where the inverse filtering levels will be
    362                           stored. */
    363     FIXP_DBL *noiseLevels, /*!< Vector where the noise levels will be stored. */
    364     INT *missingHarmonicFlag, /*!< Flag set to one or zero, dependent on if any
    365                                  strong sines are missing.*/
    366     UCHAR *missingHarmonicsIndex, /*!< Vector indicating where sines are
    367                                      missing. */
    368     UCHAR *envelopeCompensation,  /*!< Vector to store compensation values for
    369                                      the energies in. */
    370     const SBR_FRAME_INFO *frameInfo, /*!< Frame info struct, contains the time
    371                                         and frequency grid of the current
    372                                         frame.*/
    373     UCHAR *transientInfo,            /*!< Transient info.*/
    374     UCHAR *freqBandTable,            /*!< Frequency band tables for high-res.*/
    375     INT nSfb,           /*!< Number of scalefactor bands for high-res. */
    376     XPOS_MODE xposType, /*!< Type of transposer used in the decoder.*/
    377     UINT sbrSyntaxFlags) {
    378   INT band;
    379   INT transientFlag = transientInfo[1]; /*!< Flag indicating if a transient is
    380                                            present in the current frame. */
    381   INT transientPos = transientInfo[0];  /*!< Position of the transient.*/
    382   INT transientFrame, transientFrameInvfEst;
    383   INVF_MODE *infVecPtr;
    384 
    385   /* Determine if this is a frame where a transient starts...
    386 
    387   The detection of noise-floor, missing harmonics and invf_est, is not in sync
    388   for the non-buf-opt decoder such as AAC. Hence we need to keep track on the
    389   transient in the present frame as well as in the next.
    390   */
    391   transientFrame = 0;
    392   if (hTonCorr->transientNextFrame) { /* The transient was detected in the
    393                                          previous frame, but is actually */
    394     transientFrame = 1;
    395     hTonCorr->transientNextFrame = 0;
    396 
    397     if (transientFlag) {
    398       if (transientPos + hTonCorr->transientPosOffset >=
    399           frameInfo->borders[frameInfo->nEnvelopes]) {
    400         hTonCorr->transientNextFrame = 1;
    401       }
    402     }
    403   } else {
    404     if (transientFlag) {
    405       if (transientPos + hTonCorr->transientPosOffset <
    406           frameInfo->borders[frameInfo->nEnvelopes]) {
    407         transientFrame = 1;
    408         hTonCorr->transientNextFrame = 0;
    409       } else {
    410         hTonCorr->transientNextFrame = 1;
    411       }
    412     }
    413   }
    414   transientFrameInvfEst = transientFrame;
    415 
    416   /*
    417     Estimate the required invese filtereing level.
    418   */
    419   if (hTonCorr->switchInverseFilt)
    420     FDKsbrEnc_qmfInverseFilteringDetector(
    421         &hTonCorr->sbrInvFilt, hTonCorr->quotaMatrix, hTonCorr->nrgVector,
    422         hTonCorr->indexVector, hTonCorr->frameStartIndexInvfEst,
    423         hTonCorr->numberOfEstimatesPerFrame + hTonCorr->frameStartIndexInvfEst,
    424         transientFrameInvfEst, infVec);
    425 
    426   /*
    427       Detect what tones will be missing.
    428    */
    429   if (xposType == XPOS_LC) {
    430     FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(
    431         &hTonCorr->sbrMissingHarmonicsDetector, hTonCorr->quotaMatrix,
    432         hTonCorr->signMatrix, hTonCorr->indexVector, frameInfo, transientInfo,
    433         missingHarmonicFlag, missingHarmonicsIndex, freqBandTable, nSfb,
    434         envelopeCompensation, hTonCorr->nrgVectorFreq);
    435   } else {
    436     *missingHarmonicFlag = 0;
    437     FDKmemclear(missingHarmonicsIndex, nSfb * sizeof(UCHAR));
    438   }
    439 
    440   /*
    441     Noise floor estimation
    442   */
    443 
    444   infVecPtr = hTonCorr->sbrInvFilt.prevInvfMode;
    445 
    446   FDKsbrEnc_sbrNoiseFloorEstimateQmf(
    447       &hTonCorr->sbrNoiseFloorEstimate, frameInfo, noiseLevels,
    448       hTonCorr->quotaMatrix, hTonCorr->indexVector, *missingHarmonicFlag,
    449       hTonCorr->frameStartIndex, hTonCorr->numberOfEstimatesPerFrame,
    450       transientFrame, infVecPtr, sbrSyntaxFlags);
    451 
    452   /* Store the invfVec data for the next frame...*/
    453   for (band = 0; band < hTonCorr->sbrInvFilt.noDetectorBands; band++) {
    454     hTonCorr->sbrInvFilt.prevInvfMode[band] = infVec[band];
    455   }
    456 }
    457 
    458 /**************************************************************************/
    459 /*!
    460   \brief     Searches for the closest match in the frequency master table.
    461 
    462 
    463 
    464   \return   closest entry.
    465 
    466 */
    467 /**************************************************************************/
    468 static INT findClosestEntry(INT goalSb, UCHAR *v_k_master, INT numMaster,
    469                             INT direction) {
    470   INT index;
    471 
    472   if (goalSb <= v_k_master[0]) return v_k_master[0];
    473 
    474   if (goalSb >= v_k_master[numMaster]) return v_k_master[numMaster];
    475 
    476   if (direction) {
    477     index = 0;
    478     while (v_k_master[index] < goalSb) {
    479       index++;
    480     }
    481   } else {
    482     index = numMaster;
    483     while (v_k_master[index] > goalSb) {
    484       index--;
    485     }
    486   }
    487 
    488   return v_k_master[index];
    489 }
    490 
    491 /**************************************************************************/
    492 /*!
    493   \brief     resets the patch
    494 
    495 
    496 
    497   \return   errorCode, noError if successful.
    498 
    499 */
    500 /**************************************************************************/
    501 static INT resetPatch(
    502     HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
    503     INT xposctrl,                     /*!< Different patch modes. */
    504     INT highBandStartSb,              /*!< Start band of the SBR range. */
    505     UCHAR *v_k_master, /*!< Master frequency table from which all other table
    506                           are derived.*/
    507     INT numMaster,     /*!< Number of elements in the master table. */
    508     INT fs,            /*!< Sampling frequency. */
    509     INT noChannels)    /*!< Number of QMF-channels. */
    510 {
    511   INT patch, k, i;
    512   INT targetStopBand;
    513 
    514   PATCH_PARAM *patchParam = hTonCorr->patchParam;
    515 
    516   INT sbGuard = hTonCorr->guard;
    517   INT sourceStartBand;
    518   INT patchDistance;
    519   INT numBandsInPatch;
    520 
    521   INT lsb =
    522       v_k_master[0]; /* Lowest subband related to the synthesis filterbank */
    523   INT usb = v_k_master[numMaster]; /* Stop subband related to the synthesis
    524                                       filterbank */
    525   INT xoverOffset =
    526       highBandStartSb -
    527       v_k_master[0]; /* Calculate distance in subbands between k0 and kx */
    528 
    529   INT goalSb;
    530 
    531   /*
    532    * Initialize the patching parameter
    533    */
    534 
    535   if (xposctrl == 1) {
    536     lsb += xoverOffset;
    537     xoverOffset = 0;
    538   }
    539 
    540   goalSb = (INT)((2 * noChannels * 16000 + (fs >> 1)) / fs); /* 16 kHz band */
    541   goalSb = findClosestEntry(goalSb, v_k_master, numMaster,
    542                             1); /* Adapt region to master-table */
    543 
    544   /* First patch */
    545   sourceStartBand = hTonCorr->shiftStartSb + xoverOffset;
    546   targetStopBand = lsb + xoverOffset;
    547 
    548   /* even (odd) numbered channel must be patched to even (odd) numbered channel
    549    */
    550   patch = 0;
    551   while (targetStopBand < usb) {
    552     /* To many patches */
    553     if (patch >= MAX_NUM_PATCHES) return (1); /*Number of patches to high */
    554 
    555     patchParam[patch].guardStartBand = targetStopBand;
    556     targetStopBand += sbGuard;
    557     patchParam[patch].targetStartBand = targetStopBand;
    558 
    559     numBandsInPatch =
    560         goalSb - targetStopBand; /* get the desired range of the patch */
    561 
    562     if (numBandsInPatch >= lsb - sourceStartBand) {
    563       /* desired number bands are not available -> patch whole source range */
    564       patchDistance =
    565           targetStopBand - sourceStartBand; /* get the targetOffset */
    566       patchDistance =
    567           patchDistance & ~1; /* rounding off odd numbers and make all even */
    568       numBandsInPatch = lsb - (targetStopBand - patchDistance);
    569       numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch,
    570                                          v_k_master, numMaster, 0) -
    571                         targetStopBand; /* Adapt region to master-table */
    572     }
    573 
    574     /* desired number bands are available -> get the minimal even patching
    575      * distance */
    576     patchDistance =
    577         numBandsInPatch + targetStopBand - lsb; /* get minimal distance */
    578     patchDistance = (patchDistance + 1) &
    579                     ~1; /* rounding up odd numbers and make all even */
    580 
    581     if (numBandsInPatch <= 0) {
    582       patch--;
    583     } else {
    584       patchParam[patch].sourceStartBand = targetStopBand - patchDistance;
    585       patchParam[patch].targetBandOffs = patchDistance;
    586       patchParam[patch].numBandsInPatch = numBandsInPatch;
    587       patchParam[patch].sourceStopBand =
    588           patchParam[patch].sourceStartBand + numBandsInPatch;
    589 
    590       targetStopBand += patchParam[patch].numBandsInPatch;
    591     }
    592 
    593     /* All patches but first */
    594     sourceStartBand = hTonCorr->shiftStartSb;
    595 
    596     /* Check if we are close to goalSb */
    597     if (fixp_abs(targetStopBand - goalSb) < 3) {
    598       goalSb = usb;
    599     }
    600 
    601     patch++;
    602   }
    603 
    604   patch--;
    605 
    606   /* if highest patch contains less than three subband: skip it */
    607   if (patchParam[patch].numBandsInPatch < 3 && patch > 0) {
    608     patch--;
    609   }
    610 
    611   hTonCorr->noOfPatches = patch + 1;
    612 
    613   /* Assign the index-vector, so we know where to look for the high-band.
    614      -1 represents a guard-band. */
    615   for (k = 0; k < hTonCorr->patchParam[0].guardStartBand; k++)
    616     hTonCorr->indexVector[k] = k;
    617 
    618   for (i = 0; i < hTonCorr->noOfPatches; i++) {
    619     INT sourceStart = hTonCorr->patchParam[i].sourceStartBand;
    620     INT targetStart = hTonCorr->patchParam[i].targetStartBand;
    621     INT numberOfBands = hTonCorr->patchParam[i].numBandsInPatch;
    622     INT startGuardBand = hTonCorr->patchParam[i].guardStartBand;
    623 
    624     for (k = 0; k < (targetStart - startGuardBand); k++)
    625       hTonCorr->indexVector[startGuardBand + k] = -1;
    626 
    627     for (k = 0; k < numberOfBands; k++)
    628       hTonCorr->indexVector[targetStart + k] = sourceStart + k;
    629   }
    630 
    631   return (0);
    632 }
    633 
    634 /**************************************************************************/
    635 /*!
    636   \brief     Creates an instance of the tonality correction parameter module.
    637 
    638   The module includes modules for inverse filtering level estimation,
    639   missing harmonics detection and noise floor level estimation.
    640 
    641   \return   errorCode, noError if successful.
    642 */
    643 /**************************************************************************/
    644 INT FDKsbrEnc_CreateTonCorrParamExtr(
    645     HANDLE_SBR_TON_CORR_EST
    646         hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */
    647     INT chan)     /*!< Channel index, needed for mem allocation */
    648 {
    649   INT i;
    650   FIXP_DBL *quotaMatrix = GetRam_Sbr_quotaMatrix(chan);
    651   INT *signMatrix = GetRam_Sbr_signMatrix(chan);
    652 
    653   if ((NULL == quotaMatrix) || (NULL == signMatrix)) {
    654     goto bail;
    655   }
    656 
    657   FDKmemclear(hTonCorr, sizeof(SBR_TON_CORR_EST));
    658 
    659   for (i = 0; i < MAX_NO_OF_ESTIMATES; i++) {
    660     hTonCorr->quotaMatrix[i] = quotaMatrix + (i * 64);
    661     hTonCorr->signMatrix[i] = signMatrix + (i * 64);
    662   }
    663 
    664   if (0 != FDKsbrEnc_CreateSbrMissingHarmonicsDetector(
    665                &hTonCorr->sbrMissingHarmonicsDetector, chan)) {
    666     goto bail;
    667   }
    668 
    669   return 0;
    670 
    671 bail:
    672   hTonCorr->quotaMatrix[0] = quotaMatrix;
    673   hTonCorr->signMatrix[0] = signMatrix;
    674 
    675   FDKsbrEnc_DeleteTonCorrParamExtr(hTonCorr);
    676 
    677   return -1;
    678 }
    679 
    680 /**************************************************************************/
    681 /*!
    682   \brief     Initialize an instance of the tonality correction parameter module.
    683 
    684   The module includes modules for inverse filtering level estimation,
    685   missing harmonics detection and noise floor level estimation.
    686 
    687   \return   errorCode, noError if successful.
    688 */
    689 /**************************************************************************/
    690 INT FDKsbrEnc_InitTonCorrParamExtr(
    691     INT frameSize, /*!< Current SBR frame size. */
    692     HANDLE_SBR_TON_CORR_EST
    693         hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */
    694     HANDLE_SBR_CONFIG_DATA
    695         sbrCfg,           /*!< Pointer to SBR configuration parameters. */
    696     INT timeSlots,        /*!< Number of time-slots per frame */
    697     INT xposCtrl,         /*!< Different patch modes. */
    698     INT ana_max_level,    /*!< Maximum level of the adaptive noise. */
    699     INT noiseBands,       /*!< Number of noise bands per octave. */
    700     INT noiseFloorOffset, /*!< Noise floor offset. */
    701     UINT useSpeechConfig) /*!< Speech or music tuning. */
    702 {
    703   INT nCols = sbrCfg->noQmfSlots;
    704   INT fs = sbrCfg->sampleFreq;
    705   INT noQmfChannels = sbrCfg->noQmfBands;
    706 
    707   INT highBandStartSb = sbrCfg->freqBandTable[LOW_RES][0];
    708   UCHAR *v_k_master = sbrCfg->v_k_master;
    709   INT numMaster = sbrCfg->num_Master;
    710 
    711   UCHAR **freqBandTable = sbrCfg->freqBandTable;
    712   INT *nSfb = sbrCfg->nSfb;
    713 
    714   INT i;
    715 
    716   /*
    717   Reset the patching and allocate memory for the quota matrix.
    718   Assuming parameters for the LPC analysis.
    719   */
    720   if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
    721     switch (timeSlots) {
    722       case NUMBER_TIME_SLOTS_1920:
    723         hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
    724         hTonCorr->lpcLength[1] = 7 - LPC_ORDER;
    725         hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
    726         hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 7 */
    727         hTonCorr->frameStartIndexInvfEst = 0;
    728         hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
    729         break;
    730       case NUMBER_TIME_SLOTS_2048:
    731         hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
    732         hTonCorr->lpcLength[1] = 8 - LPC_ORDER;
    733         hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
    734         hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 8 */
    735         hTonCorr->frameStartIndexInvfEst = 0;
    736         hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
    737         break;
    738     }
    739   } else
    740     switch (timeSlots) {
    741       case NUMBER_TIME_SLOTS_2048:
    742         hTonCorr->lpcLength[0] = 16 - LPC_ORDER; /* blockLength[0] */
    743         hTonCorr->lpcLength[1] = 16 - LPC_ORDER; /* blockLength[0] */
    744         hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC;
    745         hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 16;
    746         hTonCorr->frameStartIndexInvfEst = 0;
    747         hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_2048;
    748         break;
    749       case NUMBER_TIME_SLOTS_1920:
    750         hTonCorr->lpcLength[0] = 15 - LPC_ORDER; /* blockLength[0] */
    751         hTonCorr->lpcLength[1] = 15 - LPC_ORDER; /* blockLength[0] */
    752         hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC;
    753         hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 15;
    754         hTonCorr->frameStartIndexInvfEst = 0;
    755         hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_1920;
    756         break;
    757       default:
    758         return -1;
    759     }
    760 
    761   hTonCorr->bufferLength = nCols;
    762   hTonCorr->stepSize =
    763       hTonCorr->lpcLength[0] + LPC_ORDER; /* stepSize[0] implicitly 0. */
    764 
    765   hTonCorr->nextSample = LPC_ORDER; /* firstSample */
    766   hTonCorr->move = hTonCorr->numberOfEstimates -
    767                    hTonCorr->numberOfEstimatesPerFrame; /* Number of estimates
    768                                                            to move when
    769                                                            buffering.*/
    770   if (hTonCorr->move < 0) {
    771     return -1;
    772   }
    773   hTonCorr->startIndexMatrix =
    774       hTonCorr->numberOfEstimates -
    775       hTonCorr->numberOfEstimatesPerFrame; /* Where to store the latest
    776                                               estimations in the tonality
    777                                               Matrix.*/
    778   hTonCorr->frameStartIndex = 0; /* Where in the tonality matrix the current
    779                                     frame (to be sent to the decoder) starts. */
    780   hTonCorr->prevTransientFlag = 0;
    781   hTonCorr->transientNextFrame = 0;
    782 
    783   hTonCorr->noQmfChannels = noQmfChannels;
    784 
    785   for (i = 0; i < hTonCorr->numberOfEstimates; i++) {
    786     FDKmemclear(hTonCorr->quotaMatrix[i], sizeof(FIXP_DBL) * noQmfChannels);
    787     FDKmemclear(hTonCorr->signMatrix[i], sizeof(INT) * noQmfChannels);
    788   }
    789 
    790   /* Reset the patch.*/
    791   hTonCorr->guard = 0;
    792   hTonCorr->shiftStartSb = 1;
    793 
    794   if (resetPatch(hTonCorr, xposCtrl, highBandStartSb, v_k_master, numMaster, fs,
    795                  noQmfChannels))
    796     return (1);
    797 
    798   if (FDKsbrEnc_InitSbrNoiseFloorEstimate(
    799           &hTonCorr->sbrNoiseFloorEstimate, ana_max_level, freqBandTable[LO],
    800           nSfb[LO], noiseBands, noiseFloorOffset, timeSlots, useSpeechConfig))
    801     return (1);
    802 
    803   if (FDKsbrEnc_initInvFiltDetector(
    804           &hTonCorr->sbrInvFilt,
    805           hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
    806           hTonCorr->sbrNoiseFloorEstimate.noNoiseBands, useSpeechConfig))
    807     return (1);
    808 
    809   if (FDKsbrEnc_InitSbrMissingHarmonicsDetector(
    810           &hTonCorr->sbrMissingHarmonicsDetector, fs, frameSize, nSfb[HI],
    811           noQmfChannels, hTonCorr->numberOfEstimates, hTonCorr->move,
    812           hTonCorr->numberOfEstimatesPerFrame, sbrCfg->sbrSyntaxFlags))
    813     return (1);
    814 
    815   return (0);
    816 }
    817 
    818 /**************************************************************************/
    819 /*!
    820   \brief     resets tonality correction parameter module.
    821 
    822 
    823 
    824   \return   errorCode, noError if successful.
    825 
    826 */
    827 /**************************************************************************/
    828 INT FDKsbrEnc_ResetTonCorrParamExtr(
    829     HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
    830     INT xposctrl,                     /*!< Different patch modes. */
    831     INT highBandStartSb,              /*!< Start band of the SBR range. */
    832     UCHAR *v_k_master, /*!< Master frequency table from which all other table
    833                           are derived.*/
    834     INT numMaster,     /*!< Number of elements in the master table. */
    835     INT fs,            /*!< Sampling frequency (of the SBR part). */
    836     UCHAR *
    837         *freqBandTable, /*!< Frequency band table for low-res and high-res. */
    838     INT *nSfb,          /*!< Number of frequency bands (hig-res and low-res). */
    839     INT noQmfChannels   /*!< Number of QMF channels. */
    840 ) {
    841   /* Reset the patch.*/
    842   hTonCorr->guard = 0;
    843   hTonCorr->shiftStartSb = 1;
    844 
    845   if (resetPatch(hTonCorr, xposctrl, highBandStartSb, v_k_master, numMaster, fs,
    846                  noQmfChannels))
    847     return (1);
    848 
    849   /* Reset the noise floor estimate.*/
    850   if (FDKsbrEnc_resetSbrNoiseFloorEstimate(&hTonCorr->sbrNoiseFloorEstimate,
    851                                            freqBandTable[LO], nSfb[LO]))
    852     return (1);
    853 
    854   /*
    855   Reset the inveerse filtereing detector.
    856   */
    857   if (FDKsbrEnc_resetInvFiltDetector(
    858           &hTonCorr->sbrInvFilt,
    859           hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
    860           hTonCorr->sbrNoiseFloorEstimate.noNoiseBands))
    861     return (1);
    862   /* Reset the missing harmonics detector. */
    863   if (FDKsbrEnc_ResetSbrMissingHarmonicsDetector(
    864           &hTonCorr->sbrMissingHarmonicsDetector, nSfb[HI]))
    865     return (1);
    866 
    867   return (0);
    868 }
    869 
    870 /**************************************************************************/
    871 /*!
    872   \brief  Deletes the tonality correction paramtere module.
    873 
    874 
    875 
    876   \return   none
    877 
    878 */
    879 /**************************************************************************/
    880 void FDKsbrEnc_DeleteTonCorrParamExtr(
    881     HANDLE_SBR_TON_CORR_EST hTonCorr) /*!< Handle to SBR_TON_CORR struct. */
    882 {
    883   if (hTonCorr) {
    884     FreeRam_Sbr_quotaMatrix(hTonCorr->quotaMatrix);
    885 
    886     FreeRam_Sbr_signMatrix(hTonCorr->signMatrix);
    887 
    888     FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(
    889         &hTonCorr->sbrMissingHarmonicsDetector);
    890   }
    891 }
    892