1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5� Copyright  1995 - 2013 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
307  C_ALLOC_SCRATCH_END(realBuf, FIXP_DBL, 2*BAND_V_SIZE*NUM_V_COMBINE);
308  C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1);
309}
310
311/**************************************************************************/
312/*!
313  \brief Extracts the parameters required in the decoder to obtain the
314  correct tonal to noise ratio after SBR.
315
316  Estimates the tonal to noise ratio of the original signal (using LPC).
317  Predicts the tonal to noise ration of the SBR signal (in the decoder) by
318  patching the tonal to noise ratio values similar to the patching of the
319  lowband in the decoder. Given the tonal to noise ratio of the original
320  and the SBR signal, it estimates the required amount of inverse filtering,
321  additional noise as well as any additional sines.
322
323  \return none.
324
325*/
326/**************************************************************************/
327void
328FDKsbrEnc_TonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr,/*!< Handle to SBR_TON_CORR struct. */
329                           INVF_MODE* infVec,               /*!< Vector where the inverse filtering levels will be stored. */
330                           FIXP_DBL * noiseLevels,          /*!< Vector where the noise levels will be stored. */
331                           INT* missingHarmonicFlag,        /*!< Flag set to one or zero, dependent on if any strong sines are missing.*/
332                           UCHAR * missingHarmonicsIndex,   /*!< Vector indicating where sines are missing. */
333                           UCHAR * envelopeCompensation,    /*!< Vector to store compensation values for the energies in. */
334                           const SBR_FRAME_INFO *frameInfo, /*!< Frame info struct, contains the time and frequency grid of the current frame.*/
335                           UCHAR* transientInfo,            /*!< Transient info.*/
336                           UCHAR* freqBandTable,            /*!< Frequency band tables for high-res.*/
337                           INT nSfb,                        /*!< Number of scalefactor bands for high-res. */
338                           XPOS_MODE xposType,              /*!< Type of transposer used in the decoder.*/
339                           UINT sbrSyntaxFlags
340                           )
341{
342  INT band;
343  INT transientFlag = transientInfo[1] ;    /*!< Flag indicating if a transient is present in the current frame. */
344  INT transientPos  = transientInfo[0];     /*!< Position of the transient.*/
345  INT transientFrame, transientFrameInvfEst;
346  INVF_MODE* infVecPtr;
347
348
349  /* Determine if this is a frame where a transient starts...
350
351  The detection of noise-floor, missing harmonics and invf_est, is not in sync for the
352  non-buf-opt decoder such as AAC. Hence we need to keep track on the transient in the
353  present frame as well as in the next.
354  */
355  transientFrame = 0;
356  if(hTonCorr->transientNextFrame){       /* The transient was detected in the previous frame, but is actually */
357    transientFrame = 1;
358    hTonCorr->transientNextFrame = 0;
359
360    if(transientFlag){
361      if(transientPos + hTonCorr->transientPosOffset >= frameInfo->borders[frameInfo->nEnvelopes]){
362        hTonCorr->transientNextFrame = 1;
363      }
364    }
365  }
366  else{
367    if(transientFlag){
368      if(transientPos + hTonCorr->transientPosOffset < frameInfo->borders[frameInfo->nEnvelopes]){
369        transientFrame = 1;
370        hTonCorr->transientNextFrame = 0;
371      }
372      else{
373        hTonCorr->transientNextFrame = 1;
374      }
375    }
376  }
377  transientFrameInvfEst = transientFrame;
378
379
380  /*
381    Estimate the required invese filtereing level.
382  */
383  if (hTonCorr->switchInverseFilt)
384    FDKsbrEnc_qmfInverseFilteringDetector(&hTonCorr->sbrInvFilt,
385                                          hTonCorr->quotaMatrix,
386                                          hTonCorr->nrgVector,
387                                          hTonCorr->indexVector,
388                                          hTonCorr->frameStartIndexInvfEst,
389                                          hTonCorr->numberOfEstimatesPerFrame + hTonCorr->frameStartIndexInvfEst,
390                                          transientFrameInvfEst,
391                                          infVec);
392
393  /*
394      Detect what tones will be missing.
395   */
396  if (xposType == XPOS_LC ){
397    FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(&hTonCorr->sbrMissingHarmonicsDetector,
398                                             hTonCorr->quotaMatrix,
399                                             hTonCorr->signMatrix,
400                                             hTonCorr->indexVector,
401                                             frameInfo,
402                                             transientInfo,
403                                             missingHarmonicFlag,
404                                             missingHarmonicsIndex,
405                                             freqBandTable,
406                                             nSfb,
407                                             envelopeCompensation,
408                                             hTonCorr->nrgVectorFreq);
409  }
410  else{
411    *missingHarmonicFlag = 0;
412    FDKmemclear(missingHarmonicsIndex,nSfb*sizeof(UCHAR));
413  }
414
415
416
417  /*
418    Noise floor estimation
419  */
420
421  infVecPtr = hTonCorr->sbrInvFilt.prevInvfMode;
422
423  FDKsbrEnc_sbrNoiseFloorEstimateQmf(&hTonCorr->sbrNoiseFloorEstimate,
424                                     frameInfo,
425                                     noiseLevels,
426                                     hTonCorr->quotaMatrix,
427                                     hTonCorr->indexVector,
428                                     *missingHarmonicFlag,
429                                     hTonCorr->frameStartIndex,
430                                     hTonCorr->numberOfEstimatesPerFrame,
431                                     transientFrame,
432                                     infVecPtr,
433                                     sbrSyntaxFlags);
434
435
436  /* Store the invfVec data for the next frame...*/
437  for(band = 0 ; band < hTonCorr->sbrInvFilt.noDetectorBands; band++){
438    hTonCorr->sbrInvFilt.prevInvfMode[band] = infVec[band];
439  }
440}
441
442/**************************************************************************/
443/*!
444  \brief     Searches for the closest match in the frequency master table.
445
446
447
448  \return   closest entry.
449
450*/
451/**************************************************************************/
452static INT
453findClosestEntry(INT goalSb,
454                 UCHAR *v_k_master,
455                 INT numMaster,
456                 INT direction)
457{
458  INT index;
459
460  if( goalSb <= v_k_master[0] )
461    return v_k_master[0];
462
463  if( goalSb >= v_k_master[numMaster] )
464    return v_k_master[numMaster];
465
466  if(direction) {
467    index = 0;
468    while( v_k_master[index] < goalSb ) {
469      index++;
470    }
471  } else {
472    index = numMaster;
473    while( v_k_master[index] > goalSb ) {
474      index--;
475    }
476  }
477
478  return v_k_master[index];
479}
480
481
482/**************************************************************************/
483/*!
484  \brief     resets the patch
485
486
487
488  \return   errorCode, noError if successful.
489
490*/
491/**************************************************************************/
492static INT
493resetPatch(HANDLE_SBR_TON_CORR_EST hTonCorr,  /*!< Handle to SBR_TON_CORR struct. */
494           INT xposctrl,                      /*!< Different patch modes. */
495           INT highBandStartSb,               /*!< Start band of the SBR range. */
496           UCHAR *v_k_master,                   /*!< Master frequency table from which all other table are derived.*/
497           INT numMaster,                     /*!< Number of elements in the master table. */
498           INT fs,                            /*!< Sampling frequency. */
499           INT noChannels)                    /*!< Number of QMF-channels. */
500{
501  INT patch,k,i;
502  INT targetStopBand;
503
504  PATCH_PARAM  *patchParam = hTonCorr->patchParam;
505
506  INT sbGuard = hTonCorr->guard;
507  INT sourceStartBand;
508  INT patchDistance;
509  INT numBandsInPatch;
510
511  INT lsb = v_k_master[0];                           /* Lowest subband related to the synthesis filterbank */
512  INT usb = v_k_master[numMaster];                   /* Stop subband related to the synthesis filterbank */
513  INT xoverOffset = highBandStartSb - v_k_master[0]; /* Calculate distance in subbands between k0 and kx */
514
515  INT goalSb;
516
517
518  /*
519   * Initialize the patching parameter
520   */
521
522  if (xposctrl == 1) {
523    lsb += xoverOffset;
524    xoverOffset = 0;
525  }
526
527  goalSb = (INT)( (2 * noChannels * 16000 + (fs>>1)) / fs ); /* 16 kHz band */
528  goalSb = findClosestEntry(goalSb, v_k_master, numMaster, 1); /* Adapt region to master-table */
529
530  /* First patch */
531  sourceStartBand = hTonCorr->shiftStartSb + xoverOffset;
532  targetStopBand = lsb + xoverOffset;
533
534  /* even (odd) numbered channel must be patched to even (odd) numbered channel */
535  patch = 0;
536  while(targetStopBand < usb) {
537
538    /* To many patches */
539    if (patch >= MAX_NUM_PATCHES)
540      return(1); /*Number of patches to high */
541
542    patchParam[patch].guardStartBand = targetStopBand;
543    targetStopBand += sbGuard;
544    patchParam[patch].targetStartBand = targetStopBand;
545
546    numBandsInPatch = goalSb - targetStopBand;                   /* get the desired range of the patch */
547
548    if ( numBandsInPatch >= lsb - sourceStartBand ) {
549      /* desired number bands are not available -> patch whole source range */
550      patchDistance   = targetStopBand - sourceStartBand;        /* get the targetOffset */
551      patchDistance   = patchDistance & ~1;                      /* rounding off odd numbers and make all even */
552      numBandsInPatch = lsb - (targetStopBand - patchDistance);
553      numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch, v_k_master, numMaster, 0) -
554                        targetStopBand;  /* Adapt region to master-table */
555    }
556
557    /* desired number bands are available -> get the minimal even patching distance */
558    patchDistance   = numBandsInPatch + targetStopBand - lsb;  /* get minimal distance */
559    patchDistance   = (patchDistance + 1) & ~1;                /* rounding up odd numbers and make all even */
560
561    if (numBandsInPatch <= 0) {
562      patch--;
563    } else {
564      patchParam[patch].sourceStartBand = targetStopBand - patchDistance;
565      patchParam[patch].targetBandOffs  = patchDistance;
566      patchParam[patch].numBandsInPatch = numBandsInPatch;
567      patchParam[patch].sourceStopBand  = patchParam[patch].sourceStartBand + numBandsInPatch;
568
569      targetStopBand += patchParam[patch].numBandsInPatch;
570    }
571
572    /* All patches but first */
573    sourceStartBand = hTonCorr->shiftStartSb;
574
575    /* Check if we are close to goalSb */
576    if( fixp_abs(targetStopBand - goalSb) < 3) {
577      goalSb = usb;
578    }
579
580    patch++;
581
582  }
583
584  patch--;
585
586  /* if highest patch contains less than three subband: skip it */
587  if ( patchParam[patch].numBandsInPatch < 3 && patch > 0 ) {
588    patch--;
589    targetStopBand = patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch;
590  }
591
592  hTonCorr->noOfPatches = patch + 1;
593
594
595  /* Assign the index-vector, so we know where to look for the high-band.
596     -1 represents a guard-band. */
597  for(k = 0; k < hTonCorr->patchParam[0].guardStartBand; k++)
598    hTonCorr->indexVector[k] = k;
599
600  for(i = 0; i < hTonCorr->noOfPatches; i++)
601  {
602    INT sourceStart    = hTonCorr->patchParam[i].sourceStartBand;
603    INT targetStart    = hTonCorr->patchParam[i].targetStartBand;
604    INT numberOfBands  = hTonCorr->patchParam[i].numBandsInPatch;
605    INT startGuardBand = hTonCorr->patchParam[i].guardStartBand;
606
607    for(k = 0; k < (targetStart- startGuardBand); k++)
608      hTonCorr->indexVector[startGuardBand+k] = -1;
609
610    for(k = 0; k < numberOfBands; k++)
611      hTonCorr->indexVector[targetStart+k] = sourceStart+k;
612  }
613
614  return (0);
615}
616
617/**************************************************************************/
618/*!
619  \brief     Creates an instance of the tonality correction parameter module.
620
621  The module includes modules for inverse filtering level estimation,
622  missing harmonics detection and noise floor level estimation.
623
624  \return   errorCode, noError if successful.
625*/
626/**************************************************************************/
627INT
628FDKsbrEnc_CreateTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */
629                                 INT                     chan)     /*!< Channel index, needed for mem allocation */
630{
631  INT i;
632  FIXP_DBL* quotaMatrix = GetRam_Sbr_quotaMatrix(chan);
633  INT*      signMatrix  = GetRam_Sbr_signMatrix(chan);
634
635  FDKmemclear(hTonCorr, sizeof(SBR_TON_CORR_EST));
636
637  for (i=0; i<MAX_NO_OF_ESTIMATES; i++) {
638    hTonCorr->quotaMatrix[i] = quotaMatrix + (i*QMF_CHANNELS);
639    hTonCorr->signMatrix[i]  = signMatrix  + (i*QMF_CHANNELS);
640  }
641
642  FDKsbrEnc_CreateSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector, chan);
643
644  return 0;
645}
646
647
648
649/**************************************************************************/
650/*!
651  \brief     Initialize an instance of the tonality correction parameter module.
652
653  The module includes modules for inverse filtering level estimation,
654  missing harmonics detection and noise floor level estimation.
655
656  \return   errorCode, noError if successful.
657*/
658/**************************************************************************/
659INT
660FDKsbrEnc_InitTonCorrParamExtr (INT frameSize,                     /*!< Current SBR frame size. */
661                                HANDLE_SBR_TON_CORR_EST hTonCorr,  /*!< Pointer to handle to SBR_TON_CORR struct. */
662                                HANDLE_SBR_CONFIG_DATA sbrCfg,     /*!< Pointer to SBR configuration parameters. */
663                                INT timeSlots,                     /*!< Number of time-slots per frame */
664                                INT xposCtrl,                      /*!< Different patch modes. */
665                                INT ana_max_level,                 /*!< Maximum level of the adaptive noise. */
666                                INT noiseBands,                    /*!< Number of noise bands per octave. */
667                                INT noiseFloorOffset,              /*!< Noise floor offset. */
668                                UINT useSpeechConfig)              /*!< Speech or music tuning. */
669{
670  INT nCols = sbrCfg->noQmfSlots;
671  INT fs    = sbrCfg->sampleFreq;
672  INT noQmfChannels = sbrCfg->noQmfBands;
673
674  INT highBandStartSb = sbrCfg->freqBandTable[LOW_RES][0];
675  UCHAR *v_k_master   = sbrCfg->v_k_master;
676  INT numMaster       = sbrCfg->num_Master;
677
678  UCHAR **freqBandTable   = sbrCfg->freqBandTable;
679  INT    *nSfb            = sbrCfg->nSfb;
680
681  INT i;
682
683  /*
684  Reset the patching and allocate memory for the quota matrix.
685  Assing parameters for the LPC analysis.
686  */
687  if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
688    switch (timeSlots) {
689    case NUMBER_TIME_SLOTS_1920:
690      hTonCorr->lpcLength[0]              = 8 - LPC_ORDER;
691      hTonCorr->lpcLength[1]              = 7 - LPC_ORDER;
692      hTonCorr->numberOfEstimates         = NO_OF_ESTIMATES_LD;
693      hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 7;
694      hTonCorr->frameStartIndexInvfEst    = 0;
695      hTonCorr->transientPosOffset        = FRAME_MIDDLE_SLOT_512LD;
696      break;
697    case NUMBER_TIME_SLOTS_2048:
698      hTonCorr->lpcLength[0]              = 8 - LPC_ORDER;
699      hTonCorr->lpcLength[1]              = 8 - LPC_ORDER;
700      hTonCorr->numberOfEstimates         = NO_OF_ESTIMATES_LD;
701      hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 8;
702      hTonCorr->frameStartIndexInvfEst    = 0;
703      hTonCorr->transientPosOffset        = FRAME_MIDDLE_SLOT_512LD;
704      break;
705    }
706  } else
707  switch (timeSlots) {
708  case NUMBER_TIME_SLOTS_2048:
709    hTonCorr->lpcLength[0]              = 16 - LPC_ORDER; /* blockLength[0] */
710    hTonCorr->lpcLength[1]              = 16 - LPC_ORDER; /* blockLength[0] */
711    hTonCorr->numberOfEstimates         = NO_OF_ESTIMATES_LC;
712    hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 16;
713    hTonCorr->frameStartIndexInvfEst    = 0;
714    hTonCorr->transientPosOffset        = FRAME_MIDDLE_SLOT_2048;
715    break;
716  case NUMBER_TIME_SLOTS_1920:
717    hTonCorr->lpcLength[0]              = 15 - LPC_ORDER; /* blockLength[0] */
718    hTonCorr->lpcLength[1]              = 15 - LPC_ORDER; /* blockLength[0] */
719    hTonCorr->numberOfEstimates         = NO_OF_ESTIMATES_LC;
720    hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 15;
721    hTonCorr->frameStartIndexInvfEst    = 0;
722    hTonCorr->transientPosOffset        = FRAME_MIDDLE_SLOT_1920;
723    break;
724  default:
725    return -1;
726  }
727
728  hTonCorr->bufferLength              = nCols;
729  hTonCorr->stepSize                  = hTonCorr->lpcLength[0] + LPC_ORDER; /* stepSize[0] implicitly 0. */
730
731  hTonCorr->nextSample                = LPC_ORDER; /* firstSample */
732  hTonCorr->move                      = hTonCorr->numberOfEstimates - hTonCorr->numberOfEstimatesPerFrame;    /* Number of estimates to move when buffering.*/
733  hTonCorr->startIndexMatrix          = hTonCorr->numberOfEstimates - hTonCorr->numberOfEstimatesPerFrame;    /* Where to store the latest estimations in the tonality Matrix.*/
734  hTonCorr->frameStartIndex           = 0;                      /* Where in the tonality matrix the current frame (to be sent to the decoder) starts. */
735  hTonCorr->prevTransientFlag = 0;
736  hTonCorr->transientNextFrame = 0;
737
738  hTonCorr->noQmfChannels = noQmfChannels;
739
740  for (i=0; i<hTonCorr->numberOfEstimates; i++) {
741    FDKmemclear (hTonCorr->quotaMatrix[i] , sizeof(FIXP_DBL)*noQmfChannels);
742    FDKmemclear (hTonCorr->signMatrix[i] , sizeof(INT)*noQmfChannels);
743  }
744
745   /* Reset the patch.*/
746  hTonCorr->guard = 0;
747  hTonCorr->shiftStartSb = 1;
748
749  if(resetPatch(hTonCorr,
750                xposCtrl,
751                highBandStartSb,
752                v_k_master,
753                numMaster,
754                fs,
755                noQmfChannels))
756    return(1);
757
758  if(FDKsbrEnc_InitSbrNoiseFloorEstimate (&hTonCorr->sbrNoiseFloorEstimate,
759                                   ana_max_level,
760                                   freqBandTable[LO],
761                                   nSfb[LO],
762                                   noiseBands,
763                                   noiseFloorOffset,
764                                   timeSlots,
765                                   useSpeechConfig))
766    return(1);
767
768
769  if(FDKsbrEnc_initInvFiltDetector(&hTonCorr->sbrInvFilt,
770                            hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
771                            hTonCorr->sbrNoiseFloorEstimate.noNoiseBands,
772                            useSpeechConfig))
773    return(1);
774
775
776
777  if(FDKsbrEnc_InitSbrMissingHarmonicsDetector(
778                                        &hTonCorr->sbrMissingHarmonicsDetector,
779                                        fs,
780                                        frameSize,
781                                        nSfb[HI],
782                                        noQmfChannels,
783                                        hTonCorr->numberOfEstimates,
784                                        hTonCorr->move,
785                                        hTonCorr->numberOfEstimatesPerFrame,
786                                        sbrCfg->sbrSyntaxFlags))
787    return(1);
788
789
790
791  return (0);
792}
793
794
795
796/**************************************************************************/
797/*!
798  \brief     resets tonality correction parameter module.
799
800
801
802  \return   errorCode, noError if successful.
803
804*/
805/**************************************************************************/
806INT
807FDKsbrEnc_ResetTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
808                      INT xposctrl,                     /*!< Different patch modes. */
809                      INT highBandStartSb,              /*!< Start band of the SBR range. */
810                      UCHAR *v_k_master,        /*!< Master frequency table from which all other table are derived.*/
811                      INT numMaster,                    /*!< Number of elements in the master table. */
812                      INT fs,                           /*!< Sampling frequency (of the SBR part). */
813                      UCHAR ** freqBandTable,   /*!< Frequency band table for low-res and high-res. */
814                      INT* nSfb,                        /*!< Number of frequency bands (hig-res and low-res). */
815                      INT noQmfChannels                 /*!< Number of QMF channels. */
816                      )
817{
818
819  /* Reset the patch.*/
820  hTonCorr->guard = 0;
821  hTonCorr->shiftStartSb = 1;
822
823  if(resetPatch(hTonCorr,
824                xposctrl,
825                highBandStartSb,
826                v_k_master,
827                numMaster,
828                fs,
829                noQmfChannels))
830    return(1);
831
832
833
834  /* Reset the noise floor estimate.*/
835  if(FDKsbrEnc_resetSbrNoiseFloorEstimate (&hTonCorr->sbrNoiseFloorEstimate,
836                                 freqBandTable[LO],
837                                 nSfb[LO]))
838    return(1);
839
840  /*
841  Reset the inveerse filtereing detector.
842  */
843  if(FDKsbrEnc_resetInvFiltDetector(&hTonCorr->sbrInvFilt,
844                           hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
845                           hTonCorr->sbrNoiseFloorEstimate.noNoiseBands))
846    return(1);
847/* Reset the missing harmonics detector. */
848  if(FDKsbrEnc_ResetSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector,
849                                       nSfb[HI]))
850    return(1);
851
852  return (0);
853}
854
855
856
857
858
859/**************************************************************************/
860/*!
861  \brief  Deletes the tonality correction paramtere module.
862
863
864
865  \return   none
866
867*/
868/**************************************************************************/
869void
870FDKsbrEnc_DeleteTonCorrParamExtr (HANDLE_SBR_TON_CORR_EST hTonCorr) /*!< Handle to SBR_TON_CORR struct. */
871{
872
873  if (hTonCorr) {
874
875   FreeRam_Sbr_quotaMatrix(hTonCorr->quotaMatrix);
876
877   FreeRam_Sbr_signMatrix(hTonCorr->signMatrix);
878
879   FDKsbrEnc_DeleteSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector);
880  }
881}
882