xref: /aosp_15_r20/external/aac/libSBRdec/src/lpp_tran.cpp (revision e54365361535b070c2db7374cec45c159c7d0e7a)
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6 
7  1.    INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18 
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28 
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33 
34 2.    COPYRIGHT LICENSE
35 
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39 
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42 
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48 
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51 
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54 
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60 
61 3.    NO PATENT LICENSE
62 
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67 
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70 
71 4.    DISCLAIMER
72 
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83 
84 5.    CONTACT INFORMATION
85 
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90 
91 www.iis.fraunhofer.de/amm
92 [email protected]
93 ----------------------------------------------------------------------------- */
94 
95 /**************************** SBR decoder library ******************************
96 
97    Author(s):
98 
99    Description:
100 
101 *******************************************************************************/
102 
103 /*!
104   \file
105   \brief  Low Power Profile Transposer
106   This module provides the transposer. The main entry point is lppTransposer().
107   The function generates high frequency content by copying data from the low
108   band (provided by core codec) into the high band. This process is also
109   referred to as "patching". The function also implements spectral whitening by
110   means of inverse filtering based on LPC coefficients.
111 
112   Together with the QMF filterbank the transposer can be tested using a supplied
113   test program. See main_audio.cpp for details. This module does use fractional
114   arithmetic and the accuracy of the computations has an impact on the overall
115   sound quality. The module also needs to take into account the different
116   scaling of spectral data.
117 
118   \sa lppTransposer(), main_audio.cpp, sbr_scale.h, \ref documentationOverview
119 */
120 
121 #if __has_include(<android/ndk-version.h>)
122 #include <android/ndk-version.h>
123 #endif
124 
125 #if defined __ANDROID__ && !defined __ANDROID_NDK__
126 #include "log/log.h"
127 #endif
128 
129 #include "lpp_tran.h"
130 
131 #include "sbr_ram.h"
132 #include "sbr_rom.h"
133 
134 #include "genericStds.h"
135 #include "autocorr2nd.h"
136 
137 #include "HFgen_preFlat.h"
138 
139 #define LPC_SCALE_FACTOR 2
140 
141 /*!
142  *
143  * \brief Get bandwidth expansion factor from filtering level
144  *
145  * Returns a filter parameter (bandwidth expansion factor) depending on
146  * the desired filtering level signalled in the bitstream.
147  * When switching the filtering level from LOW to OFF, an additional
148  * level is being inserted to achieve a smooth transition.
149  */
150 
mapInvfMode(INVF_MODE mode,INVF_MODE prevMode,WHITENING_FACTORS whFactors)151 static FIXP_DBL mapInvfMode(INVF_MODE mode, INVF_MODE prevMode,
152                             WHITENING_FACTORS whFactors) {
153   switch (mode) {
154     case INVF_LOW_LEVEL:
155       if (prevMode == INVF_OFF)
156         return whFactors.transitionLevel;
157       else
158         return whFactors.lowLevel;
159 
160     case INVF_MID_LEVEL:
161       return whFactors.midLevel;
162 
163     case INVF_HIGH_LEVEL:
164       return whFactors.highLevel;
165 
166     default:
167       if (prevMode == INVF_LOW_LEVEL)
168         return whFactors.transitionLevel;
169       else
170         return whFactors.off;
171   }
172 }
173 
174 /*!
175  *
176  * \brief Perform inverse filtering level emphasis
177  *
178  * Retrieve bandwidth expansion factor and apply smoothing for each filter band
179  *
180  */
181 
inverseFilteringLevelEmphasis(HANDLE_SBR_LPP_TRANS hLppTrans,UCHAR nInvfBands,INVF_MODE * sbr_invf_mode,INVF_MODE * sbr_invf_mode_prev,FIXP_DBL * bwVector)182 static void inverseFilteringLevelEmphasis(
183     HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer  */
184     UCHAR nInvfBands,              /*!< Number of bands for inverse filtering */
185     INVF_MODE *sbr_invf_mode,      /*!< Current inverse filtering modes */
186     INVF_MODE *sbr_invf_mode_prev, /*!< Previous inverse filtering modes */
187     FIXP_DBL *bwVector             /*!< Resulting filtering levels */
188 ) {
189   for (int i = 0; i < nInvfBands; i++) {
190     FIXP_DBL accu;
191     FIXP_DBL bwTmp = mapInvfMode(sbr_invf_mode[i], sbr_invf_mode_prev[i],
192                                  hLppTrans->pSettings->whFactors);
193 
194     if (bwTmp < hLppTrans->bwVectorOld[i]) {
195       accu = fMultDiv2(FL2FXCONST_DBL(0.75f), bwTmp) +
196              fMultDiv2(FL2FXCONST_DBL(0.25f), hLppTrans->bwVectorOld[i]);
197     } else {
198       accu = fMultDiv2(FL2FXCONST_DBL(0.90625f), bwTmp) +
199              fMultDiv2(FL2FXCONST_DBL(0.09375f), hLppTrans->bwVectorOld[i]);
200     }
201 
202     if (accu<FL2FXCONST_DBL(0.015625f)>> 1) {
203       bwVector[i] = FL2FXCONST_DBL(0.0f);
204     } else {
205       bwVector[i] = fixMin(accu << 1, FL2FXCONST_DBL(0.99609375f));
206     }
207   }
208 }
209 
210 /* Resulting autocorrelation determinant exponent */
211 #define ACDET_EXP \
212   (2 * (DFRACT_BITS + sbrScaleFactor->lb_scale + 10 - ac.det_scale))
213 #define AC_EXP (-sbrScaleFactor->lb_scale + LPC_SCALE_FACTOR)
214 #define ALPHA_EXP (-sbrScaleFactor->lb_scale + LPC_SCALE_FACTOR + 1)
215 /* Resulting transposed QMF values exponent 16 bit normalized samplebits
216  * assumed. */
217 #define QMFOUT_EXP ((SAMPLE_BITS - 15) - sbrScaleFactor->lb_scale)
218 
calc_qmfBufferReal(FIXP_DBL ** qmfBufferReal,const FIXP_DBL * const lowBandReal,const int startSample,const int stopSample,const UCHAR hiBand,const int dynamicScale,const FIXP_SGL a0r,const FIXP_SGL a1r)219 static inline void calc_qmfBufferReal(FIXP_DBL **qmfBufferReal,
220                                       const FIXP_DBL *const lowBandReal,
221                                       const int startSample,
222                                       const int stopSample, const UCHAR hiBand,
223                                       const int dynamicScale,
224                                       const FIXP_SGL a0r, const FIXP_SGL a1r) {
225   const int dynscale = fixMax(0, dynamicScale - 1) + 1;
226   const int rescale = -fixMin(0, dynamicScale - 1) + 1;
227   const int descale =
228       fixMin(DFRACT_BITS - 1, LPC_SCALE_FACTOR + dynamicScale + rescale);
229 
230   for (int i = 0; i < stopSample - startSample; i++) {
231     FIXP_DBL accu;
232 
233     accu = fMultDiv2(a1r, lowBandReal[i]) + fMultDiv2(a0r, lowBandReal[i + 1]);
234     accu = (lowBandReal[i + 2] >> descale) + (accu >> dynscale);
235 
236     qmfBufferReal[i + startSample][hiBand] =
237         SATURATE_LEFT_SHIFT(accu, rescale, DFRACT_BITS);
238   }
239 }
240 
241 /*!
242  *
243  * \brief Perform transposition by patching of subband samples.
244  * This function serves as the main entry point into the module. The function
245  * determines the areas for the patching process (these are the source range as
246  * well as the target range) and implements spectral whitening by means of
247  * inverse filtering. The function autoCorrelation2nd() is an auxiliary function
248  * for calculating the LPC coefficients for the filtering.  The actual
249  * calculation of the LPC coefficients and the implementation of the filtering
250  * are done as part of lppTransposer().
251  *
252  * Note that the filtering is done on all available QMF subsamples, whereas the
253  * patching is only done on those QMF subsamples that will be used in the next
254  * QMF synthesis. The filtering is also implemented before the patching includes
255  * further dependencies on parameters from the SBR data.
256  *
257  */
258 
lppTransposer(HANDLE_SBR_LPP_TRANS hLppTrans,QMF_SCALE_FACTOR * sbrScaleFactor,FIXP_DBL ** qmfBufferReal,FIXP_DBL * degreeAlias,FIXP_DBL ** qmfBufferImag,const int useLP,const int fPreWhitening,const int v_k_master0,const int timeStep,const int firstSlotOffs,const int lastSlotOffs,const int nInvfBands,INVF_MODE * sbr_invf_mode,INVF_MODE * sbr_invf_mode_prev)259 void lppTransposer(
260     HANDLE_SBR_LPP_TRANS hLppTrans,   /*!< Handle of lpp transposer  */
261     QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */
262     FIXP_DBL **qmfBufferReal, /*!< Pointer to pointer to real part of subband
263                                  samples (source) */
264 
265     FIXP_DBL *degreeAlias,    /*!< Vector for results of aliasing estimation */
266     FIXP_DBL **qmfBufferImag, /*!< Pointer to pointer to imaginary part of
267                                  subband samples (source) */
268     const int useLP, const int fPreWhitening, const int v_k_master0,
269     const int timeStep,       /*!< Time step of envelope */
270     const int firstSlotOffs,  /*!< Start position in time */
271     const int lastSlotOffs,   /*!< Number of overlap-slots into next frame */
272     const int nInvfBands,     /*!< Number of bands for inverse filtering */
273     INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */
274     INVF_MODE *sbr_invf_mode_prev /*!< Previous inverse filtering modes */
275 ) {
276   INT bwIndex[MAX_NUM_PATCHES];
277   FIXP_DBL bwVector[MAX_NUM_PATCHES]; /*!< pole moving factors */
278   FIXP_DBL preWhiteningGains[(64) / 2];
279   int preWhiteningGains_exp[(64) / 2];
280 
281   int i;
282   int loBand, start, stop;
283   TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
284   PATCH_PARAM *patchParam = pSettings->patchParam;
285   int patch;
286 
287   FIXP_SGL alphar[LPC_ORDER], a0r, a1r;
288   FIXP_SGL alphai[LPC_ORDER], a0i = 0, a1i = 0;
289   FIXP_SGL bw = FL2FXCONST_SGL(0.0f);
290 
291   int autoCorrLength;
292 
293   FIXP_DBL k1, k1_below = 0, k1_below2 = 0;
294 
295   ACORR_COEFS ac;
296   int startSample;
297   int stopSample;
298   int stopSampleClear;
299 
300   int comLowBandScale;
301   int ovLowBandShift;
302   int lowBandShift;
303   /*  int ovHighBandShift;*/
304 
305   alphai[0] = FL2FXCONST_SGL(0.0f);
306   alphai[1] = FL2FXCONST_SGL(0.0f);
307 
308   startSample = firstSlotOffs * timeStep;
309   stopSample = pSettings->nCols + lastSlotOffs * timeStep;
310   FDK_ASSERT((lastSlotOffs * timeStep) <= pSettings->overlap);
311 
312   inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode,
313                                 sbr_invf_mode_prev, bwVector);
314 
315   stopSampleClear = stopSample;
316 
317   autoCorrLength = pSettings->nCols + pSettings->overlap;
318 
319   if (pSettings->noOfPatches > 0) {
320     /* Set upper subbands to zero:
321        This is required in case that the patches do not cover the complete
322        highband (because the last patch would be too short). Possible
323        optimization: Clearing bands up to usb would be sufficient here. */
324     int targetStopBand =
325         patchParam[pSettings->noOfPatches - 1].targetStartBand +
326         patchParam[pSettings->noOfPatches - 1].numBandsInPatch;
327 
328     int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL);
329 
330     if (!useLP) {
331       for (i = startSample; i < stopSampleClear; i++) {
332         FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
333         FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize);
334       }
335     } else {
336       for (i = startSample; i < stopSampleClear; i++) {
337         FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
338       }
339     }
340   }
341 #if defined __ANDROID__ && !defined __ANDROID_NDK__
342   else {
343     // Safetynet logging
344     android_errorWriteLog(0x534e4554, "112160868");
345   }
346 #endif
347 
348   /* init bwIndex for each patch */
349   FDKmemclear(bwIndex, sizeof(bwIndex));
350 
351   /*
352     Calc common low band scale factor
353   */
354   comLowBandScale =
355       fixMin(sbrScaleFactor->ov_lb_scale, sbrScaleFactor->lb_scale);
356 
357   ovLowBandShift = sbrScaleFactor->ov_lb_scale - comLowBandScale;
358   lowBandShift = sbrScaleFactor->lb_scale - comLowBandScale;
359   /*  ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/
360 
361   if (fPreWhitening) {
362     sbrDecoder_calculateGainVec(
363         qmfBufferReal, qmfBufferImag,
364         DFRACT_BITS - 1 - 16 -
365             sbrScaleFactor->ov_lb_scale, /* convert scale to exponent */
366         DFRACT_BITS - 1 - 16 -
367             sbrScaleFactor->lb_scale, /* convert scale to exponent */
368         pSettings->overlap, preWhiteningGains, preWhiteningGains_exp,
369         v_k_master0, startSample, stopSample);
370   }
371 
372   /* outer loop over bands to do analysis only once for each band */
373 
374   if (!useLP) {
375     start = pSettings->lbStartPatching;
376     stop = pSettings->lbStopPatching;
377   } else {
378     start = fixMax(1, pSettings->lbStartPatching - 2);
379     stop = patchParam[0].targetStartBand;
380   }
381 
382   for (loBand = start; loBand < stop; loBand++) {
383     FIXP_DBL lowBandReal[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
384     FIXP_DBL *plowBandReal = lowBandReal;
385     FIXP_DBL **pqmfBufferReal =
386         qmfBufferReal + firstSlotOffs * timeStep /* + pSettings->overlap */;
387     FIXP_DBL lowBandImag[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
388     FIXP_DBL *plowBandImag = lowBandImag;
389     FIXP_DBL **pqmfBufferImag =
390         qmfBufferImag + firstSlotOffs * timeStep /* + pSettings->overlap */;
391     int resetLPCCoeffs = 0;
392     int dynamicScale = DFRACT_BITS - 1 - LPC_SCALE_FACTOR;
393     int acDetScale = 0; /* scaling of autocorrelation determinant */
394 
395     for (i = 0;
396          i < LPC_ORDER + firstSlotOffs * timeStep /*+pSettings->overlap*/;
397          i++) {
398       *plowBandReal++ = hLppTrans->lpcFilterStatesRealLegSBR[i][loBand];
399       if (!useLP)
400         *plowBandImag++ = hLppTrans->lpcFilterStatesImagLegSBR[i][loBand];
401     }
402 
403     /*
404       Take old slope length qmf slot source values out of (overlap)qmf buffer
405     */
406     if (!useLP) {
407       for (i = 0;
408            i < pSettings->nCols + pSettings->overlap - firstSlotOffs * timeStep;
409            i++) {
410         *plowBandReal++ = (*pqmfBufferReal++)[loBand];
411         *plowBandImag++ = (*pqmfBufferImag++)[loBand];
412       }
413     } else {
414       /* pSettings->overlap is always even */
415       FDK_ASSERT((pSettings->overlap & 1) == 0);
416       for (i = 0; i < ((pSettings->nCols + pSettings->overlap -
417                         firstSlotOffs * timeStep) >>
418                        1);
419            i++) {
420         *plowBandReal++ = (*pqmfBufferReal++)[loBand];
421         *plowBandReal++ = (*pqmfBufferReal++)[loBand];
422       }
423       if (pSettings->nCols & 1) {
424         *plowBandReal++ = (*pqmfBufferReal++)[loBand];
425       }
426     }
427 
428     /*
429       Determine dynamic scaling value.
430      */
431     dynamicScale =
432         fixMin(dynamicScale,
433                getScalefactor(lowBandReal, LPC_ORDER + pSettings->overlap) +
434                    ovLowBandShift);
435     dynamicScale =
436         fixMin(dynamicScale,
437                getScalefactor(&lowBandReal[LPC_ORDER + pSettings->overlap],
438                               pSettings->nCols) +
439                    lowBandShift);
440     if (!useLP) {
441       dynamicScale =
442           fixMin(dynamicScale,
443                  getScalefactor(lowBandImag, LPC_ORDER + pSettings->overlap) +
444                      ovLowBandShift);
445       dynamicScale =
446           fixMin(dynamicScale,
447                  getScalefactor(&lowBandImag[LPC_ORDER + pSettings->overlap],
448                                 pSettings->nCols) +
449                      lowBandShift);
450     }
451 
452     if (dynamicScale == 0) {
453       /* In this special case the available headroom bits as well as
454          ovLowBandShift and lowBandShift are zero. The spectrum is limited to
455          prevent -1.0, so negative values for dynamicScale can be avoided. */
456       for (i = 0; i < (LPC_ORDER + pSettings->overlap + pSettings->nCols);
457            i++) {
458         lowBandReal[i] = fixMax(lowBandReal[i], (FIXP_DBL)0x80000001);
459       }
460       if (!useLP) {
461         for (i = 0; i < (LPC_ORDER + pSettings->overlap + pSettings->nCols);
462              i++) {
463           lowBandImag[i] = fixMax(lowBandImag[i], (FIXP_DBL)0x80000001);
464         }
465       }
466     } else {
467       dynamicScale =
468           fixMax(0, dynamicScale -
469                         1); /* one additional bit headroom to prevent -1.0 */
470     }
471 
472     /*
473       Scale temporal QMF buffer.
474      */
475     scaleValues(&lowBandReal[0], LPC_ORDER + pSettings->overlap,
476                 dynamicScale - ovLowBandShift);
477     scaleValues(&lowBandReal[LPC_ORDER + pSettings->overlap], pSettings->nCols,
478                 dynamicScale - lowBandShift);
479 
480     if (!useLP) {
481       scaleValues(&lowBandImag[0], LPC_ORDER + pSettings->overlap,
482                   dynamicScale - ovLowBandShift);
483       scaleValues(&lowBandImag[LPC_ORDER + pSettings->overlap],
484                   pSettings->nCols, dynamicScale - lowBandShift);
485     }
486 
487     if (!useLP) {
488       acDetScale += autoCorr2nd_cplx(&ac, lowBandReal + LPC_ORDER,
489                                      lowBandImag + LPC_ORDER, autoCorrLength);
490     } else {
491       acDetScale +=
492           autoCorr2nd_real(&ac, lowBandReal + LPC_ORDER, autoCorrLength);
493     }
494 
495     /* Examine dynamic of determinant in autocorrelation. */
496     acDetScale += 2 * (comLowBandScale + dynamicScale);
497     acDetScale *= 2;            /* two times reflection coefficent scaling */
498     acDetScale += ac.det_scale; /* ac scaling of determinant */
499 
500     /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */
501     if (acDetScale > 126) {
502       resetLPCCoeffs = 1;
503     }
504 
505     alphar[1] = FL2FXCONST_SGL(0.0f);
506     if (!useLP) alphai[1] = FL2FXCONST_SGL(0.0f);
507 
508     if (ac.det != FL2FXCONST_DBL(0.0f)) {
509       FIXP_DBL tmp, absTmp, absDet;
510 
511       absDet = fixp_abs(ac.det);
512 
513       if (!useLP) {
514         tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) -
515               ((fMultDiv2(ac.r01i, ac.r12i) + fMultDiv2(ac.r02r, ac.r11r)) >>
516                (LPC_SCALE_FACTOR - 1));
517       } else {
518         tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) -
519               (fMultDiv2(ac.r02r, ac.r11r) >> (LPC_SCALE_FACTOR - 1));
520       }
521       absTmp = fixp_abs(tmp);
522 
523       /*
524         Quick check: is first filter coeff >= 1(4)
525        */
526       {
527         INT scale;
528         FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
529         scale = scale + ac.det_scale;
530 
531         if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) {
532           resetLPCCoeffs = 1;
533         } else {
534           alphar[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
535           if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
536             alphar[1] = -alphar[1];
537           }
538         }
539       }
540 
541       if (!useLP) {
542         tmp = (fMultDiv2(ac.r01i, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) +
543               ((fMultDiv2(ac.r01r, ac.r12i) -
544                 (FIXP_DBL)fMultDiv2(ac.r02i, ac.r11r)) >>
545                (LPC_SCALE_FACTOR - 1));
546 
547         absTmp = fixp_abs(tmp);
548 
549         /*
550         Quick check: is second filter coeff >= 1(4)
551         */
552         {
553           INT scale;
554           FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
555           scale = scale + ac.det_scale;
556 
557           if ((scale > 0) &&
558               (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >>
559                scale)) {
560             resetLPCCoeffs = 1;
561           } else {
562             alphai[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
563             if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
564               alphai[1] = -alphai[1];
565             }
566           }
567         }
568       }
569     }
570 
571     alphar[0] = FL2FXCONST_SGL(0.0f);
572     if (!useLP) alphai[0] = FL2FXCONST_SGL(0.0f);
573 
574     if (ac.r11r != FL2FXCONST_DBL(0.0f)) {
575       /* ac.r11r is always >=0 */
576       FIXP_DBL tmp, absTmp;
577 
578       if (!useLP) {
579         tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) +
580               (fMultDiv2(alphar[1], ac.r12r) + fMultDiv2(alphai[1], ac.r12i));
581       } else {
582         if (ac.r01r >= FL2FXCONST_DBL(0.0f))
583           tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) +
584                 fMultDiv2(alphar[1], ac.r12r);
585         else
586           tmp = -((-ac.r01r) >> (LPC_SCALE_FACTOR + 1)) +
587                 fMultDiv2(alphar[1], ac.r12r);
588       }
589 
590       absTmp = fixp_abs(tmp);
591 
592       /*
593         Quick check: is first filter coeff >= 1(4)
594       */
595 
596       if (absTmp >= (ac.r11r >> 1)) {
597         resetLPCCoeffs = 1;
598       } else {
599         INT scale;
600         FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
601         alphar[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
602 
603         if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
604           alphar[0] = -alphar[0];
605       }
606 
607       if (!useLP) {
608         tmp = (ac.r01i >> (LPC_SCALE_FACTOR + 1)) +
609               (fMultDiv2(alphai[1], ac.r12r) - fMultDiv2(alphar[1], ac.r12i));
610 
611         absTmp = fixp_abs(tmp);
612 
613         /*
614         Quick check: is second filter coeff >= 1(4)
615         */
616         if (absTmp >= (ac.r11r >> 1)) {
617           resetLPCCoeffs = 1;
618         } else {
619           INT scale;
620           FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
621           alphai[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
622           if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
623             alphai[0] = -alphai[0];
624         }
625       }
626     }
627 
628     if (!useLP) {
629       /* Now check the quadratic criteria */
630       if ((fMultDiv2(alphar[0], alphar[0]) + fMultDiv2(alphai[0], alphai[0])) >=
631           FL2FXCONST_DBL(0.5f))
632         resetLPCCoeffs = 1;
633       if ((fMultDiv2(alphar[1], alphar[1]) + fMultDiv2(alphai[1], alphai[1])) >=
634           FL2FXCONST_DBL(0.5f))
635         resetLPCCoeffs = 1;
636     }
637 
638     if (resetLPCCoeffs) {
639       alphar[0] = FL2FXCONST_SGL(0.0f);
640       alphar[1] = FL2FXCONST_SGL(0.0f);
641       if (!useLP) {
642         alphai[0] = FL2FXCONST_SGL(0.0f);
643         alphai[1] = FL2FXCONST_SGL(0.0f);
644       }
645     }
646 
647     if (useLP) {
648       /* Aliasing detection */
649       if (ac.r11r == FL2FXCONST_DBL(0.0f)) {
650         k1 = FL2FXCONST_DBL(0.0f);
651       } else {
652         if (fixp_abs(ac.r01r) >= fixp_abs(ac.r11r)) {
653           if (fMultDiv2(ac.r01r, ac.r11r) < FL2FX_DBL(0.0f)) {
654             k1 = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_SGL(1.0f)*/;
655           } else {
656             /* Since this value is squared later, it must not ever become -1.0f.
657              */
658             k1 = (FIXP_DBL)(MINVAL_DBL + 1) /*FL2FXCONST_SGL(-1.0f)*/;
659           }
660         } else {
661           INT scale;
662           FIXP_DBL result =
663               fDivNorm(fixp_abs(ac.r01r), fixp_abs(ac.r11r), &scale);
664           k1 = scaleValueSaturate(result, scale);
665 
666           if (!((ac.r01r < FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))) {
667             k1 = -k1;
668           }
669         }
670       }
671       if ((loBand > 1) && (loBand < v_k_master0)) {
672         /* Check if the gain should be locked */
673         FIXP_DBL deg =
674             /*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - fPow2(k1_below);
675         degreeAlias[loBand] = FL2FXCONST_DBL(0.0f);
676         if (((loBand & 1) == 0) && (k1 < FL2FXCONST_DBL(0.0f))) {
677           if (k1_below < FL2FXCONST_DBL(0.0f)) { /* 2-Ch Aliasing Detection */
678             degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/;
679             if (k1_below2 >
680                 FL2FXCONST_DBL(0.0f)) { /* 3-Ch Aliasing Detection */
681               degreeAlias[loBand - 1] = deg;
682             }
683           } else if (k1_below2 >
684                      FL2FXCONST_DBL(0.0f)) { /* 3-Ch Aliasing Detection */
685             degreeAlias[loBand] = deg;
686           }
687         }
688         if (((loBand & 1) == 1) && (k1 > FL2FXCONST_DBL(0.0f))) {
689           if (k1_below > FL2FXCONST_DBL(0.0f)) { /* 2-CH Aliasing Detection */
690             degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/;
691             if (k1_below2 <
692                 FL2FXCONST_DBL(0.0f)) { /* 3-CH Aliasing Detection */
693               degreeAlias[loBand - 1] = deg;
694             }
695           } else if (k1_below2 <
696                      FL2FXCONST_DBL(0.0f)) { /* 3-CH Aliasing Detection */
697             degreeAlias[loBand] = deg;
698           }
699         }
700       }
701       /* remember k1 values of the 2 QMF channels below the current channel */
702       k1_below2 = k1_below;
703       k1_below = k1;
704     }
705 
706     patch = 0;
707 
708     while (patch < pSettings->noOfPatches) { /* inner loop over every patch */
709 
710       int hiBand = loBand + patchParam[patch].targetBandOffs;
711 
712       if (loBand < patchParam[patch].sourceStartBand ||
713           loBand >= patchParam[patch].sourceStopBand
714           //|| hiBand >= hLppTrans->pSettings->noChannels
715       ) {
716         /* Lowband not in current patch - proceed */
717         patch++;
718         continue;
719       }
720 
721       FDK_ASSERT(hiBand < (64));
722 
723       /* bwIndex[patch] is already initialized with value from previous band
724        * inside this patch */
725       while (hiBand >= pSettings->bwBorders[bwIndex[patch]] &&
726              bwIndex[patch] < MAX_NUM_PATCHES - 1) {
727         bwIndex[patch]++;
728       }
729 
730       /*
731         Filter Step 2: add the left slope with the current filter to the buffer
732                        pure source values are already in there
733       */
734       bw = FX_DBL2FX_SGL(bwVector[bwIndex[patch]]);
735 
736       a0r = FX_DBL2FX_SGL(
737           fMult(bw, alphar[0])); /* Apply current bandwidth expansion factor */
738 
739       if (!useLP) a0i = FX_DBL2FX_SGL(fMult(bw, alphai[0]));
740       bw = FX_DBL2FX_SGL(fPow2(bw));
741       a1r = FX_DBL2FX_SGL(fMult(bw, alphar[1]));
742       if (!useLP) a1i = FX_DBL2FX_SGL(fMult(bw, alphai[1]));
743 
744       /*
745         Filter Step 3: insert the middle part which won't be windowed
746       */
747       if (bw <= FL2FXCONST_SGL(0.0f)) {
748         if (!useLP) {
749           int descale =
750               fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
751           for (i = startSample; i < stopSample; i++) {
752             FIXP_DBL accu1, accu2;
753             accu1 = lowBandReal[LPC_ORDER + i] >> descale;
754             accu2 = lowBandImag[LPC_ORDER + i] >> descale;
755             if (fPreWhitening) {
756               accu1 = scaleValueSaturate(
757                   fMultDiv2(accu1, preWhiteningGains[loBand]),
758                   preWhiteningGains_exp[loBand] + 1);
759               accu2 = scaleValueSaturate(
760                   fMultDiv2(accu2, preWhiteningGains[loBand]),
761                   preWhiteningGains_exp[loBand] + 1);
762             }
763             qmfBufferReal[i][hiBand] = accu1;
764             qmfBufferImag[i][hiBand] = accu2;
765           }
766         } else {
767           int descale =
768               fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
769           for (i = startSample; i < stopSample; i++) {
770             qmfBufferReal[i][hiBand] = lowBandReal[LPC_ORDER + i] >> descale;
771           }
772         }
773       } else { /* bw <= 0 */
774 
775         if (!useLP) {
776           const int dynscale = fixMax(0, dynamicScale - 2) + 1;
777           const int rescale = -fixMin(0, dynamicScale - 2) + 1;
778           const int descale = fixMin(DFRACT_BITS - 1,
779                                      LPC_SCALE_FACTOR + dynamicScale + rescale);
780 
781           for (i = startSample; i < stopSample; i++) {
782             FIXP_DBL accu1, accu2;
783 
784             accu1 = ((fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) -
785                       fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1])) >>
786                      1) +
787                     ((fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) -
788                       fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >>
789                      1);
790             accu2 = ((fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) +
791                       fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1])) >>
792                      1) +
793                     ((fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) +
794                       fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >>
795                      1);
796 
797             accu1 =
798                 (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 >> dynscale);
799             accu2 =
800                 (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 >> dynscale);
801             if (fPreWhitening) {
802               qmfBufferReal[i][hiBand] = scaleValueSaturate(
803                   fMultDiv2(accu1, preWhiteningGains[loBand]),
804                   preWhiteningGains_exp[loBand] + 1 + rescale);
805               qmfBufferImag[i][hiBand] = scaleValueSaturate(
806                   fMultDiv2(accu2, preWhiteningGains[loBand]),
807                   preWhiteningGains_exp[loBand] + 1 + rescale);
808             } else {
809               qmfBufferReal[i][hiBand] =
810                   SATURATE_LEFT_SHIFT(accu1, rescale, DFRACT_BITS);
811               qmfBufferImag[i][hiBand] =
812                   SATURATE_LEFT_SHIFT(accu2, rescale, DFRACT_BITS);
813             }
814           }
815         } else {
816           FDK_ASSERT(dynamicScale >= 0);
817           calc_qmfBufferReal(
818               qmfBufferReal, &(lowBandReal[LPC_ORDER + startSample - 2]),
819               startSample, stopSample, hiBand, dynamicScale, a0r, a1r);
820         }
821       } /* bw <= 0 */
822 
823       patch++;
824 
825     } /* inner loop over patches */
826 
827     /*
828      * store the unmodified filter coefficients if there is
829      * an overlapping envelope
830      *****************************************************************/
831 
832   } /* outer loop over bands (loBand) */
833 
834   if (useLP) {
835     for (loBand = pSettings->lbStartPatching;
836          loBand < pSettings->lbStopPatching; loBand++) {
837       patch = 0;
838       while (patch < pSettings->noOfPatches) {
839         UCHAR hiBand = loBand + patchParam[patch].targetBandOffs;
840 
841         if (loBand < patchParam[patch].sourceStartBand ||
842             loBand >= patchParam[patch].sourceStopBand ||
843             hiBand >= (64) /* Highband out of range (biterror) */
844         ) {
845           /* Lowband not in current patch or highband out of range (might be
846            * caused by biterrors)- proceed */
847           patch++;
848           continue;
849         }
850 
851         if (hiBand != patchParam[patch].targetStartBand)
852           degreeAlias[hiBand] = degreeAlias[loBand];
853 
854         patch++;
855       }
856     } /* end  for loop */
857   }
858 
859   for (i = 0; i < nInvfBands; i++) {
860     hLppTrans->bwVectorOld[i] = bwVector[i];
861   }
862 
863   /*
864     set high band scale factor
865   */
866   sbrScaleFactor->hb_scale = comLowBandScale - (LPC_SCALE_FACTOR);
867 }
868 
lppTransposerHBE(HANDLE_SBR_LPP_TRANS hLppTrans,HANDLE_HBE_TRANSPOSER hQmfTransposer,QMF_SCALE_FACTOR * sbrScaleFactor,FIXP_DBL ** qmfBufferReal,FIXP_DBL ** qmfBufferImag,const int timeStep,const int firstSlotOffs,const int lastSlotOffs,const int nInvfBands,INVF_MODE * sbr_invf_mode,INVF_MODE * sbr_invf_mode_prev)869 void lppTransposerHBE(
870     HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer  */
871     HANDLE_HBE_TRANSPOSER hQmfTransposer,
872     QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */
873     FIXP_DBL **qmfBufferReal, /*!< Pointer to pointer to real part of subband
874                                  samples (source) */
875     FIXP_DBL **qmfBufferImag, /*!< Pointer to pointer to imaginary part of
876                                  subband samples (source) */
877     const int timeStep,       /*!< Time step of envelope */
878     const int firstSlotOffs,  /*!< Start position in time */
879     const int lastSlotOffs,   /*!< Number of overlap-slots into next frame */
880     const int nInvfBands,     /*!< Number of bands for inverse filtering */
881     INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */
882     INVF_MODE *sbr_invf_mode_prev /*!< Previous inverse filtering modes */
883 ) {
884   INT bwIndex;
885   FIXP_DBL bwVector[MAX_NUM_PATCHES_HBE]; /*!< pole moving factors */
886 
887   int i;
888   int loBand, start, stop;
889   TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
890   PATCH_PARAM *patchParam = pSettings->patchParam;
891 
892   FIXP_SGL alphar[LPC_ORDER], a0r, a1r;
893   FIXP_SGL alphai[LPC_ORDER], a0i = 0, a1i = 0;
894   FIXP_SGL bw = FL2FXCONST_SGL(0.0f);
895 
896   int autoCorrLength;
897 
898   ACORR_COEFS ac;
899   int startSample;
900   int stopSample;
901   int stopSampleClear;
902 
903   int comBandScale;
904   int ovLowBandShift;
905   int lowBandShift;
906   /*  int ovHighBandShift;*/
907 
908   alphai[0] = FL2FXCONST_SGL(0.0f);
909   alphai[1] = FL2FXCONST_SGL(0.0f);
910 
911   startSample = firstSlotOffs * timeStep;
912   stopSample = pSettings->nCols + lastSlotOffs * timeStep;
913 
914   inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode,
915                                 sbr_invf_mode_prev, bwVector);
916 
917   stopSampleClear = stopSample;
918 
919   autoCorrLength = pSettings->nCols + pSettings->overlap;
920 
921   if (pSettings->noOfPatches > 0) {
922     /* Set upper subbands to zero:
923        This is required in case that the patches do not cover the complete
924        highband (because the last patch would be too short). Possible
925        optimization: Clearing bands up to usb would be sufficient here. */
926     int targetStopBand =
927         patchParam[pSettings->noOfPatches - 1].targetStartBand +
928         patchParam[pSettings->noOfPatches - 1].numBandsInPatch;
929 
930     int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL);
931 
932     for (i = startSample; i < stopSampleClear; i++) {
933       FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
934       FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize);
935     }
936   }
937 #if defined __ANDROID__ && !defined __ANDROID_NDK__
938   else {
939     // Safetynet logging
940     android_errorWriteLog(0x534e4554, "112160868");
941   }
942 #endif
943 
944   /*
945   Calc common low band scale factor
946   */
947   comBandScale = sbrScaleFactor->hb_scale;
948 
949   ovLowBandShift = sbrScaleFactor->hb_scale - comBandScale;
950   lowBandShift = sbrScaleFactor->hb_scale - comBandScale;
951   /*  ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/
952 
953   /* outer loop over bands to do analysis only once for each band */
954 
955   start = hQmfTransposer->startBand;
956   stop = hQmfTransposer->stopBand;
957 
958   for (loBand = start; loBand < stop; loBand++) {
959     bwIndex = 0;
960 
961     FIXP_DBL lowBandReal[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
962     FIXP_DBL lowBandImag[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
963 
964     int resetLPCCoeffs = 0;
965     int dynamicScale = DFRACT_BITS - 1 - LPC_SCALE_FACTOR;
966     int acDetScale = 0; /* scaling of autocorrelation determinant */
967 
968     for (i = 0; i < LPC_ORDER; i++) {
969       lowBandReal[i] = hLppTrans->lpcFilterStatesRealHBE[i][loBand];
970       lowBandImag[i] = hLppTrans->lpcFilterStatesImagHBE[i][loBand];
971     }
972 
973     for (; i < LPC_ORDER + firstSlotOffs * timeStep; i++) {
974       lowBandReal[i] = hLppTrans->lpcFilterStatesRealHBE[i][loBand];
975       lowBandImag[i] = hLppTrans->lpcFilterStatesImagHBE[i][loBand];
976     }
977 
978     /*
979     Take old slope length qmf slot source values out of (overlap)qmf buffer
980     */
981     for (i = firstSlotOffs * timeStep;
982          i < pSettings->nCols + pSettings->overlap; i++) {
983       lowBandReal[i + LPC_ORDER] = qmfBufferReal[i][loBand];
984       lowBandImag[i + LPC_ORDER] = qmfBufferImag[i][loBand];
985     }
986 
987     /* store unmodified values to buffer */
988     for (i = 0; i < LPC_ORDER + pSettings->overlap; i++) {
989       hLppTrans->lpcFilterStatesRealHBE[i][loBand] =
990           qmfBufferReal[pSettings->nCols - LPC_ORDER + i][loBand];
991       hLppTrans->lpcFilterStatesImagHBE[i][loBand] =
992           qmfBufferImag[pSettings->nCols - LPC_ORDER + i][loBand];
993     }
994 
995     /*
996     Determine dynamic scaling value.
997     */
998     dynamicScale =
999         fixMin(dynamicScale,
1000                getScalefactor(lowBandReal, LPC_ORDER + pSettings->overlap) +
1001                    ovLowBandShift);
1002     dynamicScale =
1003         fixMin(dynamicScale,
1004                getScalefactor(&lowBandReal[LPC_ORDER + pSettings->overlap],
1005                               pSettings->nCols) +
1006                    lowBandShift);
1007     dynamicScale =
1008         fixMin(dynamicScale,
1009                getScalefactor(lowBandImag, LPC_ORDER + pSettings->overlap) +
1010                    ovLowBandShift);
1011     dynamicScale =
1012         fixMin(dynamicScale,
1013                getScalefactor(&lowBandImag[LPC_ORDER + pSettings->overlap],
1014                               pSettings->nCols) +
1015                    lowBandShift);
1016 
1017     dynamicScale =
1018         dynamicScale - 1; /* one additional bit headroom to prevent -1.0 */
1019 
1020     /*
1021     Scale temporal QMF buffer.
1022     */
1023     scaleValues(&lowBandReal[0], LPC_ORDER + pSettings->overlap,
1024                 dynamicScale - ovLowBandShift);
1025     scaleValues(&lowBandReal[LPC_ORDER + pSettings->overlap], pSettings->nCols,
1026                 dynamicScale - lowBandShift);
1027     scaleValues(&lowBandImag[0], LPC_ORDER + pSettings->overlap,
1028                 dynamicScale - ovLowBandShift);
1029     scaleValues(&lowBandImag[LPC_ORDER + pSettings->overlap], pSettings->nCols,
1030                 dynamicScale - lowBandShift);
1031 
1032     acDetScale += autoCorr2nd_cplx(&ac, lowBandReal + LPC_ORDER,
1033                                    lowBandImag + LPC_ORDER, autoCorrLength);
1034 
1035     /* Examine dynamic of determinant in autocorrelation. */
1036     acDetScale += 2 * (comBandScale + dynamicScale);
1037     acDetScale *= 2;            /* two times reflection coefficent scaling */
1038     acDetScale += ac.det_scale; /* ac scaling of determinant */
1039 
1040     /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */
1041     if (acDetScale > 126) {
1042       resetLPCCoeffs = 1;
1043     }
1044 
1045     alphar[1] = FL2FXCONST_SGL(0.0f);
1046     alphai[1] = FL2FXCONST_SGL(0.0f);
1047 
1048     if (ac.det != FL2FXCONST_DBL(0.0f)) {
1049       FIXP_DBL tmp, absTmp, absDet;
1050 
1051       absDet = fixp_abs(ac.det);
1052 
1053       tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) -
1054             ((fMultDiv2(ac.r01i, ac.r12i) + fMultDiv2(ac.r02r, ac.r11r)) >>
1055              (LPC_SCALE_FACTOR - 1));
1056       absTmp = fixp_abs(tmp);
1057 
1058       /*
1059       Quick check: is first filter coeff >= 1(4)
1060       */
1061       {
1062         INT scale;
1063         FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
1064         scale = scale + ac.det_scale;
1065 
1066         if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) {
1067           resetLPCCoeffs = 1;
1068         } else {
1069           alphar[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
1070           if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
1071             alphar[1] = -alphar[1];
1072           }
1073         }
1074       }
1075 
1076       tmp = (fMultDiv2(ac.r01i, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) +
1077             ((fMultDiv2(ac.r01r, ac.r12i) -
1078               (FIXP_DBL)fMultDiv2(ac.r02i, ac.r11r)) >>
1079              (LPC_SCALE_FACTOR - 1));
1080 
1081       absTmp = fixp_abs(tmp);
1082 
1083       /*
1084       Quick check: is second filter coeff >= 1(4)
1085       */
1086       {
1087         INT scale;
1088         FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
1089         scale = scale + ac.det_scale;
1090 
1091         if ((scale > 0) &&
1092             (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >> scale)) {
1093           resetLPCCoeffs = 1;
1094         } else {
1095           alphai[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
1096           if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
1097             alphai[1] = -alphai[1];
1098           }
1099         }
1100       }
1101     }
1102 
1103     alphar[0] = FL2FXCONST_SGL(0.0f);
1104     alphai[0] = FL2FXCONST_SGL(0.0f);
1105 
1106     if (ac.r11r != FL2FXCONST_DBL(0.0f)) {
1107       /* ac.r11r is always >=0 */
1108       FIXP_DBL tmp, absTmp;
1109 
1110       tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) +
1111             (fMultDiv2(alphar[1], ac.r12r) + fMultDiv2(alphai[1], ac.r12i));
1112 
1113       absTmp = fixp_abs(tmp);
1114 
1115       /*
1116       Quick check: is first filter coeff >= 1(4)
1117       */
1118 
1119       if (absTmp >= (ac.r11r >> 1)) {
1120         resetLPCCoeffs = 1;
1121       } else {
1122         INT scale;
1123         FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
1124         alphar[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
1125 
1126         if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
1127           alphar[0] = -alphar[0];
1128       }
1129 
1130       tmp = (ac.r01i >> (LPC_SCALE_FACTOR + 1)) +
1131             (fMultDiv2(alphai[1], ac.r12r) - fMultDiv2(alphar[1], ac.r12i));
1132 
1133       absTmp = fixp_abs(tmp);
1134 
1135       /*
1136       Quick check: is second filter coeff >= 1(4)
1137       */
1138       if (absTmp >= (ac.r11r >> 1)) {
1139         resetLPCCoeffs = 1;
1140       } else {
1141         INT scale;
1142         FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
1143         alphai[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
1144         if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) {
1145           alphai[0] = -alphai[0];
1146         }
1147       }
1148     }
1149 
1150     /* Now check the quadratic criteria */
1151     if ((fMultDiv2(alphar[0], alphar[0]) + fMultDiv2(alphai[0], alphai[0])) >=
1152         FL2FXCONST_DBL(0.5f)) {
1153       resetLPCCoeffs = 1;
1154     }
1155     if ((fMultDiv2(alphar[1], alphar[1]) + fMultDiv2(alphai[1], alphai[1])) >=
1156         FL2FXCONST_DBL(0.5f)) {
1157       resetLPCCoeffs = 1;
1158     }
1159 
1160     if (resetLPCCoeffs) {
1161       alphar[0] = FL2FXCONST_SGL(0.0f);
1162       alphar[1] = FL2FXCONST_SGL(0.0f);
1163       alphai[0] = FL2FXCONST_SGL(0.0f);
1164       alphai[1] = FL2FXCONST_SGL(0.0f);
1165     }
1166 
1167     while (bwIndex < MAX_NUM_PATCHES - 1 &&
1168            loBand >= pSettings->bwBorders[bwIndex]) {
1169       bwIndex++;
1170     }
1171 
1172     /*
1173     Filter Step 2: add the left slope with the current filter to the buffer
1174     pure source values are already in there
1175     */
1176     bw = FX_DBL2FX_SGL(bwVector[bwIndex]);
1177 
1178     a0r = FX_DBL2FX_SGL(
1179         fMult(bw, alphar[0])); /* Apply current bandwidth expansion factor */
1180     a0i = FX_DBL2FX_SGL(fMult(bw, alphai[0]));
1181     bw = FX_DBL2FX_SGL(fPow2(bw));
1182     a1r = FX_DBL2FX_SGL(fMult(bw, alphar[1]));
1183     a1i = FX_DBL2FX_SGL(fMult(bw, alphai[1]));
1184 
1185     /*
1186     Filter Step 3: insert the middle part which won't be windowed
1187     */
1188     if (bw <= FL2FXCONST_SGL(0.0f)) {
1189       int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
1190       for (i = startSample; i < stopSample; i++) {
1191         qmfBufferReal[i][loBand] = lowBandReal[LPC_ORDER + i] >> descale;
1192         qmfBufferImag[i][loBand] = lowBandImag[LPC_ORDER + i] >> descale;
1193       }
1194     } else { /* bw <= 0 */
1195 
1196       int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
1197       dynamicScale +=
1198           1; /* prevent negativ scale factor due to 'one additional bit
1199                 headroom' */
1200 
1201       for (i = startSample; i < stopSample; i++) {
1202         FIXP_DBL accu1, accu2;
1203 
1204         accu1 = (fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) -
1205                  fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1]) +
1206                  fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) -
1207                  fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >>
1208                 dynamicScale;
1209         accu2 = (fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) +
1210                  fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1]) +
1211                  fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) +
1212                  fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >>
1213                 dynamicScale;
1214 
1215         qmfBufferReal[i][loBand] =
1216             (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << (1 + 1));
1217         qmfBufferImag[i][loBand] =
1218             (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << (1 + 1));
1219       }
1220     } /* bw <= 0 */
1221 
1222     /*
1223      * store the unmodified filter coefficients if there is
1224      * an overlapping envelope
1225      *****************************************************************/
1226 
1227   } /* outer loop over bands (loBand) */
1228 
1229   for (i = 0; i < nInvfBands; i++) {
1230     hLppTrans->bwVectorOld[i] = bwVector[i];
1231   }
1232 
1233   /*
1234   set high band scale factor
1235   */
1236   sbrScaleFactor->hb_scale = comBandScale - (LPC_SCALE_FACTOR);
1237 }
1238 
1239 /*!
1240  *
1241  * \brief Initialize one low power transposer instance
1242  *
1243  *
1244  */
1245 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)1246 createLppTransposer(
1247     HANDLE_SBR_LPP_TRANS hs,        /*!< Handle of low power transposer  */
1248     TRANSPOSER_SETTINGS *pSettings, /*!< Pointer to settings */
1249     const int highBandStartSb,      /*!< ? */
1250     UCHAR *v_k_master,              /*!< Master table */
1251     const int numMaster,            /*!< Valid entries in master table */
1252     const int usb,                  /*!< Highband area stop subband */
1253     const int timeSlots,            /*!< Number of time slots */
1254     const int nCols,                /*!< Number of colums (codec qmf bank) */
1255     UCHAR *noiseBandTable,  /*!< Mapping of SBR noise bands to QMF bands */
1256     const int noNoiseBands, /*!< Number of noise bands */
1257     UINT fs,                /*!< Sample Frequency */
1258     const int chan,         /*!< Channel number */
1259     const int overlap) {
1260   /* FB inverse filtering settings */
1261   hs->pSettings = pSettings;
1262 
1263   pSettings->nCols = nCols;
1264   pSettings->overlap = overlap;
1265 
1266   switch (timeSlots) {
1267     case 15:
1268     case 16:
1269       break;
1270 
1271     default:
1272       return SBRDEC_UNSUPPORTED_CONFIG; /* Unimplemented */
1273   }
1274 
1275   if (chan == 0) {
1276     /* Init common data only once */
1277     hs->pSettings->nCols = nCols;
1278 
1279     return resetLppTransposer(hs, highBandStartSb, v_k_master, numMaster,
1280                               noiseBandTable, noNoiseBands, usb, fs);
1281   }
1282   return SBRDEC_OK;
1283 }
1284 
findClosestEntry(UCHAR goalSb,UCHAR * v_k_master,UCHAR numMaster,UCHAR direction)1285 static int findClosestEntry(UCHAR goalSb, UCHAR *v_k_master, UCHAR numMaster,
1286                             UCHAR direction) {
1287   int index;
1288 
1289   if (goalSb <= v_k_master[0]) return v_k_master[0];
1290 
1291   if (goalSb >= v_k_master[numMaster]) return v_k_master[numMaster];
1292 
1293   if (direction) {
1294     index = 0;
1295     while (v_k_master[index] < goalSb) {
1296       index++;
1297     }
1298   } else {
1299     index = numMaster;
1300     while (v_k_master[index] > goalSb) {
1301       index--;
1302     }
1303   }
1304 
1305   return v_k_master[index];
1306 }
1307 
1308 /*!
1309  *
1310  * \brief Reset memory for one lpp transposer instance
1311  *
1312  * \return SBRDEC_OK on success, SBRDEC_UNSUPPORTED_CONFIG on error
1313  */
1314 SBR_ERROR
resetLppTransposer(HANDLE_SBR_LPP_TRANS hLppTrans,UCHAR highBandStartSb,UCHAR * v_k_master,UCHAR numMaster,UCHAR * noiseBandTable,UCHAR noNoiseBands,UCHAR usb,UINT fs)1315 resetLppTransposer(
1316     HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer  */
1317     UCHAR highBandStartSb,          /*!< High band area: start subband */
1318     UCHAR *v_k_master,              /*!< Master table */
1319     UCHAR numMaster,                /*!< Valid entries in master table */
1320     UCHAR *noiseBandTable, /*!< Mapping of SBR noise bands to QMF bands */
1321     UCHAR noNoiseBands,    /*!< Number of noise bands */
1322     UCHAR usb,             /*!< High band area: stop subband */
1323     UINT fs                /*!< SBR output sampling frequency */
1324 ) {
1325   TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
1326   PATCH_PARAM *patchParam = pSettings->patchParam;
1327 
1328   int i, patch;
1329   int targetStopBand;
1330   int sourceStartBand;
1331   int patchDistance;
1332   int numBandsInPatch;
1333 
1334   int lsb = v_k_master[0]; /* Start subband expressed in "non-critical" sampling
1335                               terms*/
1336   int xoverOffset = highBandStartSb -
1337                     lsb; /* Calculate distance in QMF bands between k0 and kx */
1338   int startFreqHz;
1339 
1340   int desiredBorder;
1341 
1342   usb = fixMin(usb, v_k_master[numMaster]); /* Avoid endless loops (compare with
1343                                                float code). */
1344 
1345   /*
1346    * Plausibility check
1347    */
1348 
1349   if (pSettings->nCols == 64) {
1350     if (lsb < 4) {
1351       /* 4:1 SBR Requirement k0 >= 4 missed! */
1352       return SBRDEC_UNSUPPORTED_CONFIG;
1353     }
1354   } else if (lsb - SHIFT_START_SB < 4) {
1355     return SBRDEC_UNSUPPORTED_CONFIG;
1356   }
1357 
1358   /*
1359    * Initialize the patching parameter
1360    */
1361   /* ISO/IEC 14496-3 (Figure 4.48): goalSb = round( 2.048e6 / fs ) */
1362   desiredBorder = (((2048000 * 2) / fs) + 1) >> 1;
1363 
1364   desiredBorder = findClosestEntry(desiredBorder, v_k_master, numMaster,
1365                                    1); /* Adapt region to master-table */
1366 
1367   /* First patch */
1368   sourceStartBand = SHIFT_START_SB + xoverOffset;
1369   targetStopBand = lsb + xoverOffset; /* upperBand */
1370 
1371   /* Even (odd) numbered channel must be patched to even (odd) numbered channel
1372    */
1373   patch = 0;
1374   while (targetStopBand < usb) {
1375     /* Too many patches?
1376        Allow MAX_NUM_PATCHES+1 patches here.
1377        we need to check later again, since patch might be the highest patch
1378        AND contain less than 3 bands => actual number of patches will be reduced
1379        by 1.
1380     */
1381     if (patch > MAX_NUM_PATCHES) {
1382       return SBRDEC_UNSUPPORTED_CONFIG;
1383     }
1384 
1385     patchParam[patch].guardStartBand = targetStopBand;
1386     patchParam[patch].targetStartBand = targetStopBand;
1387 
1388     numBandsInPatch =
1389         desiredBorder - targetStopBand; /* Get the desired range of the patch */
1390 
1391     if (numBandsInPatch >= lsb - sourceStartBand) {
1392       /* Desired number bands are not available -> patch whole source range */
1393       patchDistance =
1394           targetStopBand - sourceStartBand; /* Get the targetOffset */
1395       patchDistance =
1396           patchDistance & ~1; /* Rounding off odd numbers and make all even */
1397       numBandsInPatch =
1398           lsb - (targetStopBand -
1399                  patchDistance); /* Update number of bands to be patched */
1400       numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch,
1401                                          v_k_master, numMaster, 0) -
1402                         targetStopBand; /* Adapt region to master-table */
1403     }
1404 
1405     if (pSettings->nCols == 64) {
1406       if (numBandsInPatch == 0 && sourceStartBand == SHIFT_START_SB) {
1407         return SBRDEC_UNSUPPORTED_CONFIG;
1408       }
1409     }
1410 
1411     /* Desired number bands are available -> get the minimal even patching
1412      * distance */
1413     patchDistance =
1414         numBandsInPatch + targetStopBand - lsb; /* Get minimal distance */
1415     patchDistance = (patchDistance + 1) &
1416                     ~1; /* Rounding up odd numbers and make all even */
1417 
1418     if (numBandsInPatch > 0) {
1419       patchParam[patch].sourceStartBand = targetStopBand - patchDistance;
1420       patchParam[patch].targetBandOffs = patchDistance;
1421       patchParam[patch].numBandsInPatch = numBandsInPatch;
1422       patchParam[patch].sourceStopBand =
1423           patchParam[patch].sourceStartBand + numBandsInPatch;
1424 
1425       targetStopBand += patchParam[patch].numBandsInPatch;
1426       patch++;
1427     }
1428 
1429     /* All patches but first */
1430     sourceStartBand = SHIFT_START_SB;
1431 
1432     /* Check if we are close to desiredBorder */
1433     if (desiredBorder - targetStopBand < 3) /* MPEG doc */
1434     {
1435       desiredBorder = usb;
1436     }
1437   }
1438 
1439   patch--;
1440 
1441   /* If highest patch contains less than three subband: skip it */
1442   if ((patch > 0) && (patchParam[patch].numBandsInPatch < 3)) {
1443     patch--;
1444     targetStopBand =
1445         patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch;
1446   }
1447 
1448   /* now check if we don't have one too many */
1449   if (patch >= MAX_NUM_PATCHES) {
1450     return SBRDEC_UNSUPPORTED_CONFIG;
1451   }
1452 
1453   pSettings->noOfPatches = patch + 1;
1454 
1455   /* Check lowest and highest source subband */
1456   pSettings->lbStartPatching = targetStopBand;
1457   pSettings->lbStopPatching = 0;
1458   for (patch = 0; patch < pSettings->noOfPatches; patch++) {
1459     pSettings->lbStartPatching =
1460         fixMin(pSettings->lbStartPatching, patchParam[patch].sourceStartBand);
1461     pSettings->lbStopPatching =
1462         fixMax(pSettings->lbStopPatching, patchParam[patch].sourceStopBand);
1463   }
1464 
1465   for (i = 0; i < noNoiseBands; i++) {
1466     pSettings->bwBorders[i] = noiseBandTable[i + 1];
1467   }
1468   for (; i < MAX_NUM_NOISE_VALUES; i++) {
1469     pSettings->bwBorders[i] = 255;
1470   }
1471 
1472   /*
1473    * Choose whitening factors
1474    */
1475 
1476   startFreqHz =
1477       ((lsb + xoverOffset) * fs) >> 7; /* Shift does a division by 2*(64) */
1478 
1479   for (i = 1; i < NUM_WHFACTOR_TABLE_ENTRIES; i++) {
1480     if (startFreqHz < FDK_sbrDecoder_sbr_whFactorsIndex[i]) break;
1481   }
1482   i--;
1483 
1484   pSettings->whFactors.off = FDK_sbrDecoder_sbr_whFactorsTable[i][0];
1485   pSettings->whFactors.transitionLevel =
1486       FDK_sbrDecoder_sbr_whFactorsTable[i][1];
1487   pSettings->whFactors.lowLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][2];
1488   pSettings->whFactors.midLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][3];
1489   pSettings->whFactors.highLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][4];
1490 
1491   return SBRDEC_OK;
1492 }
1493