1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software 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
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17 
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24 
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28 
29 2.    COPYRIGHT LICENSE
30 
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33 
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36 
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41 
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44 
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47 
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52 
53 3.    NO PATENT LICENSE
54 
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58 
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61 
62 4.    DISCLAIMER
63 
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72 
73 5.    CONTACT INFORMATION
74 
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79 
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
83 
84 #include "invf_est.h"
85 #include "sbr_misc.h"
86 
87 #include "genericStds.h"
88 
89 #define MAX_NUM_REGIONS 10
90 #define SCALE_FAC_QUO   512.0f
91 #define SCALE_FAC_NRG   256.0f
92 
93 #ifndef min
94 #define min(a,b) ( a < b ? a:b)
95 #endif
96 
97 #ifndef max
98 #define max(a,b) ( a > b ? a:b)
99 #endif
100 
101 static const FIXP_DBL quantStepsSbr[4]  =  { 0x00400000, 0x02800000, 0x03800000, 0x04c00000 } ;    /* table scaled with SCALE_FAC_QUO */
102 static const FIXP_DBL quantStepsOrig[4] =  { 0x00000000, 0x00c00000, 0x01c00000, 0x02800000 } ;    /* table scaled with SCALE_FAC_QUO */
103 static const FIXP_DBL nrgBorders[4]     =  { 0x0c800000, 0x0f000000, 0x11800000, 0x14000000 } ;    /* table scaled with SCALE_FAC_NRG */
104 
105 static const DETECTOR_PARAMETERS detectorParamsAAC = {
106     quantStepsSbr,
107     quantStepsOrig,
108     nrgBorders,
109     4,                              /* Number of borders SBR. */
110     4,                              /* Number of borders orig. */
111     4,                              /* Number of borders Nrg. */
112     {                               /* Region space. */
113       {INVF_MID_LEVEL,   INVF_LOW_LEVEL,  INVF_OFF,        INVF_OFF, INVF_OFF}, /*    |      */
114       {INVF_MID_LEVEL,   INVF_LOW_LEVEL,  INVF_OFF,        INVF_OFF, INVF_OFF}, /*    |      */
115       {INVF_HIGH_LEVEL,  INVF_MID_LEVEL,  INVF_LOW_LEVEL,  INVF_OFF, INVF_OFF}, /* regionSbr */
116       {INVF_HIGH_LEVEL,  INVF_HIGH_LEVEL, INVF_MID_LEVEL,  INVF_OFF, INVF_OFF}, /*    |      */
117       {INVF_HIGH_LEVEL,  INVF_HIGH_LEVEL, INVF_MID_LEVEL,  INVF_OFF, INVF_OFF}  /*    |      */
118     },/*------------------------ regionOrig ---------------------------------*/
119     {                               /* Region space transient. */
120       {INVF_LOW_LEVEL,   INVF_LOW_LEVEL,  INVF_LOW_LEVEL,  INVF_OFF, INVF_OFF}, /*    |      */
121       {INVF_LOW_LEVEL,   INVF_LOW_LEVEL,  INVF_LOW_LEVEL,  INVF_OFF, INVF_OFF}, /*    |      */
122       {INVF_HIGH_LEVEL,  INVF_MID_LEVEL,  INVF_MID_LEVEL,  INVF_OFF, INVF_OFF}, /* regionSbr */
123       {INVF_HIGH_LEVEL,  INVF_HIGH_LEVEL, INVF_MID_LEVEL,  INVF_OFF, INVF_OFF}, /*    |      */
124       {INVF_HIGH_LEVEL,  INVF_HIGH_LEVEL, INVF_MID_LEVEL,  INVF_OFF, INVF_OFF}  /*    |      */
125     },/*------------------------ regionOrig ---------------------------------*/
126     {-4, -3, -2, -1, 0} /* Reduction factor of the inverse filtering for low energies.*/
127 };
128 
129 static const FIXP_DBL hysteresis = 0x00400000 ; /* Delta value for hysteresis. scaled with SCALE_FAC_QUO */
130 
131 /*
132  * AAC+SBR PARAMETERS for Speech
133  *********************************/
134 static const DETECTOR_PARAMETERS detectorParamsAACSpeech = {
135     quantStepsSbr,
136     quantStepsOrig,
137     nrgBorders,
138     4,                              /* Number of borders SBR. */
139     4,                              /* Number of borders orig. */
140     4,                              /* Number of borders Nrg. */
141     {                               /* Region space. */
142       {INVF_MID_LEVEL,   INVF_MID_LEVEL,  INVF_LOW_LEVEL,  INVF_OFF, INVF_OFF}, /*    |      */
143       {INVF_MID_LEVEL,   INVF_MID_LEVEL,  INVF_LOW_LEVEL,  INVF_OFF, INVF_OFF}, /*    |      */
144       {INVF_HIGH_LEVEL,  INVF_MID_LEVEL,  INVF_MID_LEVEL,  INVF_OFF, INVF_OFF}, /* regionSbr */
145       {INVF_HIGH_LEVEL,  INVF_HIGH_LEVEL, INVF_MID_LEVEL,  INVF_OFF, INVF_OFF}, /*    |      */
146       {INVF_HIGH_LEVEL,  INVF_HIGH_LEVEL, INVF_MID_LEVEL,  INVF_OFF, INVF_OFF}  /*    |      */
147     },/*------------------------ regionOrig ---------------------------------*/
148     {                               /* Region space transient. */
149       {INVF_MID_LEVEL,   INVF_MID_LEVEL,  INVF_LOW_LEVEL,  INVF_OFF, INVF_OFF}, /*    |      */
150       {INVF_MID_LEVEL,   INVF_MID_LEVEL,  INVF_LOW_LEVEL,  INVF_OFF, INVF_OFF}, /*    |      */
151       {INVF_HIGH_LEVEL,  INVF_MID_LEVEL,  INVF_MID_LEVEL,  INVF_OFF, INVF_OFF}, /* regionSbr */
152       {INVF_HIGH_LEVEL,  INVF_HIGH_LEVEL, INVF_MID_LEVEL,  INVF_OFF, INVF_OFF}, /*    |      */
153       {INVF_HIGH_LEVEL,  INVF_HIGH_LEVEL, INVF_MID_LEVEL,  INVF_OFF, INVF_OFF}  /*    |      */
154     },/*------------------------ regionOrig ---------------------------------*/
155     {-4, -3, -2, -1, 0} /* Reduction factor of the inverse filtering for low energies.*/
156 };
157 
158 /*
159  * Smoothing filters.
160  ************************/
161 typedef const FIXP_DBL FIR_FILTER[5];
162 
163 static const FIR_FILTER fir_0 = { 0x7fffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } ;
164 static const FIR_FILTER fir_1 = { 0x2aaaaa80, 0x555554ff, 0x00000000, 0x00000000, 0x00000000 } ;
165 static const FIR_FILTER fir_2 = { 0x10000000, 0x30000000, 0x40000000, 0x00000000, 0x00000000 } ;
166 static const FIR_FILTER fir_3 = { 0x077f80e8, 0x199999a0, 0x2bb3b240, 0x33333340, 0x00000000 } ;
167 static const FIR_FILTER fir_4 = { 0x04130598, 0x0ebdb000, 0x1becfa60, 0x2697a4c0, 0x2aaaaa80 } ;
168 
169 
170 static const FIR_FILTER *const fir_table[5] = {
171   &fir_0,
172   &fir_1,
173   &fir_2,
174   &fir_3,
175   &fir_4
176 };
177 
178 /**************************************************************************/
179 /*!
180   \brief     Calculates the values used for the detector.
181 
182 
183   \return    none
184 
185 */
186 /**************************************************************************/
187 static void
calculateDetectorValues(FIXP_DBL ** quotaMatrixOrig,SCHAR * indexVector,FIXP_DBL * nrgVector,DETECTOR_VALUES * detectorValues,INT startChannel,INT stopChannel,INT startIndex,INT stopIndex,INT numberOfStrongest)188 calculateDetectorValues(FIXP_DBL **quotaMatrixOrig,       /*!< Matrix holding the tonality values of the original. */
189                         SCHAR    *indexVector,            /*!< Index vector to obtain the patched data. */
190                         FIXP_DBL *nrgVector,              /*!< Energy vector. */
191                         DETECTOR_VALUES *detectorValues,  /*!< pointer to DETECTOR_VALUES struct. */
192                         INT startChannel,                 /*!< Start channel. */
193                         INT stopChannel,                  /*!< Stop channel. */
194                         INT startIndex,                   /*!< Start index. */
195                         INT stopIndex,                    /*!< Stop index. */
196                         INT numberOfStrongest             /*!< The number of sorted tonal components to be considered. */
197                         )
198 {
199   INT i,temp, j;
200 
201   const FIXP_DBL* filter = *fir_table[INVF_SMOOTHING_LENGTH];
202   FIXP_DBL origQuotaMeanStrongest, sbrQuotaMeanStrongest;
203   FIXP_DBL origQuota, sbrQuota;
204   FIXP_DBL invIndex, invChannel, invTemp;
205   FIXP_DBL quotaVecOrig[64], quotaVecSbr[64];
206 
207   FDKmemclear(quotaVecOrig,64*sizeof(FIXP_DBL));
208   FDKmemclear(quotaVecSbr,64*sizeof(FIXP_DBL));
209 
210   invIndex = GetInvInt(stopIndex-startIndex);
211   invChannel = GetInvInt(stopChannel-startChannel);
212 
213   /*
214    Calculate the mean value, over the current time segment, for the original, the HFR
215    and the difference, over all channels in the current frequency range.
216    NOTE: the averaging is done on the values quota/(1 - quota + RELAXATION).
217    */
218 
219   /* The original, the sbr signal and the total energy */
220   detectorValues->avgNrg = FL2FXCONST_DBL(0.0f);
221   for(j=startIndex; j<stopIndex; j++) {
222     for(i=startChannel; i<stopChannel; i++) {
223       quotaVecOrig[i] += fMult(quotaMatrixOrig[j][i], invIndex);
224 
225       if(indexVector[i] != -1)
226         quotaVecSbr[i] += fMult(quotaMatrixOrig[j][indexVector[i]], invIndex);
227     }
228     detectorValues->avgNrg += fMult(nrgVector[j], invIndex);
229   }
230 
231   /*
232    Calculate the mean value, over the current frequency range, for the original, the HFR
233    and the difference. Also calculate the same mean values for the three vectors, but only
234    includeing the x strongest copmponents.
235    */
236 
237   origQuota = FL2FXCONST_DBL(0.0f);
238   sbrQuota  = FL2FXCONST_DBL(0.0f);
239   for(i=startChannel; i<stopChannel; i++) {
240     origQuota += fMultDiv2(quotaVecOrig[i], invChannel);
241     sbrQuota  += fMultDiv2(quotaVecSbr[i], invChannel);
242   }
243 
244   /*
245    Calculate the mean value for the x strongest components
246   */
247   FDKsbrEnc_Shellsort_fract(quotaVecOrig+startChannel,stopChannel-startChannel);
248   FDKsbrEnc_Shellsort_fract(quotaVecSbr+startChannel,stopChannel-startChannel);
249 
250   origQuotaMeanStrongest = FL2FXCONST_DBL(0.0f);
251   sbrQuotaMeanStrongest  = FL2FXCONST_DBL(0.0f);
252 
253   temp = min(stopChannel - startChannel, numberOfStrongest);
254   invTemp = GetInvInt(temp);
255 
256   for(i=0; i<temp; i++) {
257     origQuotaMeanStrongest += fMultDiv2(quotaVecOrig[i + stopChannel - temp], invTemp);
258     sbrQuotaMeanStrongest  += fMultDiv2(quotaVecSbr[i + stopChannel - temp], invTemp);
259   }
260 
261   /*
262    The value for the strongest component
263   */
264   detectorValues->origQuotaMax = quotaVecOrig[stopChannel - 1];
265   detectorValues->sbrQuotaMax  = quotaVecSbr[stopChannel - 1];
266 
267   /*
268    Buffer values
269   */
270   FDKmemmove(detectorValues->origQuotaMean, detectorValues->origQuotaMean + 1, INVF_SMOOTHING_LENGTH*sizeof(FIXP_DBL));
271   FDKmemmove(detectorValues->sbrQuotaMean, detectorValues->sbrQuotaMean + 1, INVF_SMOOTHING_LENGTH*sizeof(FIXP_DBL));
272   FDKmemmove(detectorValues->origQuotaMeanStrongest, detectorValues->origQuotaMeanStrongest + 1, INVF_SMOOTHING_LENGTH*sizeof(FIXP_DBL));
273   FDKmemmove(detectorValues->sbrQuotaMeanStrongest, detectorValues->sbrQuotaMeanStrongest + 1, INVF_SMOOTHING_LENGTH*sizeof(FIXP_DBL));
274 
275   detectorValues->origQuotaMean[INVF_SMOOTHING_LENGTH]          = origQuota<<1;
276   detectorValues->sbrQuotaMean[INVF_SMOOTHING_LENGTH]           = sbrQuota<<1;
277   detectorValues->origQuotaMeanStrongest[INVF_SMOOTHING_LENGTH] = origQuotaMeanStrongest<<1;
278   detectorValues->sbrQuotaMeanStrongest[INVF_SMOOTHING_LENGTH]  = sbrQuotaMeanStrongest<<1;
279 
280   /*
281    Filter values
282   */
283   detectorValues->origQuotaMeanFilt = FL2FXCONST_DBL(0.0f);
284   detectorValues->sbrQuotaMeanFilt = FL2FXCONST_DBL(0.0f);
285   detectorValues->origQuotaMeanStrongestFilt = FL2FXCONST_DBL(0.0f);
286   detectorValues->sbrQuotaMeanStrongestFilt = FL2FXCONST_DBL(0.0f);
287 
288   for(i=0;i<INVF_SMOOTHING_LENGTH+1;i++) {
289     detectorValues->origQuotaMeanFilt += fMult(detectorValues->origQuotaMean[i], filter[i]);
290     detectorValues->sbrQuotaMeanFilt  += fMult(detectorValues->sbrQuotaMean[i], filter[i]);
291     detectorValues->origQuotaMeanStrongestFilt += fMult(detectorValues->origQuotaMeanStrongest[i], filter[i]);
292     detectorValues->sbrQuotaMeanStrongestFilt  += fMult(detectorValues->sbrQuotaMeanStrongest[i], filter[i]);
293   }
294 }
295 
296 /**************************************************************************/
297 /*!
298   \brief     Returns the region in which the input value belongs.
299 
300 
301 
302   \return    region.
303 
304 */
305 /**************************************************************************/
306 static INT
findRegion(FIXP_DBL currVal,const FIXP_DBL * borders,const INT numBorders)307 findRegion(FIXP_DBL currVal,        /*!< The current value. */
308            const FIXP_DBL *borders, /*!< The border of the regions. */
309            const INT numBorders     /*!< The number of borders. */
310            )
311 {
312   INT i;
313 
314   if(currVal < borders[0]){
315     return 0;
316   }
317 
318   for(i = 1; i < numBorders; i++){
319     if( currVal >= borders[i-1] && currVal < borders[i]){
320       return i;
321     }
322   }
323 
324   if(currVal >= borders[numBorders-1]){
325     return numBorders;
326   }
327 
328   return 0;  /* We never get here, it's just to avoid compiler warnings.*/
329 }
330 
331 /**************************************************************************/
332 /*!
333   \brief     Makes a clever decision based on the quota vector.
334 
335 
336   \return     decision on which invf mode to use
337 
338 */
339 /**************************************************************************/
340 static INVF_MODE
decisionAlgorithm(const DETECTOR_PARAMETERS * detectorParams,DETECTOR_VALUES * detectorValues,INT transientFlag,INT * prevRegionSbr,INT * prevRegionOrig)341 decisionAlgorithm(const DETECTOR_PARAMETERS *detectorParams,     /*!< Struct with the detector parameters. */
342                   DETECTOR_VALUES *detectorValues,               /*!< Struct with the detector values. */
343                   INT transientFlag,                             /*!< Flag indicating if there is a transient present.*/
344                   INT* prevRegionSbr,                            /*!< The previous region in which the Sbr value was. */
345                   INT* prevRegionOrig                            /*!< The previous region in which the Orig value was. */
346                   )
347 {
348   INT invFiltLevel, regionSbr, regionOrig, regionNrg;
349 
350   /*
351    Current thresholds.
352    */
353   const FIXP_DBL *quantStepsSbr  = detectorParams->quantStepsSbr;
354   const FIXP_DBL *quantStepsOrig = detectorParams->quantStepsOrig;
355   const FIXP_DBL *nrgBorders     = detectorParams->nrgBorders;
356   const INT numRegionsSbr     = detectorParams->numRegionsSbr;
357   const INT numRegionsOrig    = detectorParams->numRegionsOrig;
358   const INT numRegionsNrg     = detectorParams->numRegionsNrg;
359 
360   FIXP_DBL quantStepsSbrTmp[MAX_NUM_REGIONS];
361   FIXP_DBL quantStepsOrigTmp[MAX_NUM_REGIONS];
362 
363   /*
364    Current detector values.
365    */
366   FIXP_DBL origQuotaMeanFilt;
367   FIXP_DBL sbrQuotaMeanFilt;
368   FIXP_DBL nrg;
369 
370   /* 0.375 = 3.0 / 8.0; 0.31143075889 = log2(RELAXATION)/64.0; 0.625 = log(16)/64.0; 0.6875 = 44/64.0 */
371   origQuotaMeanFilt = (fMultDiv2(FL2FXCONST_DBL(2.f*0.375f), (FIXP_DBL)(CalcLdData(max(detectorValues->origQuotaMeanFilt,(FIXP_DBL)1)) + FL2FXCONST_DBL(0.31143075889f)))) << 0;  /* scaled by 1/2^9 */
372   sbrQuotaMeanFilt  = (fMultDiv2(FL2FXCONST_DBL(2.f*0.375f), (FIXP_DBL)(CalcLdData(max(detectorValues->sbrQuotaMeanFilt,(FIXP_DBL)1)) + FL2FXCONST_DBL(0.31143075889f)))) << 0;   /* scaled by 1/2^9 */
373   /* If energy is zero then we will get different results for different word lengths. */
374   nrg               = (fMultDiv2(FL2FXCONST_DBL(2.f*0.375f), (FIXP_DBL)(CalcLdData(detectorValues->avgNrg+(FIXP_DBL)1) + FL2FXCONST_DBL(0.0625f) + FL2FXCONST_DBL(0.6875f)))) << 0;     /* scaled by 1/2^8; 2^44 -> qmf energy scale */
375 
376   FDKmemcpy(quantStepsSbrTmp,quantStepsSbr,numRegionsSbr*sizeof(FIXP_DBL));
377   FDKmemcpy(quantStepsOrigTmp,quantStepsOrig,numRegionsOrig*sizeof(FIXP_DBL));
378 
379   if(*prevRegionSbr < numRegionsSbr)
380     quantStepsSbrTmp[*prevRegionSbr] = quantStepsSbr[*prevRegionSbr] + hysteresis;
381   if(*prevRegionSbr > 0)
382     quantStepsSbrTmp[*prevRegionSbr - 1] = quantStepsSbr[*prevRegionSbr - 1] - hysteresis;
383 
384   if(*prevRegionOrig < numRegionsOrig)
385     quantStepsOrigTmp[*prevRegionOrig] = quantStepsOrig[*prevRegionOrig] + hysteresis;
386   if(*prevRegionOrig > 0)
387     quantStepsOrigTmp[*prevRegionOrig - 1] = quantStepsOrig[*prevRegionOrig - 1] - hysteresis;
388 
389   regionSbr  = findRegion(sbrQuotaMeanFilt, quantStepsSbrTmp, numRegionsSbr);
390   regionOrig = findRegion(origQuotaMeanFilt, quantStepsOrigTmp, numRegionsOrig);
391   regionNrg  = findRegion(nrg,nrgBorders,numRegionsNrg);
392 
393   *prevRegionSbr = regionSbr;
394   *prevRegionOrig = regionOrig;
395 
396   /* Use different settings if a transient is present*/
397   invFiltLevel = (transientFlag == 1) ? detectorParams->regionSpaceTransient[regionSbr][regionOrig]
398                                       : detectorParams->regionSpace[regionSbr][regionOrig];
399 
400   /* Compensate for low energy.*/
401   invFiltLevel = max(invFiltLevel + detectorParams->EnergyCompFactor[regionNrg],0);
402 
403   return (INVF_MODE) (invFiltLevel);
404 }
405 
406 /**************************************************************************/
407 /*!
408   \brief     Estiamtion of the inverse filtering level required
409              in the decoder.
410 
411    A second order LPC is calculated for every filterbank channel, using
412    the covariance method. THe ratio between the energy of the predicted
413    signal and the energy of the non-predictable signal is calcualted.
414 
415   \return    none.
416 
417 */
418 /**************************************************************************/
419 void
FDKsbrEnc_qmfInverseFilteringDetector(HANDLE_SBR_INV_FILT_EST hInvFilt,FIXP_DBL ** quotaMatrix,FIXP_DBL * nrgVector,SCHAR * indexVector,INT startIndex,INT stopIndex,INT transientFlag,INVF_MODE * infVec)420 FDKsbrEnc_qmfInverseFilteringDetector(HANDLE_SBR_INV_FILT_EST hInvFilt,  /*!< Handle to the SBR_INV_FILT_EST struct. */
421                             FIXP_DBL **quotaMatrix,            /*!< The matrix holding the tonality values of the original. */
422                             FIXP_DBL *nrgVector,               /*!< The energy vector. */
423                             SCHAR    *indexVector,             /*!< Index vector to obtain the patched data. */
424                             INT startIndex,                    /*!< Start index. */
425                             INT stopIndex,                     /*!< Stop index. */
426                             INT transientFlag,                 /*!< Flag indicating if a transient is present or not.*/
427                             INVF_MODE* infVec                  /*!< Vector holding the inverse filtering levels. */
428                             )
429 {
430   INT band;
431 
432   /*
433    * Do the inverse filtering level estimation.
434    *****************************************************/
435   for(band = 0 ; band < hInvFilt->noDetectorBands; band++){
436     INT startChannel = hInvFilt->freqBandTableInvFilt[band];
437     INT stopChannel  = hInvFilt->freqBandTableInvFilt[band+1];
438 
439 
440     calculateDetectorValues( quotaMatrix,
441                              indexVector,
442                              nrgVector,
443                             &hInvFilt->detectorValues[band],
444                              startChannel,
445                              stopChannel,
446                              startIndex,
447                              stopIndex,
448                              hInvFilt->numberOfStrongest);
449 
450     infVec[band]= decisionAlgorithm( hInvFilt->detectorParams,
451                                     &hInvFilt->detectorValues[band],
452                                      transientFlag,
453                                     &hInvFilt->prevRegionSbr[band],
454                                     &hInvFilt->prevRegionOrig[band]);
455   }
456 
457 }
458 
459 
460 /**************************************************************************/
461 /*!
462   \brief     Initialize an instance of the inverse filtering level estimator.
463 
464 
465   \return   errorCode, noError if successful.
466 
467 */
468 /**************************************************************************/
469 INT
FDKsbrEnc_initInvFiltDetector(HANDLE_SBR_INV_FILT_EST hInvFilt,INT * freqBandTableDetector,INT numDetectorBands,UINT useSpeechConfig)470 FDKsbrEnc_initInvFiltDetector (HANDLE_SBR_INV_FILT_EST hInvFilt,   /*!< Pointer to a handle to the SBR_INV_FILT_EST struct. */
471                        INT* freqBandTableDetector,          /*!< Frequency band table for the inverse filtering. */
472                        INT numDetectorBands,                /*!< Number of inverse filtering bands. */
473                        UINT useSpeechConfig         /*!< Flag: adapt tuning parameters according to speech*/
474                        )
475 {
476   INT i;
477 
478   FDKmemclear( hInvFilt,sizeof(SBR_INV_FILT_EST));
479 
480   hInvFilt->detectorParams = (useSpeechConfig) ? &detectorParamsAACSpeech
481                                                : &detectorParamsAAC ;
482 
483   hInvFilt->noDetectorBandsMax = numDetectorBands;
484 
485   /*
486      Memory initialisation
487   */
488   for(i=0;i<hInvFilt->noDetectorBandsMax;i++){
489     FDKmemclear(&hInvFilt->detectorValues[i], sizeof(DETECTOR_VALUES));
490     hInvFilt->prevInvfMode[i]   = INVF_OFF;
491     hInvFilt->prevRegionOrig[i] = 0;
492     hInvFilt->prevRegionSbr[i]  = 0;
493   }
494 
495   /*
496   Reset the inverse fltering detector.
497   */
498   FDKsbrEnc_resetInvFiltDetector(hInvFilt,
499                        freqBandTableDetector,
500                        hInvFilt->noDetectorBandsMax);
501 
502   return (0);
503 }
504 
505 
506 /**************************************************************************/
507 /*!
508   \brief     resets sbr inverse filtering structure.
509 
510 
511 
512   \return   errorCode, noError if successful.
513 
514 */
515 /**************************************************************************/
516 INT
FDKsbrEnc_resetInvFiltDetector(HANDLE_SBR_INV_FILT_EST hInvFilt,INT * freqBandTableDetector,INT numDetectorBands)517 FDKsbrEnc_resetInvFiltDetector(HANDLE_SBR_INV_FILT_EST hInvFilt, /*!< Handle to the SBR_INV_FILT_EST struct. */
518                      INT* freqBandTableDetector,       /*!< Frequency band table for the inverse filtering. */
519                      INT numDetectorBands)             /*!< Number of inverse filtering bands. */
520 {
521 
522   hInvFilt->numberOfStrongest     = 1;
523   FDKmemcpy(hInvFilt->freqBandTableInvFilt,freqBandTableDetector,(numDetectorBands+1)*sizeof(INT));
524   hInvFilt->noDetectorBands = numDetectorBands;
525 
526   return (0);
527 }
528 
529 
530