Coverage Report

Created: 2025-08-26 06:50

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