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