Coverage Report

Created: 2026-07-25 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fdk-aac/libSBRdec/src/lpp_tran.cpp
Line
Count
Source
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
amm-info@iis.fraunhofer.de
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
54.8M
#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
151
static FIXP_DBL mapInvfMode(INVF_MODE mode, INVF_MODE prevMode,
152
1.31M
                            WHITENING_FACTORS whFactors) {
153
1.31M
  switch (mode) {
154
179k
    case INVF_LOW_LEVEL:
155
179k
      if (prevMode == INVF_OFF)
156
8.71k
        return whFactors.transitionLevel;
157
171k
      else
158
171k
        return whFactors.lowLevel;
159
160
77.8k
    case INVF_MID_LEVEL:
161
77.8k
      return whFactors.midLevel;
162
163
68.0k
    case INVF_HIGH_LEVEL:
164
68.0k
      return whFactors.highLevel;
165
166
989k
    default:
167
989k
      if (prevMode == INVF_LOW_LEVEL)
168
6.29k
        return whFactors.transitionLevel;
169
983k
      else
170
983k
        return whFactors.off;
171
1.31M
  }
172
1.31M
}
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
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
593k
) {
189
1.90M
  for (int i = 0; i < nInvfBands; i++) {
190
1.31M
    FIXP_DBL accu;
191
1.31M
    FIXP_DBL bwTmp = mapInvfMode(sbr_invf_mode[i], sbr_invf_mode_prev[i],
192
1.31M
                                 hLppTrans->pSettings->whFactors);
193
194
1.31M
    if (bwTmp < hLppTrans->bwVectorOld[i]) {
195
35.9k
      accu = fMultDiv2(FL2FXCONST_DBL(0.75f), bwTmp) +
196
35.9k
             fMultDiv2(FL2FXCONST_DBL(0.25f), hLppTrans->bwVectorOld[i]);
197
1.27M
    } else {
198
1.27M
      accu = fMultDiv2(FL2FXCONST_DBL(0.90625f), bwTmp) +
199
1.27M
             fMultDiv2(FL2FXCONST_DBL(0.09375f), hLppTrans->bwVectorOld[i]);
200
1.27M
    }
201
202
1.31M
    if (accu<FL2FXCONST_DBL(0.015625f)>> 1) {
203
965k
      bwVector[i] = FL2FXCONST_DBL(0.0f);
204
965k
    } else {
205
349k
      bwVector[i] = fixMin(accu << 1, FL2FXCONST_DBL(0.99609375f));
206
349k
    }
207
1.31M
  }
208
593k
}
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
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
2.53M
                                      const FIXP_SGL a0r, const FIXP_SGL a1r) {
225
2.53M
  const int dynscale = fixMax(0, dynamicScale - 1) + 1;
226
2.53M
  const int rescale = -fixMin(0, dynamicScale - 1) + 1;
227
2.53M
  const int descale =
228
2.53M
      fixMin(DFRACT_BITS - 1, LPC_SCALE_FACTOR + dynamicScale + rescale);
229
230
41.9M
  for (int i = 0; i < stopSample - startSample; i++) {
231
39.4M
    FIXP_DBL accu;
232
233
39.4M
    accu = fMultDiv2(a1r, lowBandReal[i]) + fMultDiv2(a0r, lowBandReal[i + 1]);
234
39.4M
    accu = (lowBandReal[i + 2] >> descale) + (accu >> dynscale);
235
236
39.4M
    qmfBufferReal[i + startSample][hiBand] =
237
39.4M
        SATURATE_LEFT_SHIFT(accu, rescale, DFRACT_BITS);
238
39.4M
  }
239
2.53M
}
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
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
514k
) {
276
514k
  INT bwIndex[MAX_NUM_PATCHES];
277
514k
  FIXP_DBL bwVector[MAX_NUM_PATCHES]; /*!< pole moving factors */
278
514k
  FIXP_DBL preWhiteningGains[(64) / 2];
279
514k
  int preWhiteningGains_exp[(64) / 2];
280
281
514k
  int i;
282
514k
  int loBand, start, stop;
283
514k
  TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
284
514k
  PATCH_PARAM *patchParam = pSettings->patchParam;
285
514k
  int patch;
286
287
514k
  FIXP_SGL alphar[LPC_ORDER], a0r, a1r;
288
514k
  FIXP_SGL alphai[LPC_ORDER], a0i = 0, a1i = 0;
289
514k
  FIXP_SGL bw = FL2FXCONST_SGL(0.0f);
290
291
514k
  int autoCorrLength;
292
293
514k
  FIXP_DBL k1, k1_below = 0, k1_below2 = 0;
294
295
514k
  ACORR_COEFS ac;
296
514k
  int startSample;
297
514k
  int stopSample;
298
514k
  int stopSampleClear;
299
300
514k
  int comLowBandScale;
301
514k
  int ovLowBandShift;
302
514k
  int lowBandShift;
303
  /*  int ovHighBandShift;*/
304
305
514k
  alphai[0] = FL2FXCONST_SGL(0.0f);
306
514k
  alphai[1] = FL2FXCONST_SGL(0.0f);
307
308
514k
  startSample = firstSlotOffs * timeStep;
309
514k
  stopSample = pSettings->nCols + lastSlotOffs * timeStep;
310
514k
  FDK_ASSERT((lastSlotOffs * timeStep) <= pSettings->overlap);
311
312
514k
  inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode,
313
514k
                                sbr_invf_mode_prev, bwVector);
314
315
514k
  stopSampleClear = stopSample;
316
317
514k
  autoCorrLength = pSettings->nCols + pSettings->overlap;
318
319
514k
  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
514k
    int targetStopBand =
325
514k
        patchParam[pSettings->noOfPatches - 1].targetStartBand +
326
514k
        patchParam[pSettings->noOfPatches - 1].numBandsInPatch;
327
328
514k
    int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL);
329
330
514k
    if (!useLP) {
331
2.88M
      for (i = startSample; i < stopSampleClear; i++) {
332
2.78M
        FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
333
2.78M
        FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize);
334
2.78M
      }
335
412k
    } else {
336
8.00M
      for (i = startSample; i < stopSampleClear; i++) {
337
7.59M
        FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
338
7.59M
      }
339
412k
    }
340
514k
  }
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
514k
  FDKmemclear(bwIndex, sizeof(bwIndex));
350
351
  /*
352
    Calc common low band scale factor
353
  */
354
514k
  comLowBandScale =
355
514k
      fixMin(sbrScaleFactor->ov_lb_scale, sbrScaleFactor->lb_scale);
356
357
514k
  ovLowBandShift = sbrScaleFactor->ov_lb_scale - comLowBandScale;
358
514k
  lowBandShift = sbrScaleFactor->lb_scale - comLowBandScale;
359
  /*  ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/
360
361
514k
  if (fPreWhitening) {
362
14.2k
    sbrDecoder_calculateGainVec(
363
14.2k
        qmfBufferReal, qmfBufferImag,
364
14.2k
        DFRACT_BITS - 1 - 16 -
365
14.2k
            sbrScaleFactor->ov_lb_scale, /* convert scale to exponent */
366
14.2k
        DFRACT_BITS - 1 - 16 -
367
14.2k
            sbrScaleFactor->lb_scale, /* convert scale to exponent */
368
14.2k
        pSettings->overlap, preWhiteningGains, preWhiteningGains_exp,
369
14.2k
        v_k_master0, startSample, stopSample);
370
14.2k
  }
371
372
  /* outer loop over bands to do analysis only once for each band */
373
374
514k
  if (!useLP) {
375
101k
    start = pSettings->lbStartPatching;
376
101k
    stop = pSettings->lbStopPatching;
377
412k
  } else {
378
412k
    start = fixMax(1, pSettings->lbStartPatching - 2);
379
412k
    stop = patchParam[0].targetStartBand;
380
412k
  }
381
382
10.1M
  for (loBand = start; loBand < stop; loBand++) {
383
9.64M
    FIXP_DBL lowBandReal[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
384
9.64M
    FIXP_DBL *plowBandReal = lowBandReal;
385
9.64M
    FIXP_DBL **pqmfBufferReal =
386
9.64M
        qmfBufferReal + firstSlotOffs * timeStep /* + pSettings->overlap */;
387
9.64M
    FIXP_DBL lowBandImag[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
388
9.64M
    FIXP_DBL *plowBandImag = lowBandImag;
389
9.64M
    FIXP_DBL **pqmfBufferImag =
390
9.64M
        qmfBufferImag + firstSlotOffs * timeStep /* + pSettings->overlap */;
391
9.64M
    int resetLPCCoeffs = 0;
392
9.64M
    int dynamicScale = DFRACT_BITS - 1 - LPC_SCALE_FACTOR;
393
9.64M
    int acDetScale = 0; /* scaling of autocorrelation determinant */
394
395
9.64M
    for (i = 0;
396
29.1M
         i < LPC_ORDER + firstSlotOffs * timeStep /*+pSettings->overlap*/;
397
19.4M
         i++) {
398
19.4M
      *plowBandReal++ = hLppTrans->lpcFilterStatesRealLegSBR[i][loBand];
399
19.4M
      if (!useLP)
400
2.05M
        *plowBandImag++ = hLppTrans->lpcFilterStatesImagLegSBR[i][loBand];
401
19.4M
    }
402
403
    /*
404
      Take old slope length qmf slot source values out of (overlap)qmf buffer
405
    */
406
9.64M
    if (!useLP) {
407
993k
      for (i = 0;
408
27.8M
           i < pSettings->nCols + pSettings->overlap - firstSlotOffs * timeStep;
409
26.8M
           i++) {
410
26.8M
        *plowBandReal++ = (*pqmfBufferReal++)[loBand];
411
26.8M
        *plowBandImag++ = (*pqmfBufferImag++)[loBand];
412
26.8M
      }
413
8.64M
    } else {
414
      /* pSettings->overlap is always even */
415
8.64M
      FDK_ASSERT((pSettings->overlap & 1) == 0);
416
96.2M
      for (i = 0; i < ((pSettings->nCols + pSettings->overlap -
417
96.2M
                        firstSlotOffs * timeStep) >>
418
96.2M
                       1);
419
87.6M
           i++) {
420
87.6M
        *plowBandReal++ = (*pqmfBufferReal++)[loBand];
421
87.6M
        *plowBandReal++ = (*pqmfBufferReal++)[loBand];
422
87.6M
      }
423
8.64M
      if (pSettings->nCols & 1) {
424
5.70M
        *plowBandReal++ = (*pqmfBufferReal++)[loBand];
425
5.70M
      }
426
8.64M
    }
427
428
    /*
429
      Determine dynamic scaling value.
430
     */
431
9.64M
    dynamicScale =
432
9.64M
        fixMin(dynamicScale,
433
9.64M
               getScalefactor(lowBandReal, LPC_ORDER + pSettings->overlap) +
434
9.64M
                   ovLowBandShift);
435
9.64M
    dynamicScale =
436
9.64M
        fixMin(dynamicScale,
437
9.64M
               getScalefactor(&lowBandReal[LPC_ORDER + pSettings->overlap],
438
9.64M
                              pSettings->nCols) +
439
9.64M
                   lowBandShift);
440
9.64M
    if (!useLP) {
441
993k
      dynamicScale =
442
993k
          fixMin(dynamicScale,
443
993k
                 getScalefactor(lowBandImag, LPC_ORDER + pSettings->overlap) +
444
993k
                     ovLowBandShift);
445
993k
      dynamicScale =
446
993k
          fixMin(dynamicScale,
447
993k
                 getScalefactor(&lowBandImag[LPC_ORDER + pSettings->overlap],
448
993k
                                pSettings->nCols) +
449
993k
                     lowBandShift);
450
993k
    }
451
452
9.64M
    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
63.9M
      for (i = 0; i < (LPC_ORDER + pSettings->overlap + pSettings->nCols);
457
61.3M
           i++) {
458
61.3M
        lowBandReal[i] = fixMax(lowBandReal[i], (FIXP_DBL)0x80000001);
459
61.3M
      }
460
2.58M
      if (!useLP) {
461
7.56M
        for (i = 0; i < (LPC_ORDER + pSettings->overlap + pSettings->nCols);
462
7.28M
             i++) {
463
7.28M
          lowBandImag[i] = fixMax(lowBandImag[i], (FIXP_DBL)0x80000001);
464
7.28M
        }
465
282k
      }
466
7.05M
    } else {
467
7.05M
      dynamicScale =
468
7.05M
          fixMax(0, dynamicScale -
469
7.05M
                        1); /* one additional bit headroom to prevent -1.0 */
470
7.05M
    }
471
472
    /*
473
      Scale temporal QMF buffer.
474
     */
475
9.64M
    scaleValues(&lowBandReal[0], LPC_ORDER + pSettings->overlap,
476
9.64M
                dynamicScale - ovLowBandShift);
477
9.64M
    scaleValues(&lowBandReal[LPC_ORDER + pSettings->overlap], pSettings->nCols,
478
9.64M
                dynamicScale - lowBandShift);
479
480
9.64M
    if (!useLP) {
481
993k
      scaleValues(&lowBandImag[0], LPC_ORDER + pSettings->overlap,
482
993k
                  dynamicScale - ovLowBandShift);
483
993k
      scaleValues(&lowBandImag[LPC_ORDER + pSettings->overlap],
484
993k
                  pSettings->nCols, dynamicScale - lowBandShift);
485
993k
    }
486
487
9.64M
    if (!useLP) {
488
993k
      acDetScale += autoCorr2nd_cplx(&ac, lowBandReal + LPC_ORDER,
489
993k
                                     lowBandImag + LPC_ORDER, autoCorrLength);
490
8.64M
    } else {
491
8.64M
      acDetScale +=
492
8.64M
          autoCorr2nd_real(&ac, lowBandReal + LPC_ORDER, autoCorrLength);
493
8.64M
    }
494
495
    /* Examine dynamic of determinant in autocorrelation. */
496
9.64M
    acDetScale += 2 * (comLowBandScale + dynamicScale);
497
9.64M
    acDetScale *= 2;            /* two times reflection coefficent scaling */
498
9.64M
    acDetScale += ac.det_scale; /* ac scaling of determinant */
499
500
    /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */
501
9.64M
    if (acDetScale > 126) {
502
151k
      resetLPCCoeffs = 1;
503
151k
    }
504
505
9.64M
    alphar[1] = FL2FXCONST_SGL(0.0f);
506
9.64M
    if (!useLP) alphai[1] = FL2FXCONST_SGL(0.0f);
507
508
9.64M
    if (ac.det != FL2FXCONST_DBL(0.0f)) {
509
9.48M
      FIXP_DBL tmp, absTmp, absDet;
510
511
9.48M
      absDet = fixp_abs(ac.det);
512
513
9.48M
      if (!useLP) {
514
935k
        tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) -
515
935k
              ((fMultDiv2(ac.r01i, ac.r12i) + fMultDiv2(ac.r02r, ac.r11r)) >>
516
935k
               (LPC_SCALE_FACTOR - 1));
517
8.55M
      } else {
518
8.55M
        tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) -
519
8.55M
              (fMultDiv2(ac.r02r, ac.r11r) >> (LPC_SCALE_FACTOR - 1));
520
8.55M
      }
521
9.48M
      absTmp = fixp_abs(tmp);
522
523
      /*
524
        Quick check: is first filter coeff >= 1(4)
525
       */
526
9.48M
      {
527
9.48M
        INT scale;
528
9.48M
        FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
529
9.48M
        scale = scale + ac.det_scale;
530
531
9.48M
        if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) {
532
2.79k
          resetLPCCoeffs = 1;
533
9.48M
        } else {
534
9.48M
          alphar[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
535
9.48M
          if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
536
4.83M
            alphar[1] = -alphar[1];
537
4.83M
          }
538
9.48M
        }
539
9.48M
      }
540
541
9.48M
      if (!useLP) {
542
935k
        tmp = (fMultDiv2(ac.r01i, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) +
543
935k
              ((fMultDiv2(ac.r01r, ac.r12i) -
544
935k
                (FIXP_DBL)fMultDiv2(ac.r02i, ac.r11r)) >>
545
935k
               (LPC_SCALE_FACTOR - 1));
546
547
935k
        absTmp = fixp_abs(tmp);
548
549
        /*
550
        Quick check: is second filter coeff >= 1(4)
551
        */
552
935k
        {
553
935k
          INT scale;
554
935k
          FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
555
935k
          scale = scale + ac.det_scale;
556
557
935k
          if ((scale > 0) &&
558
3.82k
              (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >>
559
3.82k
               scale)) {
560
135
            resetLPCCoeffs = 1;
561
935k
          } else {
562
935k
            alphai[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
563
935k
            if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
564
409k
              alphai[1] = -alphai[1];
565
409k
            }
566
935k
          }
567
935k
        }
568
935k
      }
569
9.48M
    }
570
571
9.64M
    alphar[0] = FL2FXCONST_SGL(0.0f);
572
9.64M
    if (!useLP) alphai[0] = FL2FXCONST_SGL(0.0f);
573
574
9.64M
    if (ac.r11r != FL2FXCONST_DBL(0.0f)) {
575
      /* ac.r11r is always >=0 */
576
9.48M
      FIXP_DBL tmp, absTmp;
577
578
9.48M
      if (!useLP) {
579
935k
        tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) +
580
935k
              (fMultDiv2(alphar[1], ac.r12r) + fMultDiv2(alphai[1], ac.r12i));
581
8.55M
      } else {
582
8.55M
        if (ac.r01r >= FL2FXCONST_DBL(0.0f))
583
4.29M
          tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) +
584
4.29M
                fMultDiv2(alphar[1], ac.r12r);
585
4.25M
        else
586
4.25M
          tmp = -((-ac.r01r) >> (LPC_SCALE_FACTOR + 1)) +
587
4.25M
                fMultDiv2(alphar[1], ac.r12r);
588
8.55M
      }
589
590
9.48M
      absTmp = fixp_abs(tmp);
591
592
      /*
593
        Quick check: is first filter coeff >= 1(4)
594
      */
595
596
9.48M
      if (absTmp >= (ac.r11r >> 1)) {
597
861
        resetLPCCoeffs = 1;
598
9.48M
      } else {
599
9.48M
        INT scale;
600
9.48M
        FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
601
9.48M
        alphar[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
602
603
9.48M
        if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
604
4.75M
          alphar[0] = -alphar[0];
605
9.48M
      }
606
607
9.48M
      if (!useLP) {
608
935k
        tmp = (ac.r01i >> (LPC_SCALE_FACTOR + 1)) +
609
935k
              (fMultDiv2(alphai[1], ac.r12r) - fMultDiv2(alphar[1], ac.r12i));
610
611
935k
        absTmp = fixp_abs(tmp);
612
613
        /*
614
        Quick check: is second filter coeff >= 1(4)
615
        */
616
935k
        if (absTmp >= (ac.r11r >> 1)) {
617
112
          resetLPCCoeffs = 1;
618
935k
        } else {
619
935k
          INT scale;
620
935k
          FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
621
935k
          alphai[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
622
935k
          if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
623
458k
            alphai[0] = -alphai[0];
624
935k
        }
625
935k
      }
626
9.48M
    }
627
628
9.64M
    if (!useLP) {
629
      /* Now check the quadratic criteria */
630
993k
      if ((fMultDiv2(alphar[0], alphar[0]) + fMultDiv2(alphai[0], alphai[0])) >=
631
993k
          FL2FXCONST_DBL(0.5f))
632
52
        resetLPCCoeffs = 1;
633
993k
      if ((fMultDiv2(alphar[1], alphar[1]) + fMultDiv2(alphai[1], alphai[1])) >=
634
993k
          FL2FXCONST_DBL(0.5f))
635
29
        resetLPCCoeffs = 1;
636
993k
    }
637
638
9.64M
    if (resetLPCCoeffs) {
639
155k
      alphar[0] = FL2FXCONST_SGL(0.0f);
640
155k
      alphar[1] = FL2FXCONST_SGL(0.0f);
641
155k
      if (!useLP) {
642
57.9k
        alphai[0] = FL2FXCONST_SGL(0.0f);
643
57.9k
        alphai[1] = FL2FXCONST_SGL(0.0f);
644
57.9k
      }
645
155k
    }
646
647
9.64M
    if (useLP) {
648
      /* Aliasing detection */
649
8.64M
      if (ac.r11r == FL2FXCONST_DBL(0.0f)) {
650
94.4k
        k1 = FL2FXCONST_DBL(0.0f);
651
8.55M
      } else {
652
8.55M
        if (fixp_abs(ac.r01r) >= fixp_abs(ac.r11r)) {
653
6.70k
          if (fMultDiv2(ac.r01r, ac.r11r) < FL2FX_DBL(0.0f)) {
654
2.12k
            k1 = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_SGL(1.0f)*/;
655
4.58k
          } else {
656
            /* Since this value is squared later, it must not ever become -1.0f.
657
             */
658
4.58k
            k1 = (FIXP_DBL)(MINVAL_DBL + 1) /*FL2FXCONST_SGL(-1.0f)*/;
659
4.58k
          }
660
8.54M
        } else {
661
8.54M
          INT scale;
662
8.54M
          FIXP_DBL result =
663
8.54M
              fDivNorm(fixp_abs(ac.r01r), fixp_abs(ac.r11r), &scale);
664
8.54M
          k1 = scaleValueSaturate(result, scale);
665
666
8.54M
          if (!((ac.r01r < FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))) {
667
4.29M
            k1 = -k1;
668
4.29M
          }
669
8.54M
        }
670
8.55M
      }
671
8.64M
      if ((loBand > 1) && (loBand < v_k_master0)) {
672
        /* Check if the gain should be locked */
673
7.41M
        FIXP_DBL deg =
674
7.41M
            /*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - fPow2(k1_below);
675
7.41M
        degreeAlias[loBand] = FL2FXCONST_DBL(0.0f);
676
7.41M
        if (((loBand & 1) == 0) && (k1 < FL2FXCONST_DBL(0.0f))) {
677
2.05M
          if (k1_below < FL2FXCONST_DBL(0.0f)) { /* 2-Ch Aliasing Detection */
678
974k
            degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/;
679
974k
            if (k1_below2 >
680
974k
                FL2FXCONST_DBL(0.0f)) { /* 3-Ch Aliasing Detection */
681
365k
              degreeAlias[loBand - 1] = deg;
682
365k
            }
683
1.08M
          } else if (k1_below2 >
684
1.08M
                     FL2FXCONST_DBL(0.0f)) { /* 3-Ch Aliasing Detection */
685
465k
            degreeAlias[loBand] = deg;
686
465k
          }
687
2.05M
        }
688
7.41M
        if (((loBand & 1) == 1) && (k1 > FL2FXCONST_DBL(0.0f))) {
689
1.99M
          if (k1_below > FL2FXCONST_DBL(0.0f)) { /* 2-CH Aliasing Detection */
690
968k
            degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/;
691
968k
            if (k1_below2 <
692
968k
                FL2FXCONST_DBL(0.0f)) { /* 3-CH Aliasing Detection */
693
387k
              degreeAlias[loBand - 1] = deg;
694
387k
            }
695
1.02M
          } else if (k1_below2 <
696
1.02M
                     FL2FXCONST_DBL(0.0f)) { /* 3-CH Aliasing Detection */
697
465k
            degreeAlias[loBand] = deg;
698
465k
          }
699
1.99M
        }
700
7.41M
      }
701
      /* remember k1 values of the 2 QMF channels below the current channel */
702
8.64M
      k1_below2 = k1_below;
703
8.64M
      k1_below = k1;
704
8.64M
    }
705
706
9.64M
    patch = 0;
707
708
29.5M
    while (patch < pSettings->noOfPatches) { /* inner loop over every patch */
709
710
19.9M
      int hiBand = loBand + patchParam[patch].targetBandOffs;
711
712
19.9M
      if (loBand < patchParam[patch].sourceStartBand ||
713
15.2M
          loBand >= patchParam[patch].sourceStopBand
714
          //|| hiBand >= hLppTrans->pSettings->noChannels
715
19.9M
      ) {
716
        /* Lowband not in current patch - proceed */
717
7.25M
        patch++;
718
7.25M
        continue;
719
7.25M
      }
720
721
12.6M
      FDK_ASSERT(hiBand < (64));
722
723
      /* bwIndex[patch] is already initialized with value from previous band
724
       * inside this patch */
725
14.1M
      while (hiBand >= pSettings->bwBorders[bwIndex[patch]] &&
726
1.46M
             bwIndex[patch] < MAX_NUM_PATCHES - 1) {
727
1.46M
        bwIndex[patch]++;
728
1.46M
      }
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
12.6M
      bw = FX_DBL2FX_SGL(bwVector[bwIndex[patch]]);
735
736
12.6M
      a0r = FX_DBL2FX_SGL(
737
12.6M
          fMult(bw, alphar[0])); /* Apply current bandwidth expansion factor */
738
739
12.6M
      if (!useLP) a0i = FX_DBL2FX_SGL(fMult(bw, alphai[0]));
740
12.6M
      bw = FX_DBL2FX_SGL(fPow2(bw));
741
12.6M
      a1r = FX_DBL2FX_SGL(fMult(bw, alphar[1]));
742
12.6M
      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
12.6M
      if (bw <= FL2FXCONST_SGL(0.0f)) {
748
9.69M
        if (!useLP) {
749
1.40M
          int descale =
750
1.40M
              fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
751
34.4M
          for (i = startSample; i < stopSample; i++) {
752
33.0M
            FIXP_DBL accu1, accu2;
753
33.0M
            accu1 = lowBandReal[LPC_ORDER + i] >> descale;
754
33.0M
            accu2 = lowBandImag[LPC_ORDER + i] >> descale;
755
33.0M
            if (fPreWhitening) {
756
5.87M
              accu1 = scaleValueSaturate(
757
5.87M
                  fMultDiv2(accu1, preWhiteningGains[loBand]),
758
5.87M
                  preWhiteningGains_exp[loBand] + 1);
759
5.87M
              accu2 = scaleValueSaturate(
760
5.87M
                  fMultDiv2(accu2, preWhiteningGains[loBand]),
761
5.87M
                  preWhiteningGains_exp[loBand] + 1);
762
5.87M
            }
763
33.0M
            qmfBufferReal[i][hiBand] = accu1;
764
33.0M
            qmfBufferImag[i][hiBand] = accu2;
765
33.0M
          }
766
8.28M
        } else {
767
8.28M
          int descale =
768
8.28M
              fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
769
164M
          for (i = startSample; i < stopSample; i++) {
770
156M
            qmfBufferReal[i][hiBand] = lowBandReal[LPC_ORDER + i] >> descale;
771
156M
          }
772
8.28M
        }
773
9.69M
      } else { /* bw <= 0 */
774
775
3.00M
        if (!useLP) {
776
471k
          const int dynscale = fixMax(0, dynamicScale - 2) + 1;
777
471k
          const int rescale = -fixMin(0, dynamicScale - 2) + 1;
778
471k
          const int descale = fixMin(DFRACT_BITS - 1,
779
471k
                                     LPC_SCALE_FACTOR + dynamicScale + rescale);
780
781
12.9M
          for (i = startSample; i < stopSample; i++) {
782
12.5M
            FIXP_DBL accu1, accu2;
783
784
12.5M
            accu1 = ((fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) -
785
12.5M
                      fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1])) >>
786
12.5M
                     1) +
787
12.5M
                    ((fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) -
788
12.5M
                      fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >>
789
12.5M
                     1);
790
12.5M
            accu2 = ((fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) +
791
12.5M
                      fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1])) >>
792
12.5M
                     1) +
793
12.5M
                    ((fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) +
794
12.5M
                      fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >>
795
12.5M
                     1);
796
797
12.5M
            accu1 =
798
12.5M
                (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 >> dynscale);
799
12.5M
            accu2 =
800
12.5M
                (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 >> dynscale);
801
12.5M
            if (fPreWhitening) {
802
1.31M
              qmfBufferReal[i][hiBand] = scaleValueSaturate(
803
1.31M
                  fMultDiv2(accu1, preWhiteningGains[loBand]),
804
1.31M
                  preWhiteningGains_exp[loBand] + 1 + rescale);
805
1.31M
              qmfBufferImag[i][hiBand] = scaleValueSaturate(
806
1.31M
                  fMultDiv2(accu2, preWhiteningGains[loBand]),
807
1.31M
                  preWhiteningGains_exp[loBand] + 1 + rescale);
808
11.1M
            } else {
809
11.1M
              qmfBufferReal[i][hiBand] =
810
11.1M
                  SATURATE_LEFT_SHIFT(accu1, rescale, DFRACT_BITS);
811
11.1M
              qmfBufferImag[i][hiBand] =
812
11.1M
                  SATURATE_LEFT_SHIFT(accu2, rescale, DFRACT_BITS);
813
11.1M
            }
814
12.5M
          }
815
2.53M
        } else {
816
2.53M
          FDK_ASSERT(dynamicScale >= 0);
817
2.53M
          calc_qmfBufferReal(
818
2.53M
              qmfBufferReal, &(lowBandReal[LPC_ORDER + startSample - 2]),
819
2.53M
              startSample, stopSample, hiBand, dynamicScale, a0r, a1r);
820
2.53M
        }
821
3.00M
      } /* bw <= 0 */
822
823
12.6M
      patch++;
824
825
12.6M
    } /* inner loop over patches */
826
827
    /*
828
     * store the unmodified filter coefficients if there is
829
     * an overlapping envelope
830
     *****************************************************************/
831
832
9.64M
  } /* outer loop over bands (loBand) */
833
834
514k
  if (useLP) {
835
412k
    for (loBand = pSettings->lbStartPatching;
836
7.39M
         loBand < pSettings->lbStopPatching; loBand++) {
837
6.98M
      patch = 0;
838
21.1M
      while (patch < pSettings->noOfPatches) {
839
14.1M
        UCHAR hiBand = loBand + patchParam[patch].targetBandOffs;
840
841
14.1M
        if (loBand < patchParam[patch].sourceStartBand ||
842
11.0M
            loBand >= patchParam[patch].sourceStopBand ||
843
10.8M
            hiBand >= (64) /* Highband out of range (biterror) */
844
14.1M
        ) {
845
          /* Lowband not in current patch or highband out of range (might be
846
           * caused by biterrors)- proceed */
847
3.34M
          patch++;
848
3.34M
          continue;
849
3.34M
        }
850
851
10.8M
        if (hiBand != patchParam[patch].targetStartBand)
852
9.91M
          degreeAlias[hiBand] = degreeAlias[loBand];
853
854
10.8M
        patch++;
855
10.8M
      }
856
6.98M
    } /* end  for loop */
857
412k
  }
858
859
1.63M
  for (i = 0; i < nInvfBands; i++) {
860
1.12M
    hLppTrans->bwVectorOld[i] = bwVector[i];
861
1.12M
  }
862
863
  /*
864
    set high band scale factor
865
  */
866
514k
  sbrScaleFactor->hb_scale = comLowBandScale - (LPC_SCALE_FACTOR);
867
514k
}
868
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
79.4k
) {
884
79.4k
  INT bwIndex;
885
79.4k
  FIXP_DBL bwVector[MAX_NUM_PATCHES_HBE]; /*!< pole moving factors */
886
887
79.4k
  int i;
888
79.4k
  int loBand, start, stop;
889
79.4k
  TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
890
79.4k
  PATCH_PARAM *patchParam = pSettings->patchParam;
891
892
79.4k
  FIXP_SGL alphar[LPC_ORDER], a0r, a1r;
893
79.4k
  FIXP_SGL alphai[LPC_ORDER], a0i = 0, a1i = 0;
894
79.4k
  FIXP_SGL bw = FL2FXCONST_SGL(0.0f);
895
896
79.4k
  int autoCorrLength;
897
898
79.4k
  ACORR_COEFS ac;
899
79.4k
  int startSample;
900
79.4k
  int stopSample;
901
79.4k
  int stopSampleClear;
902
903
79.4k
  int comBandScale;
904
79.4k
  int ovLowBandShift;
905
79.4k
  int lowBandShift;
906
  /*  int ovHighBandShift;*/
907
908
79.4k
  alphai[0] = FL2FXCONST_SGL(0.0f);
909
79.4k
  alphai[1] = FL2FXCONST_SGL(0.0f);
910
911
79.4k
  startSample = firstSlotOffs * timeStep;
912
79.4k
  stopSample = pSettings->nCols + lastSlotOffs * timeStep;
913
914
79.4k
  inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode,
915
79.4k
                                sbr_invf_mode_prev, bwVector);
916
917
79.4k
  stopSampleClear = stopSample;
918
919
79.4k
  autoCorrLength = pSettings->nCols + pSettings->overlap;
920
921
79.4k
  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
79.4k
    int targetStopBand =
927
79.4k
        patchParam[pSettings->noOfPatches - 1].targetStartBand +
928
79.4k
        patchParam[pSettings->noOfPatches - 1].numBandsInPatch;
929
930
79.4k
    int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL);
931
932
2.80M
    for (i = startSample; i < stopSampleClear; i++) {
933
2.72M
      FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
934
2.72M
      FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize);
935
2.72M
    }
936
79.4k
  }
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
79.4k
  comBandScale = sbrScaleFactor->hb_scale;
948
949
79.4k
  ovLowBandShift = sbrScaleFactor->hb_scale - comBandScale;
950
79.4k
  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
79.4k
  start = hQmfTransposer->startBand;
956
79.4k
  stop = hQmfTransposer->stopBand;
957
958
2.04M
  for (loBand = start; loBand < stop; loBand++) {
959
1.96M
    bwIndex = 0;
960
961
1.96M
    FIXP_DBL lowBandReal[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
962
1.96M
    FIXP_DBL lowBandImag[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
963
964
1.96M
    int resetLPCCoeffs = 0;
965
1.96M
    int dynamicScale = DFRACT_BITS - 1 - LPC_SCALE_FACTOR;
966
1.96M
    int acDetScale = 0; /* scaling of autocorrelation determinant */
967
968
5.89M
    for (i = 0; i < LPC_ORDER; i++) {
969
3.93M
      lowBandReal[i] = hLppTrans->lpcFilterStatesRealHBE[i][loBand];
970
3.93M
      lowBandImag[i] = hLppTrans->lpcFilterStatesImagHBE[i][loBand];
971
3.93M
    }
972
973
1.97M
    for (; i < LPC_ORDER + firstSlotOffs * timeStep; i++) {
974
7.20k
      lowBandReal[i] = hLppTrans->lpcFilterStatesRealHBE[i][loBand];
975
7.20k
      lowBandImag[i] = hLppTrans->lpcFilterStatesImagHBE[i][loBand];
976
7.20k
    }
977
978
    /*
979
    Take old slope length qmf slot source values out of (overlap)qmf buffer
980
    */
981
1.96M
    for (i = firstSlotOffs * timeStep;
982
79.1M
         i < pSettings->nCols + pSettings->overlap; i++) {
983
77.2M
      lowBandReal[i + LPC_ORDER] = qmfBufferReal[i][loBand];
984
77.2M
      lowBandImag[i + LPC_ORDER] = qmfBufferImag[i][loBand];
985
77.2M
    }
986
987
    /* store unmodified values to buffer */
988
18.0M
    for (i = 0; i < LPC_ORDER + pSettings->overlap; i++) {
989
16.1M
      hLppTrans->lpcFilterStatesRealHBE[i][loBand] =
990
16.1M
          qmfBufferReal[pSettings->nCols - LPC_ORDER + i][loBand];
991
16.1M
      hLppTrans->lpcFilterStatesImagHBE[i][loBand] =
992
16.1M
          qmfBufferImag[pSettings->nCols - LPC_ORDER + i][loBand];
993
16.1M
    }
994
995
    /*
996
    Determine dynamic scaling value.
997
    */
998
1.96M
    dynamicScale =
999
1.96M
        fixMin(dynamicScale,
1000
1.96M
               getScalefactor(lowBandReal, LPC_ORDER + pSettings->overlap) +
1001
1.96M
                   ovLowBandShift);
1002
1.96M
    dynamicScale =
1003
1.96M
        fixMin(dynamicScale,
1004
1.96M
               getScalefactor(&lowBandReal[LPC_ORDER + pSettings->overlap],
1005
1.96M
                              pSettings->nCols) +
1006
1.96M
                   lowBandShift);
1007
1.96M
    dynamicScale =
1008
1.96M
        fixMin(dynamicScale,
1009
1.96M
               getScalefactor(lowBandImag, LPC_ORDER + pSettings->overlap) +
1010
1.96M
                   ovLowBandShift);
1011
1.96M
    dynamicScale =
1012
1.96M
        fixMin(dynamicScale,
1013
1.96M
               getScalefactor(&lowBandImag[LPC_ORDER + pSettings->overlap],
1014
1.96M
                              pSettings->nCols) +
1015
1.96M
                   lowBandShift);
1016
1017
1.96M
    dynamicScale =
1018
1.96M
        dynamicScale - 1; /* one additional bit headroom to prevent -1.0 */
1019
1020
    /*
1021
    Scale temporal QMF buffer.
1022
    */
1023
1.96M
    scaleValues(&lowBandReal[0], LPC_ORDER + pSettings->overlap,
1024
1.96M
                dynamicScale - ovLowBandShift);
1025
1.96M
    scaleValues(&lowBandReal[LPC_ORDER + pSettings->overlap], pSettings->nCols,
1026
1.96M
                dynamicScale - lowBandShift);
1027
1.96M
    scaleValues(&lowBandImag[0], LPC_ORDER + pSettings->overlap,
1028
1.96M
                dynamicScale - ovLowBandShift);
1029
1.96M
    scaleValues(&lowBandImag[LPC_ORDER + pSettings->overlap], pSettings->nCols,
1030
1.96M
                dynamicScale - lowBandShift);
1031
1032
1.96M
    acDetScale += autoCorr2nd_cplx(&ac, lowBandReal + LPC_ORDER,
1033
1.96M
                                   lowBandImag + LPC_ORDER, autoCorrLength);
1034
1035
    /* Examine dynamic of determinant in autocorrelation. */
1036
1.96M
    acDetScale += 2 * (comBandScale + dynamicScale);
1037
1.96M
    acDetScale *= 2;            /* two times reflection coefficent scaling */
1038
1.96M
    acDetScale += ac.det_scale; /* ac scaling of determinant */
1039
1040
    /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */
1041
1.96M
    if (acDetScale > 126) {
1042
69.4k
      resetLPCCoeffs = 1;
1043
69.4k
    }
1044
1045
1.96M
    alphar[1] = FL2FXCONST_SGL(0.0f);
1046
1.96M
    alphai[1] = FL2FXCONST_SGL(0.0f);
1047
1048
1.96M
    if (ac.det != FL2FXCONST_DBL(0.0f)) {
1049
1.89M
      FIXP_DBL tmp, absTmp, absDet;
1050
1051
1.89M
      absDet = fixp_abs(ac.det);
1052
1053
1.89M
      tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) -
1054
1.89M
            ((fMultDiv2(ac.r01i, ac.r12i) + fMultDiv2(ac.r02r, ac.r11r)) >>
1055
1.89M
             (LPC_SCALE_FACTOR - 1));
1056
1.89M
      absTmp = fixp_abs(tmp);
1057
1058
      /*
1059
      Quick check: is first filter coeff >= 1(4)
1060
      */
1061
1.89M
      {
1062
1.89M
        INT scale;
1063
1.89M
        FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
1064
1.89M
        scale = scale + ac.det_scale;
1065
1066
1.89M
        if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) {
1067
716
          resetLPCCoeffs = 1;
1068
1.89M
        } else {
1069
1.89M
          alphar[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
1070
1.89M
          if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
1071
1.26M
            alphar[1] = -alphar[1];
1072
1.26M
          }
1073
1.89M
        }
1074
1.89M
      }
1075
1076
1.89M
      tmp = (fMultDiv2(ac.r01i, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) +
1077
1.89M
            ((fMultDiv2(ac.r01r, ac.r12i) -
1078
1.89M
              (FIXP_DBL)fMultDiv2(ac.r02i, ac.r11r)) >>
1079
1.89M
             (LPC_SCALE_FACTOR - 1));
1080
1081
1.89M
      absTmp = fixp_abs(tmp);
1082
1083
      /*
1084
      Quick check: is second filter coeff >= 1(4)
1085
      */
1086
1.89M
      {
1087
1.89M
        INT scale;
1088
1.89M
        FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
1089
1.89M
        scale = scale + ac.det_scale;
1090
1091
1.89M
        if ((scale > 0) &&
1092
918
            (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >> scale)) {
1093
412
          resetLPCCoeffs = 1;
1094
1.89M
        } else {
1095
1.89M
          alphai[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
1096
1.89M
          if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
1097
939k
            alphai[1] = -alphai[1];
1098
939k
          }
1099
1.89M
        }
1100
1.89M
      }
1101
1.89M
    }
1102
1103
1.96M
    alphar[0] = FL2FXCONST_SGL(0.0f);
1104
1.96M
    alphai[0] = FL2FXCONST_SGL(0.0f);
1105
1106
1.96M
    if (ac.r11r != FL2FXCONST_DBL(0.0f)) {
1107
      /* ac.r11r is always >=0 */
1108
1.89M
      FIXP_DBL tmp, absTmp;
1109
1110
1.89M
      tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) +
1111
1.89M
            (fMultDiv2(alphar[1], ac.r12r) + fMultDiv2(alphai[1], ac.r12i));
1112
1113
1.89M
      absTmp = fixp_abs(tmp);
1114
1115
      /*
1116
      Quick check: is first filter coeff >= 1(4)
1117
      */
1118
1119
1.89M
      if (absTmp >= (ac.r11r >> 1)) {
1120
117
        resetLPCCoeffs = 1;
1121
1.89M
      } else {
1122
1.89M
        INT scale;
1123
1.89M
        FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
1124
1.89M
        alphar[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
1125
1126
1.89M
        if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
1127
1.00M
          alphar[0] = -alphar[0];
1128
1.89M
      }
1129
1130
1.89M
      tmp = (ac.r01i >> (LPC_SCALE_FACTOR + 1)) +
1131
1.89M
            (fMultDiv2(alphai[1], ac.r12r) - fMultDiv2(alphar[1], ac.r12i));
1132
1133
1.89M
      absTmp = fixp_abs(tmp);
1134
1135
      /*
1136
      Quick check: is second filter coeff >= 1(4)
1137
      */
1138
1.89M
      if (absTmp >= (ac.r11r >> 1)) {
1139
72
        resetLPCCoeffs = 1;
1140
1.89M
      } else {
1141
1.89M
        INT scale;
1142
1.89M
        FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
1143
1.89M
        alphai[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
1144
1.89M
        if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) {
1145
949k
          alphai[0] = -alphai[0];
1146
949k
        }
1147
1.89M
      }
1148
1.89M
    }
1149
1150
    /* Now check the quadratic criteria */
1151
1.96M
    if ((fMultDiv2(alphar[0], alphar[0]) + fMultDiv2(alphai[0], alphai[0])) >=
1152
1.96M
        FL2FXCONST_DBL(0.5f)) {
1153
83
      resetLPCCoeffs = 1;
1154
83
    }
1155
1.96M
    if ((fMultDiv2(alphar[1], alphar[1]) + fMultDiv2(alphai[1], alphai[1])) >=
1156
1.96M
        FL2FXCONST_DBL(0.5f)) {
1157
184
      resetLPCCoeffs = 1;
1158
184
    }
1159
1160
1.96M
    if (resetLPCCoeffs) {
1161
70.6k
      alphar[0] = FL2FXCONST_SGL(0.0f);
1162
70.6k
      alphar[1] = FL2FXCONST_SGL(0.0f);
1163
70.6k
      alphai[0] = FL2FXCONST_SGL(0.0f);
1164
70.6k
      alphai[1] = FL2FXCONST_SGL(0.0f);
1165
70.6k
    }
1166
1167
4.89M
    while (bwIndex < MAX_NUM_PATCHES - 1 &&
1168
4.89M
           loBand >= pSettings->bwBorders[bwIndex]) {
1169
2.92M
      bwIndex++;
1170
2.92M
    }
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
1.96M
    bw = FX_DBL2FX_SGL(bwVector[bwIndex]);
1177
1178
1.96M
    a0r = FX_DBL2FX_SGL(
1179
1.96M
        fMult(bw, alphar[0])); /* Apply current bandwidth expansion factor */
1180
1.96M
    a0i = FX_DBL2FX_SGL(fMult(bw, alphai[0]));
1181
1.96M
    bw = FX_DBL2FX_SGL(fPow2(bw));
1182
1.96M
    a1r = FX_DBL2FX_SGL(fMult(bw, alphar[1]));
1183
1.96M
    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
1.96M
    if (bw <= FL2FXCONST_SGL(0.0f)) {
1189
890k
      int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
1190
30.6M
      for (i = startSample; i < stopSample; i++) {
1191
29.7M
        qmfBufferReal[i][loBand] = lowBandReal[LPC_ORDER + i] >> descale;
1192
29.7M
        qmfBufferImag[i][loBand] = lowBandImag[LPC_ORDER + i] >> descale;
1193
29.7M
      }
1194
1.07M
    } else { /* bw <= 0 */
1195
1196
1.07M
      int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
1197
1.07M
      dynamicScale +=
1198
1.07M
          1; /* prevent negativ scale factor due to 'one additional bit
1199
                headroom' */
1200
1201
36.3M
      for (i = startSample; i < stopSample; i++) {
1202
35.2M
        FIXP_DBL accu1, accu2;
1203
1204
35.2M
        accu1 = (fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) -
1205
35.2M
                 fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1]) +
1206
35.2M
                 fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) -
1207
35.2M
                 fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >>
1208
35.2M
                dynamicScale;
1209
35.2M
        accu2 = (fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) +
1210
35.2M
                 fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1]) +
1211
35.2M
                 fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) +
1212
35.2M
                 fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >>
1213
35.2M
                dynamicScale;
1214
1215
35.2M
        qmfBufferReal[i][loBand] =
1216
35.2M
            (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << (1 + 1));
1217
35.2M
        qmfBufferImag[i][loBand] =
1218
35.2M
            (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << (1 + 1));
1219
35.2M
      }
1220
1.07M
    } /* bw <= 0 */
1221
1222
    /*
1223
     * store the unmodified filter coefficients if there is
1224
     * an overlapping envelope
1225
     *****************************************************************/
1226
1227
1.96M
  } /* outer loop over bands (loBand) */
1228
1229
270k
  for (i = 0; i < nInvfBands; i++) {
1230
191k
    hLppTrans->bwVectorOld[i] = bwVector[i];
1231
191k
  }
1232
1233
  /*
1234
  set high band scale factor
1235
  */
1236
79.4k
  sbrScaleFactor->hb_scale = comBandScale - (LPC_SCALE_FACTOR);
1237
79.4k
}
1238
1239
/*!
1240
 *
1241
 * \brief Initialize one low power transposer instance
1242
 *
1243
 *
1244
 */
1245
SBR_ERROR
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
165k
    const int overlap) {
1260
  /* FB inverse filtering settings */
1261
165k
  hs->pSettings = pSettings;
1262
1263
165k
  pSettings->nCols = nCols;
1264
165k
  pSettings->overlap = overlap;
1265
1266
165k
  switch (timeSlots) {
1267
2.90k
    case 15:
1268
165k
    case 16:
1269
165k
      break;
1270
1271
0
    default:
1272
0
      return SBRDEC_UNSUPPORTED_CONFIG; /* Unimplemented */
1273
165k
  }
1274
1275
165k
  if (chan == 0) {
1276
    /* Init common data only once */
1277
95.5k
    hs->pSettings->nCols = nCols;
1278
1279
95.5k
    return resetLppTransposer(hs, highBandStartSb, v_k_master, numMaster,
1280
95.5k
                              noiseBandTable, noNoiseBands, usb, fs);
1281
95.5k
  }
1282
70.2k
  return SBRDEC_OK;
1283
165k
}
1284
1285
static int findClosestEntry(UCHAR goalSb, UCHAR *v_k_master, UCHAR numMaster,
1286
3.58M
                            UCHAR direction) {
1287
3.58M
  int index;
1288
1289
3.58M
  if (goalSb <= v_k_master[0]) return v_k_master[0];
1290
1291
3.57M
  if (goalSb >= v_k_master[numMaster]) return v_k_master[numMaster];
1292
1293
1.43M
  if (direction) {
1294
191k
    index = 0;
1295
1.86M
    while (v_k_master[index] < goalSb) {
1296
1.67M
      index++;
1297
1.67M
    }
1298
1.24M
  } else {
1299
1.24M
    index = numMaster;
1300
6.68M
    while (v_k_master[index] > goalSb) {
1301
5.44M
      index--;
1302
5.44M
    }
1303
1.24M
  }
1304
1305
1.43M
  return v_k_master[index];
1306
3.57M
}
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
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
2.34M
) {
1325
2.34M
  TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
1326
2.34M
  PATCH_PARAM *patchParam = pSettings->patchParam;
1327
1328
2.34M
  int i, patch;
1329
2.34M
  int targetStopBand;
1330
2.34M
  int sourceStartBand;
1331
2.34M
  int patchDistance;
1332
2.34M
  int numBandsInPatch;
1333
1334
2.34M
  int lsb = v_k_master[0]; /* Start subband expressed in "non-critical" sampling
1335
                              terms*/
1336
2.34M
  int xoverOffset = highBandStartSb -
1337
2.34M
                    lsb; /* Calculate distance in QMF bands between k0 and kx */
1338
2.34M
  int startFreqHz;
1339
1340
2.34M
  int desiredBorder;
1341
1342
2.34M
  usb = fixMin(usb, v_k_master[numMaster]); /* Avoid endless loops (compare with
1343
                                               float code). */
1344
1345
  /*
1346
   * Plausibility check
1347
   */
1348
1349
2.34M
  if (pSettings->nCols == 64) {
1350
69.7k
    if (lsb < 4) {
1351
      /* 4:1 SBR Requirement k0 >= 4 missed! */
1352
270
      return SBRDEC_UNSUPPORTED_CONFIG;
1353
270
    }
1354
2.27M
  } else if (lsb - SHIFT_START_SB < 4) {
1355
459
    return SBRDEC_UNSUPPORTED_CONFIG;
1356
459
  }
1357
1358
  /*
1359
   * Initialize the patching parameter
1360
   */
1361
  /* ISO/IEC 14496-3 (Figure 4.48): goalSb = round( 2.048e6 / fs ) */
1362
2.34M
  desiredBorder = (((2048000 * 2) / fs) + 1) >> 1;
1363
1364
2.34M
  desiredBorder = findClosestEntry(desiredBorder, v_k_master, numMaster,
1365
2.34M
                                   1); /* Adapt region to master-table */
1366
1367
  /* First patch */
1368
2.34M
  sourceStartBand = SHIFT_START_SB + xoverOffset;
1369
2.34M
  targetStopBand = lsb + xoverOffset; /* upperBand */
1370
1371
  /* Even (odd) numbered channel must be patched to even (odd) numbered channel
1372
   */
1373
2.34M
  patch = 0;
1374
4.80M
  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
2.46M
    if (patch > MAX_NUM_PATCHES) {
1382
1.90k
      return SBRDEC_UNSUPPORTED_CONFIG;
1383
1.90k
    }
1384
1385
2.46M
    patchParam[patch].guardStartBand = targetStopBand;
1386
2.46M
    patchParam[patch].targetStartBand = targetStopBand;
1387
1388
2.46M
    numBandsInPatch =
1389
2.46M
        desiredBorder - targetStopBand; /* Get the desired range of the patch */
1390
1391
2.46M
    if (numBandsInPatch >= lsb - sourceStartBand) {
1392
      /* Desired number bands are not available -> patch whole source range */
1393
1.24M
      patchDistance =
1394
1.24M
          targetStopBand - sourceStartBand; /* Get the targetOffset */
1395
1.24M
      patchDistance =
1396
1.24M
          patchDistance & ~1; /* Rounding off odd numbers and make all even */
1397
1.24M
      numBandsInPatch =
1398
1.24M
          lsb - (targetStopBand -
1399
1.24M
                 patchDistance); /* Update number of bands to be patched */
1400
1.24M
      numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch,
1401
1.24M
                                         v_k_master, numMaster, 0) -
1402
1.24M
                        targetStopBand; /* Adapt region to master-table */
1403
1.24M
    }
1404
1405
2.46M
    if (pSettings->nCols == 64) {
1406
54.8k
      if (numBandsInPatch == 0 && sourceStartBand == SHIFT_START_SB) {
1407
1.20k
        return SBRDEC_UNSUPPORTED_CONFIG;
1408
1.20k
      }
1409
54.8k
    }
1410
1411
    /* Desired number bands are available -> get the minimal even patching
1412
     * distance */
1413
2.46M
    patchDistance =
1414
2.46M
        numBandsInPatch + targetStopBand - lsb; /* Get minimal distance */
1415
2.46M
    patchDistance = (patchDistance + 1) &
1416
2.46M
                    ~1; /* Rounding up odd numbers and make all even */
1417
1418
2.46M
    if (numBandsInPatch > 0) {
1419
2.29M
      patchParam[patch].sourceStartBand = targetStopBand - patchDistance;
1420
2.29M
      patchParam[patch].targetBandOffs = patchDistance;
1421
2.29M
      patchParam[patch].numBandsInPatch = numBandsInPatch;
1422
2.29M
      patchParam[patch].sourceStopBand =
1423
2.29M
          patchParam[patch].sourceStartBand + numBandsInPatch;
1424
1425
2.29M
      targetStopBand += patchParam[patch].numBandsInPatch;
1426
2.29M
      patch++;
1427
2.29M
    }
1428
1429
    /* All patches but first */
1430
2.46M
    sourceStartBand = SHIFT_START_SB;
1431
1432
    /* Check if we are close to desiredBorder */
1433
2.46M
    if (desiredBorder - targetStopBand < 3) /* MPEG doc */
1434
1.38M
    {
1435
1.38M
      desiredBorder = usb;
1436
1.38M
    }
1437
2.46M
  }
1438
1439
2.33M
  patch--;
1440
1441
  /* If highest patch contains less than three subband: skip it */
1442
2.33M
  if ((patch > 0) && (patchParam[patch].numBandsInPatch < 3)) {
1443
147k
    patch--;
1444
147k
    targetStopBand =
1445
147k
        patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch;
1446
147k
  }
1447
1448
  /* now check if we don't have one too many */
1449
2.33M
  if (patch >= MAX_NUM_PATCHES) {
1450
498
    return SBRDEC_UNSUPPORTED_CONFIG;
1451
498
  }
1452
1453
2.33M
  pSettings->noOfPatches = patch + 1;
1454
1455
  /* Check lowest and highest source subband */
1456
2.33M
  pSettings->lbStartPatching = targetStopBand;
1457
2.33M
  pSettings->lbStopPatching = 0;
1458
4.46M
  for (patch = 0; patch < pSettings->noOfPatches; patch++) {
1459
2.12M
    pSettings->lbStartPatching =
1460
2.12M
        fixMin(pSettings->lbStartPatching, patchParam[patch].sourceStartBand);
1461
2.12M
    pSettings->lbStopPatching =
1462
2.12M
        fixMax(pSettings->lbStopPatching, patchParam[patch].sourceStopBand);
1463
2.12M
  }
1464
1465
6.87M
  for (i = 0; i < noNoiseBands; i++) {
1466
4.53M
    pSettings->bwBorders[i] = noiseBandTable[i + 1];
1467
4.53M
  }
1468
21.1M
  for (; i < MAX_NUM_NOISE_VALUES; i++) {
1469
18.8M
    pSettings->bwBorders[i] = 255;
1470
18.8M
  }
1471
1472
  /*
1473
   * Choose whitening factors
1474
   */
1475
1476
2.33M
  startFreqHz =
1477
2.33M
      ((lsb + xoverOffset) * fs) >> 7; /* Shift does a division by 2*(64) */
1478
1479
8.58M
  for (i = 1; i < NUM_WHFACTOR_TABLE_ENTRIES; i++) {
1480
8.14M
    if (startFreqHz < FDK_sbrDecoder_sbr_whFactorsIndex[i]) break;
1481
8.14M
  }
1482
2.33M
  i--;
1483
1484
2.33M
  pSettings->whFactors.off = FDK_sbrDecoder_sbr_whFactorsTable[i][0];
1485
2.33M
  pSettings->whFactors.transitionLevel =
1486
2.33M
      FDK_sbrDecoder_sbr_whFactorsTable[i][1];
1487
2.33M
  pSettings->whFactors.lowLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][2];
1488
2.33M
  pSettings->whFactors.midLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][3];
1489
2.33M
  pSettings->whFactors.highLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][4];
1490
1491
2.33M
  return SBRDEC_OK;
1492
2.33M
}