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