Coverage Report

Created: 2025-11-16 07:20

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