Coverage Report

Created: 2025-07-12 07:02

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