Coverage Report

Created: 2026-02-14 06:59

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