1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5© Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
6  All rights reserved.
7
8 1.    INTRODUCTION
9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16of the MPEG specifications.
17
18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20individually for the purpose of encoding or decoding bit streams in products that are compliant with
21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27applications information and documentation.
28
292.    COPYRIGHT LICENSE
30
31Redistribution and use in source and binary forms, with or without modification, are permitted without
32payment of copyright license fees provided that you satisfy the following conditions:
33
34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35your modifications thereto in source code form.
36
37You must retain the complete text of this software license in the documentation and/or other materials
38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40modifications thereto to recipients of copies in binary form.
41
42The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43prior written permission.
44
45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46software or your modifications thereto.
47
48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49and 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
533.    NO PATENT LICENSE
54
55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57respect to this software.
58
59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60by appropriate patent licenses.
61
624.    DISCLAIMER
63
64This 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
66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69or business interruption, however caused and on any theory of liability, whether in contract, strict
70liability, or tort (including negligence), arising in any way out of the use of this software, even if
71advised of the possibility of such damage.
72
735.    CONTACT INFORMATION
74
75Fraunhofer Institute for Integrated Circuits IIS
76Attention: Audio and Multimedia Departments - FDK AAC LL
77Am Wolfsmantel 33
7891058 Erlangen, Germany
79
80www.iis.fraunhofer.de/amm
81amm-info@iis.fraunhofer.de
82----------------------------------------------------------------------------------------------------------- */
83
84#include "ton_corr.h"
85
86#include "sbr_ram.h"
87#include "sbr_misc.h"
88#include "genericStds.h"
89#include "autocorr2nd.h"
90
91
92
93/***************************************************************************
94
95  Send autoCorrSecondOrder to mlfile
96
97****************************************************************************/
98
99/**************************************************************************/
100/*!
101  \brief Calculates the tonal to noise ration for different frequency bands
102   and time segments.
103
104   The ratio between the predicted energy (tonal energy A) and the total
105   energy (A + B) is calculated. This is converted to the ratio between
106   the predicted energy (tonal energy A) and the non-predictable energy
107   (noise energy B). Hence the quota-matrix contains A/B = q/(1-q).
108
109   The samples in nrgVector are scaled by 1.0/16.0
110		The samples in pNrgVectorFreq	are scaled by 1.0/2.0
111   The samples in quotaMatrix are scaled by RELAXATION
112
113  \return none.
114
115*/
116/**************************************************************************/
117
118void
119FDKsbrEnc_CalculateTonalityQuotas( HANDLE_SBR_TON_CORR_EST hTonCorr,      /*!< Handle to SBR_TON_CORR struct. */
120                                   FIXP_DBL **RESTRICT sourceBufferReal,  /*!< The real part of the QMF-matrix.  */
121                                   FIXP_DBL **RESTRICT sourceBufferImag,  /*!< The imaginary part of the QMF-matrix. */
122                                   INT usb,                               /*!< upper side band, highest + 1 QMF band in the SBR range. */
123                                   INT qmfScale                       /*!< sclefactor of QMF subsamples */
124                                 )
125{
126  INT     i, k, r, r2, timeIndex, autoCorrScaling;
127
128  INT     startIndexMatrix  = hTonCorr->startIndexMatrix;
129  INT     totNoEst          = hTonCorr->numberOfEstimates;
130  INT     noEstPerFrame     = hTonCorr->numberOfEstimatesPerFrame;
131  INT     move              = hTonCorr->move;
132  INT     noQmfChannels     = hTonCorr->noQmfChannels;     /* Numer of Bands */
133  INT     buffLen           = hTonCorr->bufferLength;      /* Numer of Slots */
134  INT     stepSize          = hTonCorr->stepSize;
135  INT    *pBlockLength      = hTonCorr->lpcLength;
136  INT**   RESTRICT signMatrix        = hTonCorr->signMatrix;
137  FIXP_DBL* RESTRICT  nrgVector      = hTonCorr->nrgVector;
138  FIXP_DBL** RESTRICT quotaMatrix    = hTonCorr->quotaMatrix;
139  FIXP_DBL*  RESTRICT pNrgVectorFreq = hTonCorr->nrgVectorFreq;
140
141#define BAND_V_SIZE QMF_MAX_TIME_SLOTS
142#define NUM_V_COMBINE 8 /* Must be a divisor of 64 and fulfill the ASSERTs below */
143
144  FIXP_DBL *realBuf;
145  FIXP_DBL *imagBuf;
146
147  FIXP_DBL  alphar[2],alphai[2],fac;
148
149  C_ALLOC_SCRATCH_START(ac, ACORR_COEFS, 1);
150  C_ALLOC_SCRATCH_START(realBufRef, FIXP_DBL, 2*BAND_V_SIZE*NUM_V_COMBINE);
151
152  realBuf = realBufRef;
153  imagBuf = realBuf + BAND_V_SIZE*NUM_V_COMBINE;
154
155
156  FDK_ASSERT(buffLen <= BAND_V_SIZE);
157  FDK_ASSERT(sizeof(FIXP_DBL)*NUM_V_COMBINE*BAND_V_SIZE*2 < (1024*sizeof(FIXP_DBL)-sizeof(ACORR_COEFS)) );
158
159  /*
160   * Buffering of the quotaMatrix and the quotaMatrixTransp.
161   *********************************************************/
162  for(i =  0 ; i < move; i++){
163    FDKmemcpy(quotaMatrix[i],quotaMatrix[i + noEstPerFrame],noQmfChannels * sizeof(FIXP_DBL));
164    FDKmemcpy(signMatrix[i],signMatrix[i + noEstPerFrame],noQmfChannels * sizeof(INT));
165  }
166
167  FDKmemmove(nrgVector,nrgVector+noEstPerFrame,move*sizeof(FIXP_DBL));
168  FDKmemclear(nrgVector+startIndexMatrix,(totNoEst-startIndexMatrix)*sizeof(FIXP_DBL));
169  FDKmemclear(pNrgVectorFreq,noQmfChannels * sizeof(FIXP_DBL));
170
171  /*
172   * Calculate the quotas for the current time steps.
173   **************************************************/
174
175  for (r = 0; r < usb; r++)
176  {
177    int blockLength;
178
179    k = hTonCorr->nextSample; /* startSample */
180    timeIndex = startIndexMatrix;
181    /* Copy as many as possible Band accross all Slots at once */
182    if (realBuf != realBufRef) {
183      realBuf -= BAND_V_SIZE;
184      imagBuf -= BAND_V_SIZE;
185    } else {
186      realBuf += BAND_V_SIZE*(NUM_V_COMBINE-1);
187      imagBuf += BAND_V_SIZE*(NUM_V_COMBINE-1);
188      for (i = 0; i < buffLen; i++) {
189        int v;
190        FIXP_DBL *ptr;
191        ptr = realBuf+i;
192        for (v=0; v<NUM_V_COMBINE; v++)
193        {
194          ptr[0] = sourceBufferReal[i][r+v];
195          ptr[0+BAND_V_SIZE*NUM_V_COMBINE] = sourceBufferImag[i][r+v];
196          ptr -= BAND_V_SIZE;
197        }
198      }
199    }
200
201    blockLength = pBlockLength[0];
202
203    while(k <= buffLen - blockLength)
204    {
205      autoCorrScaling = fixMin(getScalefactor(&realBuf[k-LPC_ORDER], LPC_ORDER+blockLength), getScalefactor(&imagBuf[k-LPC_ORDER], LPC_ORDER+blockLength));
206      autoCorrScaling = fixMax(0, autoCorrScaling-1);
207
208      scaleValues(&realBuf[k-LPC_ORDER], LPC_ORDER+blockLength, autoCorrScaling);
209      scaleValues(&imagBuf[k-LPC_ORDER], LPC_ORDER+blockLength, autoCorrScaling);
210
211      autoCorrScaling <<= 1; /* consider qmf buffer scaling twice */
212      autoCorrScaling += autoCorr2nd_cplx ( ac, realBuf+k, imagBuf+k, blockLength );
213
214
215      if(ac->det == FL2FXCONST_DBL(0.0f)){
216        alphar[1] = alphai[1] = FL2FXCONST_DBL(0.0f);
217
218        alphar[0] = (ac->r01r)>>2;
219        alphai[0] = (ac->r01i)>>2;
220
221        fac = fMultDiv2(ac->r00r, ac->r11r)>>1;
222      }
223      else{
224        alphar[1] = (fMultDiv2(ac->r01r, ac->r12r)>>1) - (fMultDiv2(ac->r01i, ac->r12i)>>1) - (fMultDiv2(ac->r02r, ac->r11r)>>1);
225        alphai[1] = (fMultDiv2(ac->r01i, ac->r12r)>>1) + (fMultDiv2(ac->r01r, ac->r12i)>>1) - (fMultDiv2(ac->r02i, ac->r11r)>>1);
226
227        alphar[0] = (fMultDiv2(ac->r01r, ac->det)>>(ac->det_scale+1)) + fMult(alphar[1], ac->r12r) + fMult(alphai[1], ac->r12i);
228        alphai[0] = (fMultDiv2(ac->r01i, ac->det)>>(ac->det_scale+1)) + fMult(alphai[1], ac->r12r) - fMult(alphar[1], ac->r12i);
229
230        fac = fMultDiv2(ac->r00r, fMult(ac->det, ac->r11r))>>(ac->det_scale+1);
231      }
232
233      if(fac == FL2FXCONST_DBL(0.0f)){
234        quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f);
235        signMatrix[timeIndex][r] = 0;
236      }
237      else {
238        /* quotaMatrix is scaled with the factor RELAXATION
239           parse RELAXATION in fractional part and shift factor: 1/(1/0.524288 * 2^RELAXATION_SHIFT) */
240        FIXP_DBL tmp,num,denom;
241        INT numShift,denomShift,commonShift;
242        INT sign;
243
244        num = fMultDiv2(alphar[0], ac->r01r) + fMultDiv2(alphai[0], ac->r01i) - fMultDiv2(alphar[1], fMult(ac->r02r, ac->r11r)) - fMultDiv2(alphai[1], fMult(ac->r02i, ac->r11r));
245        num = fixp_abs(num);
246
247        denom = (fac>>1) + (fMultDiv2(fac,RELAXATION_FRACT)>>RELAXATION_SHIFT) - num;
248        denom = fixp_abs(denom);
249
250        num = fMult(num,RELAXATION_FRACT);
251
252        numShift = CountLeadingBits(num) - 2;
253        num = scaleValue(num, numShift);
254
255        denomShift = CountLeadingBits(denom);
256        denom = (FIXP_DBL)denom << denomShift;
257
258        if ((num > FL2FXCONST_DBL(0.0f)) && (denom != FL2FXCONST_DBL(0.0f))) {
259          commonShift = fixMin(numShift - denomShift + RELAXATION_SHIFT, DFRACT_BITS-1);
260          if (commonShift < 0) {
261            commonShift = -commonShift;
262            tmp = schur_div(num,denom,16);
263            commonShift = fixMin(commonShift,CountLeadingBits(tmp));
264            quotaMatrix[timeIndex][r] = tmp << commonShift;
265          }
266          else {
267            quotaMatrix[timeIndex][r] = schur_div(num,denom,16) >> commonShift;
268          }
269        }
270        else {
271          quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f);
272        }
273
274        if (ac->r11r != FL2FXCONST_DBL(0.0f)) {
275          if (  ( (ac->r01r >= FL2FXCONST_DBL(0.0f) ) && ( ac->r11r >= FL2FXCONST_DBL(0.0f) ) )
276              ||( (ac->r01r <  FL2FXCONST_DBL(0.0f) ) && ( ac->r11r <  FL2FXCONST_DBL(0.0f) ) )  ) {
277            sign = 1;
278          }
279          else {
280            sign = -1;
281          }
282        }
283        else {
284          sign = 1;
285        }
286
287        if(sign < 0) {
288          r2 = r;       /* (INT) pow(-1, band); */
289        }
290        else {
291          r2 = r + 1;   /* (INT) pow(-1, band+1); */
292        }
293        signMatrix[timeIndex][r] = 1 - 2*(r2 & 0x1);
294      }
295
296      nrgVector[timeIndex] += ((ac->r00r) >> fixMin(DFRACT_BITS-1,(2*qmfScale+autoCorrScaling + SCALE_NRGVEC)));
297      /* pNrgVectorFreq[r] finally has to be divided by noEstPerFrame, replaced division by shifting with one */
298      pNrgVectorFreq[r] = pNrgVectorFreq[r] + ((ac->r00r) >> fixMin(DFRACT_BITS-1,(2*qmfScale+autoCorrScaling + SCALE_NRGVEC)));
299
300      blockLength = pBlockLength[1];
301      k += stepSize;
302      timeIndex++;
303    }
304  }
305
306  FDK_ASSERT(noEstPerFrame == 2);
307
308
309  C_ALLOC_SCRATCH_END(realBuf, FIXP_DBL, 2*BAND_V_SIZE*NUM_V_COMBINE);
310  C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1);
311}
312
313/**************************************************************************/
314/*!
315  \brief Extracts the parameters required in the decoder to obtain the
316  correct tonal to noise ratio after SBR.
317
318  Estimates the tonal to noise ratio of the original signal (using LPC).
319  Predicts the tonal to noise ration of the SBR signal (in the decoder) by
320  patching the tonal to noise ratio values similar to the patching of the
321  lowband in the decoder. Given the tonal to noise ratio of the original
322  and the SBR signal, it estimates the required amount of inverse filtering,
323  additional noise as well as any additional sines.
324
325  \return none.
326
327*/
328/**************************************************************************/
329void
330FDKsbrEnc_TonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr,/*!< Handle to SBR_TON_CORR struct. */
331                           INVF_MODE* infVec,               /*!< Vector where the inverse filtering levels will be stored. */
332                           FIXP_DBL * noiseLevels,          /*!< Vector where the noise levels will be stored. */
333                           INT* missingHarmonicFlag,        /*!< Flag set to one or zero, dependent on if any strong sines are missing.*/
334                           UCHAR * missingHarmonicsIndex,   /*!< Vector indicating where sines are missing. */
335                           UCHAR * envelopeCompensation,    /*!< Vector to store compensation values for the energies in. */
336                           const SBR_FRAME_INFO *frameInfo, /*!< Frame info struct, contains the time and frequency grid of the current frame.*/
337                           UCHAR* transientInfo,            /*!< Transient info.*/
338                           UCHAR* freqBandTable,            /*!< Frequency band tables for high-res.*/
339                           INT nSfb,                        /*!< Number of scalefactor bands for high-res. */
340                           XPOS_MODE xposType,              /*!< Type of transposer used in the decoder.*/
341                           UINT sbrSyntaxFlags
342                           )
343{
344  INT band;
345  INT transientFlag = transientInfo[1] ;    /*!< Flag indicating if a transient is present in the current frame. */
346  INT transientPos  = transientInfo[0];     /*!< Position of the transient.*/
347  INT transientFrame, transientFrameInvfEst;
348  INVF_MODE* infVecPtr;
349
350
351  /* Determine if this is a frame where a transient starts...
352
353  The detection of noise-floor, missing harmonics and invf_est, is not in sync for the
354  non-buf-opt decoder such as AAC. Hence we need to keep track on the transient in the
355  present frame as well as in the next.
356  */
357  transientFrame = 0;
358  if(hTonCorr->transientNextFrame){       /* The transient was detected in the previous frame, but is actually */
359    transientFrame = 1;
360    hTonCorr->transientNextFrame = 0;
361
362    if(transientFlag){
363      if(transientPos + hTonCorr->transientPosOffset >= frameInfo->borders[frameInfo->nEnvelopes]){
364        hTonCorr->transientNextFrame = 1;
365      }
366    }
367  }
368  else{
369    if(transientFlag){
370      if(transientPos + hTonCorr->transientPosOffset < frameInfo->borders[frameInfo->nEnvelopes]){
371        transientFrame = 1;
372        hTonCorr->transientNextFrame = 0;
373      }
374      else{
375        hTonCorr->transientNextFrame = 1;
376      }
377    }
378  }
379  transientFrameInvfEst = transientFrame;
380
381
382  /*
383    Estimate the required invese filtereing level.
384  */
385  if (hTonCorr->switchInverseFilt)
386    FDKsbrEnc_qmfInverseFilteringDetector(&hTonCorr->sbrInvFilt,
387                                          hTonCorr->quotaMatrix,
388                                          hTonCorr->nrgVector,
389                                          hTonCorr->indexVector,
390                                          hTonCorr->frameStartIndexInvfEst,
391                                          hTonCorr->numberOfEstimatesPerFrame + hTonCorr->frameStartIndexInvfEst,
392                                          transientFrameInvfEst,
393                                          infVec);
394
395  /*
396      Detect what tones will be missing.
397   */
398  if (xposType == XPOS_LC ){
399    FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(&hTonCorr->sbrMissingHarmonicsDetector,
400                                             hTonCorr->quotaMatrix,
401                                             hTonCorr->signMatrix,
402                                             hTonCorr->indexVector,
403                                             frameInfo,
404                                             transientInfo,
405                                             missingHarmonicFlag,
406                                             missingHarmonicsIndex,
407                                             freqBandTable,
408                                             nSfb,
409                                             envelopeCompensation,
410                                             hTonCorr->nrgVectorFreq);
411  }
412  else{
413    *missingHarmonicFlag = 0;
414    FDKmemclear(missingHarmonicsIndex,nSfb*sizeof(UCHAR));
415  }
416
417
418
419  /*
420    Noise floor estimation
421  */
422
423  infVecPtr = hTonCorr->sbrInvFilt.prevInvfMode;
424
425  FDKsbrEnc_sbrNoiseFloorEstimateQmf(&hTonCorr->sbrNoiseFloorEstimate,
426                                     frameInfo,
427                                     noiseLevels,
428                                     hTonCorr->quotaMatrix,
429                                     hTonCorr->indexVector,
430                                     *missingHarmonicFlag,
431                                     hTonCorr->frameStartIndex,
432                                     hTonCorr->numberOfEstimatesPerFrame,
433                                     transientFrame,
434                                     infVecPtr,
435                                     sbrSyntaxFlags);
436
437
438  /* Store the invfVec data for the next frame...*/
439  for(band = 0 ; band < hTonCorr->sbrInvFilt.noDetectorBands; band++){
440    hTonCorr->sbrInvFilt.prevInvfMode[band] = infVec[band];
441  }
442}
443
444/**************************************************************************/
445/*!
446  \brief     Searches for the closest match in the frequency master table.
447
448
449
450  \return   closest entry.
451
452*/
453/**************************************************************************/
454static INT
455findClosestEntry(INT goalSb,
456                 UCHAR *v_k_master,
457                 INT numMaster,
458                 INT direction)
459{
460  INT index;
461
462  if( goalSb <= v_k_master[0] )
463    return v_k_master[0];
464
465  if( goalSb >= v_k_master[numMaster] )
466    return v_k_master[numMaster];
467
468  if(direction) {
469    index = 0;
470    while( v_k_master[index] < goalSb ) {
471      index++;
472    }
473  } else {
474    index = numMaster;
475    while( v_k_master[index] > goalSb ) {
476      index--;
477    }
478  }
479
480  return v_k_master[index];
481}
482
483
484/**************************************************************************/
485/*!
486  \brief     resets the patch
487
488
489
490  \return   errorCode, noError if successful.
491
492*/
493/**************************************************************************/
494static INT
495resetPatch(HANDLE_SBR_TON_CORR_EST hTonCorr,  /*!< Handle to SBR_TON_CORR struct. */
496           INT xposctrl,                      /*!< Different patch modes. */
497           INT highBandStartSb,               /*!< Start band of the SBR range. */
498           UCHAR *v_k_master,                   /*!< Master frequency table from which all other table are derived.*/
499           INT numMaster,                     /*!< Number of elements in the master table. */
500           INT fs,                            /*!< Sampling frequency. */
501           INT noChannels)                    /*!< Number of QMF-channels. */
502{
503  INT patch,k,i;
504  INT targetStopBand;
505
506  PATCH_PARAM  *patchParam = hTonCorr->patchParam;
507
508  INT sbGuard = hTonCorr->guard;
509  INT sourceStartBand;
510  INT patchDistance;
511  INT numBandsInPatch;
512
513  INT lsb = v_k_master[0];                           /* Lowest subband related to the synthesis filterbank */
514  INT usb = v_k_master[numMaster];                   /* Stop subband related to the synthesis filterbank */
515  INT xoverOffset = highBandStartSb - v_k_master[0]; /* Calculate distance in subbands between k0 and kx */
516
517  INT goalSb;
518
519
520  /*
521   * Initialize the patching parameter
522   */
523
524  if (xposctrl == 1) {
525    lsb += xoverOffset;
526    xoverOffset = 0;
527  }
528
529  goalSb = (INT)( (2 * noChannels * 16000 + (fs>>1)) / fs ); /* 16 kHz band */
530  goalSb = findClosestEntry(goalSb, v_k_master, numMaster, 1); /* Adapt region to master-table */
531
532  /* First patch */
533  sourceStartBand = hTonCorr->shiftStartSb + xoverOffset;
534  targetStopBand = lsb + xoverOffset;
535
536  /* even (odd) numbered channel must be patched to even (odd) numbered channel */
537  patch = 0;
538  while(targetStopBand < usb) {
539
540    /* To many patches */
541    if (patch >= MAX_NUM_PATCHES)
542      return(1); /*Number of patches to high */
543
544    patchParam[patch].guardStartBand = targetStopBand;
545    targetStopBand += sbGuard;
546    patchParam[patch].targetStartBand = targetStopBand;
547
548    numBandsInPatch = goalSb - targetStopBand;                   /* get the desired range of the patch */
549
550    if ( numBandsInPatch >= lsb - sourceStartBand ) {
551      /* desired number bands are not available -> patch whole source range */
552      patchDistance   = targetStopBand - sourceStartBand;        /* get the targetOffset */
553      patchDistance   = patchDistance & ~1;                      /* rounding off odd numbers and make all even */
554      numBandsInPatch = lsb - (targetStopBand - patchDistance);
555      numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch, v_k_master, numMaster, 0) -
556                        targetStopBand;  /* Adapt region to master-table */
557    }
558
559    /* desired number bands are available -> get the minimal even patching distance */
560    patchDistance   = numBandsInPatch + targetStopBand - lsb;  /* get minimal distance */
561    patchDistance   = (patchDistance + 1) & ~1;                /* rounding up odd numbers and make all even */
562
563    if (numBandsInPatch <= 0) {
564      patch--;
565    } else {
566      patchParam[patch].sourceStartBand = targetStopBand - patchDistance;
567      patchParam[patch].targetBandOffs  = patchDistance;
568      patchParam[patch].numBandsInPatch = numBandsInPatch;
569      patchParam[patch].sourceStopBand  = patchParam[patch].sourceStartBand + numBandsInPatch;
570
571      targetStopBand += patchParam[patch].numBandsInPatch;
572    }
573
574    /* All patches but first */
575    sourceStartBand = hTonCorr->shiftStartSb;
576
577    /* Check if we are close to goalSb */
578    if( fixp_abs(targetStopBand - goalSb) < 3) {
579      goalSb = usb;
580    }
581
582    patch++;
583
584  }
585
586  patch--;
587
588  /* if highest patch contains less than three subband: skip it */
589  if ( patchParam[patch].numBandsInPatch < 3 && patch > 0 ) {
590    patch--;
591    targetStopBand = patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch;
592  }
593
594  hTonCorr->noOfPatches = patch + 1;
595
596
597  /* Assign the index-vector, so we know where to look for the high-band.
598     -1 represents a guard-band. */
599  for(k = 0; k < hTonCorr->patchParam[0].guardStartBand; k++)
600    hTonCorr->indexVector[k] = k;
601
602  for(i = 0; i < hTonCorr->noOfPatches; i++)
603  {
604    INT sourceStart    = hTonCorr->patchParam[i].sourceStartBand;
605    INT targetStart    = hTonCorr->patchParam[i].targetStartBand;
606    INT numberOfBands  = hTonCorr->patchParam[i].numBandsInPatch;
607    INT startGuardBand = hTonCorr->patchParam[i].guardStartBand;
608
609    for(k = 0; k < (targetStart- startGuardBand); k++)
610      hTonCorr->indexVector[startGuardBand+k] = -1;
611
612    for(k = 0; k < numberOfBands; k++)
613      hTonCorr->indexVector[targetStart+k] = sourceStart+k;
614  }
615
616  return (0);
617}
618
619/**************************************************************************/
620/*!
621  \brief     Creates an instance of the tonality correction parameter module.
622
623  The module includes modules for inverse filtering level estimation,
624  missing harmonics detection and noise floor level estimation.
625
626  \return   errorCode, noError if successful.
627*/
628/**************************************************************************/
629INT
630FDKsbrEnc_CreateTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */
631                                 INT                     chan)     /*!< Channel index, needed for mem allocation */
632{
633  INT i;
634  FIXP_DBL* quotaMatrix = GetRam_Sbr_quotaMatrix(chan);
635  INT*      signMatrix  = GetRam_Sbr_signMatrix(chan);
636
637  FDKmemclear(hTonCorr, sizeof(SBR_TON_CORR_EST));
638
639  for (i=0; i<MAX_NO_OF_ESTIMATES; i++) {
640    hTonCorr->quotaMatrix[i] = quotaMatrix + (i*QMF_CHANNELS);
641    hTonCorr->signMatrix[i]  = signMatrix  + (i*QMF_CHANNELS);
642  }
643
644  FDKsbrEnc_CreateSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector, chan);
645
646  return 0;
647}
648
649
650
651/**************************************************************************/
652/*!
653  \brief     Initialize an instance of the tonality correction parameter module.
654
655  The module includes modules for inverse filtering level estimation,
656  missing harmonics detection and noise floor level estimation.
657
658  \return   errorCode, noError if successful.
659*/
660/**************************************************************************/
661INT
662FDKsbrEnc_InitTonCorrParamExtr (INT frameSize,                     /*!< Current SBR frame size. */
663                                HANDLE_SBR_TON_CORR_EST hTonCorr,  /*!< Pointer to handle to SBR_TON_CORR struct. */
664                                HANDLE_SBR_CONFIG_DATA sbrCfg,     /*!< Pointer to SBR configuration parameters. */
665                                INT timeSlots,                     /*!< Number of time-slots per frame */
666                                INT xposCtrl,                      /*!< Different patch modes. */
667                                INT ana_max_level,                 /*!< Maximum level of the adaptive noise. */
668                                INT noiseBands,                    /*!< Number of noise bands per octave. */
669                                INT noiseFloorOffset,              /*!< Noise floor offset. */
670                                UINT useSpeechConfig)              /*!< Speech or music tuning. */
671{
672  INT nCols = sbrCfg->noQmfSlots;
673  INT fs    = sbrCfg->sampleFreq;
674  INT noQmfChannels = sbrCfg->noQmfBands;
675
676  INT highBandStartSb = sbrCfg->freqBandTable[LOW_RES][0];
677  UCHAR *v_k_master   = sbrCfg->v_k_master;
678  INT numMaster       = sbrCfg->num_Master;
679
680  UCHAR **freqBandTable   = sbrCfg->freqBandTable;
681  INT    *nSfb            = sbrCfg->nSfb;
682
683  INT i;
684
685  /*
686  Reset the patching and allocate memory for the quota matrix.
687  Assing parameters for the LPC analysis.
688  */
689  if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
690    switch (timeSlots) {
691    case NUMBER_TIME_SLOTS_1920:
692      hTonCorr->lpcLength[0]              = 8 - LPC_ORDER;
693      hTonCorr->lpcLength[1]              = 7 - LPC_ORDER;
694      hTonCorr->numberOfEstimates         = NO_OF_ESTIMATES_LD;
695      hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 7;
696      hTonCorr->frameStartIndexInvfEst    = 0;
697      hTonCorr->transientPosOffset        = FRAME_MIDDLE_SLOT_512LD;
698      break;
699    case NUMBER_TIME_SLOTS_2048:
700      hTonCorr->lpcLength[0]              = 8 - LPC_ORDER;
701      hTonCorr->lpcLength[1]              = 8 - LPC_ORDER;
702      hTonCorr->numberOfEstimates         = NO_OF_ESTIMATES_LD;
703      hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 8;
704      hTonCorr->frameStartIndexInvfEst    = 0;
705      hTonCorr->transientPosOffset        = FRAME_MIDDLE_SLOT_512LD;
706      break;
707    }
708  } else
709  switch (timeSlots) {
710  case NUMBER_TIME_SLOTS_2048:
711    hTonCorr->lpcLength[0]              = 16 - LPC_ORDER; /* blockLength[0] */
712    hTonCorr->lpcLength[1]              = 16 - LPC_ORDER; /* blockLength[0] */
713    hTonCorr->numberOfEstimates         = NO_OF_ESTIMATES_LC;
714    hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 16;
715    hTonCorr->frameStartIndexInvfEst    = 0;
716    hTonCorr->transientPosOffset        = FRAME_MIDDLE_SLOT_2048;
717    break;
718  case NUMBER_TIME_SLOTS_1920:
719    hTonCorr->lpcLength[0]              = 15 - LPC_ORDER; /* blockLength[0] */
720    hTonCorr->lpcLength[1]              = 15 - LPC_ORDER; /* blockLength[0] */
721    hTonCorr->numberOfEstimates         = NO_OF_ESTIMATES_LC;
722    hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 15;
723    hTonCorr->frameStartIndexInvfEst    = 0;
724    hTonCorr->transientPosOffset        = FRAME_MIDDLE_SLOT_1920;
725    break;
726  default:
727    return -1;
728  }
729
730  hTonCorr->bufferLength              = nCols;
731  hTonCorr->stepSize                  = hTonCorr->lpcLength[0] + LPC_ORDER; /* stepSize[0] implicitly 0. */
732
733  hTonCorr->nextSample                = LPC_ORDER; /* firstSample */
734  hTonCorr->move                      = hTonCorr->numberOfEstimates - hTonCorr->numberOfEstimatesPerFrame;    /* Number of estimates to move when buffering.*/
735  hTonCorr->startIndexMatrix          = hTonCorr->numberOfEstimates - hTonCorr->numberOfEstimatesPerFrame;    /* Where to store the latest estimations in the tonality Matrix.*/
736  hTonCorr->frameStartIndex           = 0;                      /* Where in the tonality matrix the current frame (to be sent to the decoder) starts. */
737  hTonCorr->prevTransientFlag = 0;
738  hTonCorr->transientNextFrame = 0;
739
740  hTonCorr->noQmfChannels = noQmfChannels;
741
742  for (i=0; i<hTonCorr->numberOfEstimates; i++) {
743    FDKmemclear (hTonCorr->quotaMatrix[i] , sizeof(FIXP_DBL)*noQmfChannels);
744    FDKmemclear (hTonCorr->signMatrix[i] , sizeof(INT)*noQmfChannels);
745  }
746
747   /* Reset the patch.*/
748  hTonCorr->guard = 0;
749  hTonCorr->shiftStartSb = 1;
750
751  if(resetPatch(hTonCorr,
752                xposCtrl,
753                highBandStartSb,
754                v_k_master,
755                numMaster,
756                fs,
757                noQmfChannels))
758    return(1);
759
760  if(FDKsbrEnc_InitSbrNoiseFloorEstimate (&hTonCorr->sbrNoiseFloorEstimate,
761                                   ana_max_level,
762                                   freqBandTable[LO],
763                                   nSfb[LO],
764                                   noiseBands,
765                                   noiseFloorOffset,
766                                   timeSlots,
767                                   useSpeechConfig))
768    return(1);
769
770
771  if(FDKsbrEnc_initInvFiltDetector(&hTonCorr->sbrInvFilt,
772                            hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
773                            hTonCorr->sbrNoiseFloorEstimate.noNoiseBands,
774                            useSpeechConfig))
775    return(1);
776
777
778
779  if(FDKsbrEnc_InitSbrMissingHarmonicsDetector(
780                                        &hTonCorr->sbrMissingHarmonicsDetector,
781                                        fs,
782                                        frameSize,
783                                        nSfb[HI],
784                                        noQmfChannels,
785                                        hTonCorr->numberOfEstimates,
786                                        hTonCorr->move,
787                                        hTonCorr->numberOfEstimatesPerFrame,
788                                        sbrCfg->sbrSyntaxFlags))
789    return(1);
790
791
792
793  return (0);
794}
795
796
797
798/**************************************************************************/
799/*!
800  \brief     resets tonality correction parameter module.
801
802
803
804  \return   errorCode, noError if successful.
805
806*/
807/**************************************************************************/
808INT
809FDKsbrEnc_ResetTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
810                      INT xposctrl,                     /*!< Different patch modes. */
811                      INT highBandStartSb,              /*!< Start band of the SBR range. */
812                      UCHAR *v_k_master,        /*!< Master frequency table from which all other table are derived.*/
813                      INT numMaster,                    /*!< Number of elements in the master table. */
814                      INT fs,                           /*!< Sampling frequency (of the SBR part). */
815                      UCHAR ** freqBandTable,   /*!< Frequency band table for low-res and high-res. */
816                      INT* nSfb,                        /*!< Number of frequency bands (hig-res and low-res). */
817                      INT noQmfChannels                 /*!< Number of QMF channels. */
818                      )
819{
820
821  /* Reset the patch.*/
822  hTonCorr->guard = 0;
823  hTonCorr->shiftStartSb = 1;
824
825  if(resetPatch(hTonCorr,
826                xposctrl,
827                highBandStartSb,
828                v_k_master,
829                numMaster,
830                fs,
831                noQmfChannels))
832    return(1);
833
834
835
836  /* Reset the noise floor estimate.*/
837  if(FDKsbrEnc_resetSbrNoiseFloorEstimate (&hTonCorr->sbrNoiseFloorEstimate,
838                                 freqBandTable[LO],
839                                 nSfb[LO]))
840    return(1);
841
842  /*
843  Reset the inveerse filtereing detector.
844  */
845  if(FDKsbrEnc_resetInvFiltDetector(&hTonCorr->sbrInvFilt,
846                           hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
847                           hTonCorr->sbrNoiseFloorEstimate.noNoiseBands))
848    return(1);
849/* Reset the missing harmonics detector. */
850  if(FDKsbrEnc_ResetSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector,
851                                       nSfb[HI]))
852    return(1);
853
854  return (0);
855}
856
857
858
859
860
861/**************************************************************************/
862/*!
863  \brief  Deletes the tonality correction paramtere module.
864
865
866
867  \return   none
868
869*/
870/**************************************************************************/
871void
872FDKsbrEnc_DeleteTonCorrParamExtr (HANDLE_SBR_TON_CORR_EST hTonCorr) /*!< Handle to SBR_TON_CORR struct. */
873{
874
875  if (hTonCorr) {
876
877   FreeRam_Sbr_quotaMatrix(hTonCorr->quotaMatrix);
878
879   FreeRam_Sbr_signMatrix(hTonCorr->signMatrix);
880
881   FDKsbrEnc_DeleteSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector);
882  }
883}
884