Coverage Report

Created: 2025-10-28 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aac/libAACenc/src/sf_estim.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4
© Copyright  1995 - 2018 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
/**************************** AAC encoder library ******************************
96
97
   Author(s):   M. Werner
98
99
   Description: Scale factor estimation
100
101
*******************************************************************************/
102
103
#include "sf_estim.h"
104
#include "aacEnc_rom.h"
105
#include "quantize.h"
106
#include "bit_cnt.h"
107
108
#ifdef __arm__
109
#endif
110
111
0
#define UPCOUNT_LIMIT 1
112
0
#define AS_PE_FAC_SHIFT 7
113
0
#define DIST_FAC_SHIFT 3
114
#define AS_PE_FAC_FLOAT (float)(1 << AS_PE_FAC_SHIFT)
115
static const INT MAX_SCF_DELTA = 60;
116
117
static const FIXP_DBL PE_C1 = FL2FXCONST_DBL(
118
    3.0f / AS_PE_FAC_FLOAT); /* (log(8.0)/log(2)) >> AS_PE_FAC_SHIFT */
119
static const FIXP_DBL PE_C2 = FL2FXCONST_DBL(
120
    1.3219281f / AS_PE_FAC_FLOAT); /* (log(2.5)/log(2)) >> AS_PE_FAC_SHIFT */
121
static const FIXP_DBL PE_C3 = FL2FXCONST_DBL(0.5593573f); /* 1-C2/C1 */
122
123
/*
124
  Function; FDKaacEnc_FDKaacEnc_CalcFormFactorChannel
125
126
  Description: Calculates the formfactor
127
128
  sf: scale factor of the mdct spectrum
129
  sfbFormFactorLdData is scaled with the factor 1/(((2^sf)^0.5) *
130
  (2^FORM_FAC_SHIFT))
131
*/
132
static void FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(
133
    FIXP_DBL *RESTRICT sfbFormFactorLdData,
134
0
    PSY_OUT_CHANNEL *RESTRICT psyOutChan) {
135
0
  INT j, sfb, sfbGrp;
136
0
  FIXP_DBL formFactor;
137
138
0
  int tmp0 = psyOutChan->sfbCnt;
139
0
  int tmp1 = psyOutChan->maxSfbPerGroup;
140
0
  int step = psyOutChan->sfbPerGroup;
141
0
  for (sfbGrp = 0; sfbGrp < tmp0; sfbGrp += step) {
142
0
    for (sfb = 0; sfb < tmp1; sfb++) {
143
0
      formFactor = FL2FXCONST_DBL(0.0f);
144
      /* calc sum of sqrt(spec) */
145
0
      for (j = psyOutChan->sfbOffsets[sfbGrp + sfb];
146
0
           j < psyOutChan->sfbOffsets[sfbGrp + sfb + 1]; j++) {
147
0
        formFactor +=
148
0
            sqrtFixp(fixp_abs(psyOutChan->mdctSpectrum[j])) >> FORM_FAC_SHIFT;
149
0
      }
150
0
      sfbFormFactorLdData[sfbGrp + sfb] = CalcLdData(formFactor);
151
0
    }
152
    /* set sfbFormFactor for sfbs with zero spec to zero. Just for debugging. */
153
0
    for (; sfb < psyOutChan->sfbPerGroup; sfb++) {
154
0
      sfbFormFactorLdData[sfbGrp + sfb] = FL2FXCONST_DBL(-1.0f);
155
0
    }
156
0
  }
157
0
}
158
159
/*
160
  Function: FDKaacEnc_CalcFormFactor
161
162
  Description: Calls FDKaacEnc_FDKaacEnc_CalcFormFactorChannel() for each
163
  channel
164
*/
165
166
void FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)],
167
                              PSY_OUT_CHANNEL *psyOutChannel[(2)],
168
0
                              const INT nChannels) {
169
0
  INT j;
170
0
  for (j = 0; j < nChannels; j++) {
171
0
    FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(
172
0
        qcOutChannel[j]->sfbFormFactorLdData, psyOutChannel[j]);
173
0
  }
174
0
}
175
176
/*
177
  Function: FDKaacEnc_calcSfbRelevantLines
178
179
  Description: Calculates sfbNRelevantLines
180
181
  sfbNRelevantLines is scaled with the factor 1/((2^FORM_FAC_SHIFT) * 2.0)
182
*/
183
static void FDKaacEnc_calcSfbRelevantLines(
184
    const FIXP_DBL *const sfbFormFactorLdData,
185
    const FIXP_DBL *const sfbEnergyLdData,
186
    const FIXP_DBL *const sfbThresholdLdData, const INT *const sfbOffsets,
187
    const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup,
188
0
    FIXP_DBL *sfbNRelevantLines) {
189
0
  INT sfbOffs, sfb;
190
0
  FIXP_DBL sfbWidthLdData;
191
0
  FIXP_DBL asPeFacLdData =
192
0
      FL2FXCONST_DBL(0.109375); /* AS_PE_FAC_SHIFT*ld64(2) */
193
0
  FIXP_DBL accu;
194
195
  /* sfbNRelevantLines[i] = 2^( (sfbFormFactorLdData[i] - 0.25 *
196
   * (sfbEnergyLdData[i] - ld64(sfbWidth[i]/(2^7)) - AS_PE_FAC_SHIFT*ld64(2)) *
197
   * 64); */
198
199
0
  FDKmemclear(sfbNRelevantLines, sfbCnt * sizeof(FIXP_DBL));
200
201
0
  for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup) {
202
0
    for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
203
      /* calc sum of sqrt(spec) */
204
0
      if ((FIXP_DBL)sfbEnergyLdData[sfbOffs + sfb] >
205
0
          (FIXP_DBL)sfbThresholdLdData[sfbOffs + sfb]) {
206
0
        INT sfbWidth =
207
0
            sfbOffsets[sfbOffs + sfb + 1] - sfbOffsets[sfbOffs + sfb];
208
209
        /* avgFormFactorLdData =
210
         * sqrtFixp(sqrtFixp(sfbEnergyLdData[sfbOffs+sfb]/sfbWidth)); */
211
        /* sfbNRelevantLines[sfbOffs+sfb] = sfbFormFactor[sfbOffs+sfb] /
212
         * avgFormFactorLdData; */
213
0
        sfbWidthLdData =
214
0
            (FIXP_DBL)(sfbWidth << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
215
0
        sfbWidthLdData = CalcLdData(sfbWidthLdData);
216
217
0
        accu = sfbEnergyLdData[sfbOffs + sfb] - sfbWidthLdData - asPeFacLdData;
218
0
        accu = sfbFormFactorLdData[sfbOffs + sfb] - (accu >> 2);
219
220
0
        sfbNRelevantLines[sfbOffs + sfb] = CalcInvLdData(accu) >> 1;
221
0
      }
222
0
    }
223
0
  }
224
0
}
225
226
/*
227
  Function: FDKaacEnc_countSingleScfBits
228
229
  Description:
230
231
  scfBitsFract is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
232
*/
233
static FIXP_DBL FDKaacEnc_countSingleScfBits(INT scf, INT scfLeft,
234
0
                                             INT scfRight) {
235
0
  FIXP_DBL scfBitsFract;
236
237
0
  scfBitsFract = (FIXP_DBL)(FDKaacEnc_bitCountScalefactorDelta(scfLeft - scf) +
238
0
                            FDKaacEnc_bitCountScalefactorDelta(scf - scfRight));
239
240
0
  scfBitsFract = scfBitsFract << (DFRACT_BITS - 1 - (2 * AS_PE_FAC_SHIFT));
241
242
0
  return scfBitsFract; /* output scaled by 1/(2^(2*AS_PE_FAC)) */
243
0
}
244
245
/*
246
  Function: FDKaacEnc_calcSingleSpecPe
247
248
  specPe is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
249
*/
250
static FIXP_DBL FDKaacEnc_calcSingleSpecPe(INT scf, FIXP_DBL sfbConstPePart,
251
0
                                           FIXP_DBL nLines) {
252
0
  FIXP_DBL specPe = FL2FXCONST_DBL(0.0f);
253
0
  FIXP_DBL ldRatio;
254
0
  FIXP_DBL scfFract;
255
256
0
  scfFract = (FIXP_DBL)(scf << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
257
258
0
  ldRatio = sfbConstPePart - fMult(FL2FXCONST_DBL(0.375f), scfFract);
259
260
0
  if (ldRatio >= PE_C1) {
261
0
    specPe = fMult(FL2FXCONST_DBL(0.7f), fMult(nLines, ldRatio));
262
0
  } else {
263
0
    specPe = fMult(FL2FXCONST_DBL(0.7f),
264
0
                   fMult(nLines, (PE_C2 + fMult(PE_C3, ldRatio))));
265
0
  }
266
267
0
  return specPe; /* output scaled by 1/(2^(2*AS_PE_FAC)) */
268
0
}
269
270
/*
271
  Function: FDKaacEnc_countScfBitsDiff
272
273
  scfBitsDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
274
*/
275
static FIXP_DBL FDKaacEnc_countScfBitsDiff(INT *scfOld, INT *scfNew, INT sfbCnt,
276
0
                                           INT startSfb, INT stopSfb) {
277
0
  FIXP_DBL scfBitsFract;
278
0
  INT scfBitsDiff = 0;
279
0
  INT sfb = 0, sfbLast;
280
0
  INT sfbPrev, sfbNext;
281
282
  /* search for first relevant sfb */
283
0
  sfbLast = startSfb;
284
0
  while ((sfbLast < stopSfb) && (scfOld[sfbLast] == FDK_INT_MIN)) sfbLast++;
285
  /* search for previous relevant sfb and count diff */
286
0
  sfbPrev = startSfb - 1;
287
0
  while ((sfbPrev >= 0) && (scfOld[sfbPrev] == FDK_INT_MIN)) sfbPrev--;
288
0
  if (sfbPrev >= 0)
289
0
    scfBitsDiff +=
290
0
        FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbPrev] - scfNew[sfbLast]) -
291
0
        FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbPrev] - scfOld[sfbLast]);
292
  /* now loop through all sfbs and count diffs of relevant sfbs */
293
0
  for (sfb = sfbLast + 1; sfb < stopSfb; sfb++) {
294
0
    if (scfOld[sfb] != FDK_INT_MIN) {
295
0
      scfBitsDiff +=
296
0
          FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfb]) -
297
0
          FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfb]);
298
0
      sfbLast = sfb;
299
0
    }
300
0
  }
301
  /* search for next relevant sfb and count diff */
302
0
  sfbNext = stopSfb;
303
0
  while ((sfbNext < sfbCnt) && (scfOld[sfbNext] == FDK_INT_MIN)) sfbNext++;
304
0
  if (sfbNext < sfbCnt)
305
0
    scfBitsDiff +=
306
0
        FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfbNext]) -
307
0
        FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfbNext]);
308
309
0
  scfBitsFract =
310
0
      (FIXP_DBL)(scfBitsDiff << (DFRACT_BITS - 1 - (2 * AS_PE_FAC_SHIFT)));
311
312
0
  return scfBitsFract;
313
0
}
314
315
/*
316
  Function: FDKaacEnc_calcSpecPeDiff
317
318
  specPeDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
319
*/
320
static FIXP_DBL FDKaacEnc_calcSpecPeDiff(
321
    PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, INT *scfOld,
322
    INT *scfNew, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData,
323
0
    FIXP_DBL *sfbNRelevantLines, INT startSfb, INT stopSfb) {
324
0
  FIXP_DBL specPeDiff = FL2FXCONST_DBL(0.0f);
325
0
  FIXP_DBL scfFract = FL2FXCONST_DBL(0.0f);
326
0
  INT sfb;
327
328
  /* loop through all sfbs and count pe difference */
329
0
  for (sfb = startSfb; sfb < stopSfb; sfb++) {
330
0
    if (scfOld[sfb] != FDK_INT_MIN) {
331
0
      FIXP_DBL ldRatioOld, ldRatioNew, pOld, pNew;
332
333
      /* sfbConstPePart[sfb] = (float)log(psyOutChan->sfbEnergy[sfb] * 6.75f /
334
       * sfbFormFactor[sfb]) * LOG2_1; */
335
      /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for
336
       * log2 */
337
      /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
338
0
      if (sfbConstPePart[sfb] == (FIXP_DBL)FDK_INT_MIN)
339
0
        sfbConstPePart[sfb] =
340
0
            ((psyOutChan->sfbEnergyLdData[sfb] - sfbFormFactorLdData[sfb] -
341
0
              FL2FXCONST_DBL(0.09375f)) >>
342
0
             1) +
343
0
            FL2FXCONST_DBL(0.02152255861f);
344
345
0
      scfFract = (FIXP_DBL)(scfOld[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
346
0
      ldRatioOld =
347
0
          sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract);
348
349
0
      scfFract = (FIXP_DBL)(scfNew[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
350
0
      ldRatioNew =
351
0
          sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract);
352
353
0
      if (ldRatioOld >= PE_C1)
354
0
        pOld = ldRatioOld;
355
0
      else
356
0
        pOld = PE_C2 + fMult(PE_C3, ldRatioOld);
357
358
0
      if (ldRatioNew >= PE_C1)
359
0
        pNew = ldRatioNew;
360
0
      else
361
0
        pNew = PE_C2 + fMult(PE_C3, ldRatioNew);
362
363
0
      specPeDiff += fMult(FL2FXCONST_DBL(0.7f),
364
0
                          fMult(sfbNRelevantLines[sfb], (pNew - pOld)));
365
0
    }
366
0
  }
367
368
0
  return specPeDiff;
369
0
}
370
371
/*
372
  Function: FDKaacEnc_improveScf
373
374
  Description: Calculate the distortion by quantization and inverse quantization
375
  of the spectrum with various scalefactors. The scalefactor which provides the
376
  best results will be used.
377
*/
378
static INT FDKaacEnc_improveScf(const FIXP_DBL *spec, SHORT *quantSpec,
379
                                SHORT *quantSpecTmp, INT sfbWidth,
380
                                FIXP_DBL threshLdData, INT scf, INT minScf,
381
                                FIXP_DBL *distLdData, INT *minScfCalculated,
382
0
                                INT dZoneQuantEnable) {
383
0
  FIXP_DBL sfbDistLdData;
384
0
  INT scfBest = scf;
385
0
  INT k;
386
0
  FIXP_DBL distFactorLdData = FL2FXCONST_DBL(-0.0050301265); /* ld64(1/1.25) */
387
388
  /* calc real distortion */
389
0
  sfbDistLdData =
390
0
      FDKaacEnc_calcSfbDist(spec, quantSpec, sfbWidth, scf, dZoneQuantEnable);
391
0
  *minScfCalculated = scf;
392
  /* nmr > 1.25 -> try to improve nmr */
393
0
  if (sfbDistLdData > (threshLdData - distFactorLdData)) {
394
0
    INT scfEstimated = scf;
395
0
    FIXP_DBL sfbDistBestLdData = sfbDistLdData;
396
0
    INT cnt;
397
    /* improve by bigger scf ? */
398
0
    cnt = 0;
399
400
0
    while ((sfbDistLdData > (threshLdData - distFactorLdData)) &&
401
0
           (cnt++ < UPCOUNT_LIMIT)) {
402
0
      scf++;
403
0
      sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf,
404
0
                                            dZoneQuantEnable);
405
406
0
      if (sfbDistLdData < sfbDistBestLdData) {
407
0
        scfBest = scf;
408
0
        sfbDistBestLdData = sfbDistLdData;
409
0
        for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k];
410
0
      }
411
0
    }
412
    /* improve by smaller scf ? */
413
0
    cnt = 0;
414
0
    scf = scfEstimated;
415
0
    sfbDistLdData = sfbDistBestLdData;
416
0
    while ((sfbDistLdData > (threshLdData - distFactorLdData)) && (cnt++ < 1) &&
417
0
           (scf > minScf)) {
418
0
      scf--;
419
0
      sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf,
420
0
                                            dZoneQuantEnable);
421
422
0
      if (sfbDistLdData < sfbDistBestLdData) {
423
0
        scfBest = scf;
424
0
        sfbDistBestLdData = sfbDistLdData;
425
0
        for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k];
426
0
      }
427
0
      *minScfCalculated = scf;
428
0
    }
429
0
    *distLdData = sfbDistBestLdData;
430
0
  } else { /* nmr <= 1.25 -> try to find bigger scf to use less bits */
431
0
    FIXP_DBL sfbDistBestLdData = sfbDistLdData;
432
0
    FIXP_DBL sfbDistAllowedLdData =
433
0
        fixMin(sfbDistLdData - distFactorLdData, threshLdData);
434
0
    int cnt;
435
0
    for (cnt = 0; cnt < UPCOUNT_LIMIT; cnt++) {
436
0
      scf++;
437
0
      sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf,
438
0
                                            dZoneQuantEnable);
439
440
0
      if (sfbDistLdData < sfbDistAllowedLdData) {
441
0
        *minScfCalculated = scfBest + 1;
442
0
        scfBest = scf;
443
0
        sfbDistBestLdData = sfbDistLdData;
444
0
        for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k];
445
0
      }
446
0
    }
447
0
    *distLdData = sfbDistBestLdData;
448
0
  }
449
450
  /* return best scalefactor */
451
0
  return scfBest;
452
0
}
453
454
/*
455
  Function: FDKaacEnc_assimilateSingleScf
456
457
*/
458
static void FDKaacEnc_assimilateSingleScf(
459
    const PSY_OUT_CHANNEL *psyOutChan, const QC_OUT_CHANNEL *qcOutChannel,
460
    SHORT *quantSpec, SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf,
461
    const INT *minScf, FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart,
462
    const FIXP_DBL *sfbFormFactorLdData, const FIXP_DBL *sfbNRelevantLines,
463
0
    INT *minScfCalculated, INT restartOnSuccess) {
464
0
  INT sfbLast, sfbAct, sfbNext;
465
0
  INT scfAct, *scfLast, *scfNext, scfMin, scfMax;
466
0
  INT sfbWidth, sfbOffs;
467
0
  FIXP_DBL enLdData;
468
0
  FIXP_DBL sfbPeOld, sfbPeNew;
469
0
  FIXP_DBL sfbDistNew;
470
0
  INT i, k;
471
0
  INT success = 0;
472
0
  FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
473
0
  FIXP_DBL deltaPeNew, deltaPeTmp;
474
0
  INT prevScfLast[MAX_GROUPED_SFB], prevScfNext[MAX_GROUPED_SFB];
475
0
  FIXP_DBL deltaPeLast[MAX_GROUPED_SFB];
476
0
  INT updateMinScfCalculated;
477
478
0
  for (i = 0; i < psyOutChan->sfbCnt; i++) {
479
0
    prevScfLast[i] = FDK_INT_MAX;
480
0
    prevScfNext[i] = FDK_INT_MAX;
481
0
    deltaPeLast[i] = (FIXP_DBL)FDK_INT_MAX;
482
0
  }
483
484
0
  sfbLast = -1;
485
0
  sfbAct = -1;
486
0
  sfbNext = -1;
487
0
  scfLast = 0;
488
0
  scfNext = 0;
489
0
  scfMin = FDK_INT_MAX;
490
0
  scfMax = FDK_INT_MAX;
491
0
  do {
492
    /* search for new relevant sfb */
493
0
    sfbNext++;
494
0
    while ((sfbNext < psyOutChan->sfbCnt) && (scf[sfbNext] == FDK_INT_MIN))
495
0
      sfbNext++;
496
0
    if ((sfbLast >= 0) && (sfbAct >= 0) && (sfbNext < psyOutChan->sfbCnt)) {
497
      /* relevant scfs to the left and to the right */
498
0
      scfAct = scf[sfbAct];
499
0
      scfLast = scf + sfbLast;
500
0
      scfNext = scf + sfbNext;
501
0
      scfMin = fixMin(*scfLast, *scfNext);
502
0
      scfMax = fixMax(*scfLast, *scfNext);
503
0
    } else if ((sfbLast == -1) && (sfbAct >= 0) &&
504
0
               (sfbNext < psyOutChan->sfbCnt)) {
505
      /* first relevant scf */
506
0
      scfAct = scf[sfbAct];
507
0
      scfLast = &scfAct;
508
0
      scfNext = scf + sfbNext;
509
0
      scfMin = *scfNext;
510
0
      scfMax = *scfNext;
511
0
    } else if ((sfbLast >= 0) && (sfbAct >= 0) &&
512
0
               (sfbNext == psyOutChan->sfbCnt)) {
513
      /* last relevant scf */
514
0
      scfAct = scf[sfbAct];
515
0
      scfLast = scf + sfbLast;
516
0
      scfNext = &scfAct;
517
0
      scfMin = *scfLast;
518
0
      scfMax = *scfLast;
519
0
    }
520
0
    if (sfbAct >= 0) scfMin = fixMax(scfMin, minScf[sfbAct]);
521
522
0
    if ((sfbAct >= 0) && (sfbLast >= 0 || sfbNext < psyOutChan->sfbCnt) &&
523
0
        (scfAct > scfMin) && (scfAct <= scfMin + MAX_SCF_DELTA) &&
524
0
        (scfAct >= scfMax - MAX_SCF_DELTA) &&
525
0
        (scfAct <=
526
0
         fixMin(scfMin, fixMin(*scfLast, *scfNext)) + MAX_SCF_DELTA) &&
527
0
        (*scfLast != prevScfLast[sfbAct] || *scfNext != prevScfNext[sfbAct] ||
528
0
         deltaPe < deltaPeLast[sfbAct])) {
529
      /* bigger than neighbouring scf found, try to use smaller scf */
530
0
      success = 0;
531
532
0
      sfbWidth =
533
0
          psyOutChan->sfbOffsets[sfbAct + 1] - psyOutChan->sfbOffsets[sfbAct];
534
0
      sfbOffs = psyOutChan->sfbOffsets[sfbAct];
535
536
      /* estimate required bits for actual scf */
537
0
      enLdData = qcOutChannel->sfbEnergyLdData[sfbAct];
538
539
      /* sfbConstPePart[sfbAct] = (float)log(6.75f*en/sfbFormFactor[sfbAct]) *
540
       * LOG2_1; */
541
      /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for
542
       * log2 */
543
      /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
544
0
      if (sfbConstPePart[sfbAct] == (FIXP_DBL)FDK_INT_MIN) {
545
0
        sfbConstPePart[sfbAct] = ((enLdData - sfbFormFactorLdData[sfbAct] -
546
0
                                   FL2FXCONST_DBL(0.09375f)) >>
547
0
                                  1) +
548
0
                                 FL2FXCONST_DBL(0.02152255861f);
549
0
      }
550
551
0
      sfbPeOld = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct],
552
0
                                            sfbNRelevantLines[sfbAct]) +
553
0
                 FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext);
554
555
0
      deltaPeNew = deltaPe;
556
0
      updateMinScfCalculated = 1;
557
558
0
      do {
559
        /* estimate required bits for smaller scf */
560
0
        scfAct--;
561
        /* check only if the same check was not done before */
562
0
        if (scfAct < minScfCalculated[sfbAct] &&
563
0
            scfAct >= scfMax - MAX_SCF_DELTA) {
564
          /* estimate required bits for new scf */
565
0
          sfbPeNew = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct],
566
0
                                                sfbNRelevantLines[sfbAct]) +
567
0
                     FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext);
568
569
          /* use new scf if no increase in pe and
570
             quantization error is smaller */
571
0
          deltaPeTmp = deltaPe + sfbPeNew - sfbPeOld;
572
          /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
573
0
          if (deltaPeTmp < FL2FXCONST_DBL(0.0006103515625f)) {
574
            /* distortion of new scf */
575
0
            sfbDistNew = FDKaacEnc_calcSfbDist(
576
0
                qcOutChannel->mdctSpectrum + sfbOffs, quantSpecTmp + sfbOffs,
577
0
                sfbWidth, scfAct, dZoneQuantEnable);
578
579
0
            if (sfbDistNew < sfbDist[sfbAct]) {
580
              /* success, replace scf by new one */
581
0
              scf[sfbAct] = scfAct;
582
0
              sfbDist[sfbAct] = sfbDistNew;
583
584
0
              for (k = 0; k < sfbWidth; k++)
585
0
                quantSpec[sfbOffs + k] = quantSpecTmp[sfbOffs + k];
586
587
0
              deltaPeNew = deltaPeTmp;
588
0
              success = 1;
589
0
            }
590
            /* mark as already checked */
591
0
            if (updateMinScfCalculated) minScfCalculated[sfbAct] = scfAct;
592
0
          } else {
593
            /* from this scf value on not all new values have been checked */
594
0
            updateMinScfCalculated = 0;
595
0
          }
596
0
        }
597
0
      } while (scfAct > scfMin);
598
599
0
      deltaPe = deltaPeNew;
600
601
      /* save parameters to avoid multiple computations of the same sfb */
602
0
      prevScfLast[sfbAct] = *scfLast;
603
0
      prevScfNext[sfbAct] = *scfNext;
604
0
      deltaPeLast[sfbAct] = deltaPe;
605
0
    }
606
607
0
    if (success && restartOnSuccess) {
608
      /* start again at first sfb */
609
0
      sfbLast = -1;
610
0
      sfbAct = -1;
611
0
      sfbNext = -1;
612
0
      scfLast = 0;
613
0
      scfNext = 0;
614
0
      scfMin = FDK_INT_MAX;
615
0
      scfMax = FDK_INT_MAX;
616
0
      success = 0;
617
0
    } else {
618
      /* shift sfbs for next band */
619
0
      sfbLast = sfbAct;
620
0
      sfbAct = sfbNext;
621
0
    }
622
0
  } while (sfbNext < psyOutChan->sfbCnt);
623
0
}
624
625
/*
626
  Function: FDKaacEnc_assimilateMultipleScf
627
628
*/
629
static void FDKaacEnc_assimilateMultipleScf(
630
    PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, SHORT *quantSpec,
631
    SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, const INT *minScf,
632
    FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData,
633
0
    FIXP_DBL *sfbNRelevantLines) {
634
0
  INT sfb, startSfb, stopSfb;
635
0
  INT scfTmp[MAX_GROUPED_SFB], scfMin, scfMax, scfAct;
636
0
  INT possibleRegionFound;
637
0
  INT sfbWidth, sfbOffs, i, k;
638
0
  FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], distOldSum, distNewSum;
639
0
  INT deltaScfBits;
640
0
  FIXP_DBL deltaSpecPe;
641
0
  FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
642
0
  FIXP_DBL deltaPeNew;
643
0
  INT sfbCnt = psyOutChan->sfbCnt;
644
645
  /* calc min and max scalfactors */
646
0
  scfMin = FDK_INT_MAX;
647
0
  scfMax = FDK_INT_MIN;
648
0
  for (sfb = 0; sfb < sfbCnt; sfb++) {
649
0
    if (scf[sfb] != FDK_INT_MIN) {
650
0
      scfMin = fixMin(scfMin, scf[sfb]);
651
0
      scfMax = fixMax(scfMax, scf[sfb]);
652
0
    }
653
0
  }
654
655
0
  if (scfMax != FDK_INT_MIN && scfMax <= scfMin + MAX_SCF_DELTA) {
656
0
    scfAct = scfMax;
657
658
0
    do {
659
      /* try smaller scf */
660
0
      scfAct--;
661
0
      for (i = 0; i < MAX_GROUPED_SFB; i++) scfTmp[i] = scf[i];
662
0
      stopSfb = 0;
663
0
      do {
664
        /* search for region where all scfs are bigger than scfAct */
665
0
        sfb = stopSfb;
666
0
        while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN || scf[sfb] <= scfAct))
667
0
          sfb++;
668
0
        startSfb = sfb;
669
0
        sfb++;
670
0
        while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN || scf[sfb] > scfAct))
671
0
          sfb++;
672
0
        stopSfb = sfb;
673
674
        /* check if in all sfb of a valid region scfAct >= minScf[sfb] */
675
0
        possibleRegionFound = 0;
676
0
        if (startSfb < sfbCnt) {
677
0
          possibleRegionFound = 1;
678
0
          for (sfb = startSfb; sfb < stopSfb; sfb++) {
679
0
            if (scf[sfb] != FDK_INT_MIN)
680
0
              if (scfAct < minScf[sfb]) {
681
0
                possibleRegionFound = 0;
682
0
                break;
683
0
              }
684
0
          }
685
0
        }
686
687
0
        if (possibleRegionFound) { /* region found */
688
689
          /* replace scfs in region by scfAct */
690
0
          for (sfb = startSfb; sfb < stopSfb; sfb++) {
691
0
            if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfAct;
692
0
          }
693
694
          /* estimate change in bit demand for new scfs */
695
0
          deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
696
0
                                                    startSfb, stopSfb);
697
698
0
          deltaSpecPe = FDKaacEnc_calcSpecPeDiff(
699
0
              psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
700
0
              sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb);
701
702
0
          deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
703
704
          /* new bit demand small enough ? */
705
          /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
706
0
          if (deltaPeNew < FL2FXCONST_DBL(0.0006103515625f)) {
707
            /* quantize and calc sum of new distortion */
708
0
            distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
709
0
            for (sfb = startSfb; sfb < stopSfb; sfb++) {
710
0
              if (scfTmp[sfb] != FDK_INT_MIN) {
711
0
                distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
712
713
0
                sfbWidth = psyOutChan->sfbOffsets[sfb + 1] -
714
0
                           psyOutChan->sfbOffsets[sfb];
715
0
                sfbOffs = psyOutChan->sfbOffsets[sfb];
716
717
0
                sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(
718
0
                    qcOutChannel->mdctSpectrum + sfbOffs,
719
0
                    quantSpecTmp + sfbOffs, sfbWidth, scfAct, dZoneQuantEnable);
720
721
0
                if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) {
722
                  /* no improvement, skip further dist. calculations */
723
0
                  distNewSum = distOldSum << 1;
724
0
                  break;
725
0
                }
726
0
                distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
727
0
              }
728
0
            }
729
            /* distortion smaller ? -> use new scalefactors */
730
0
            if (distNewSum < distOldSum) {
731
0
              deltaPe = deltaPeNew;
732
0
              for (sfb = startSfb; sfb < stopSfb; sfb++) {
733
0
                if (scf[sfb] != FDK_INT_MIN) {
734
0
                  sfbWidth = psyOutChan->sfbOffsets[sfb + 1] -
735
0
                             psyOutChan->sfbOffsets[sfb];
736
0
                  sfbOffs = psyOutChan->sfbOffsets[sfb];
737
0
                  scf[sfb] = scfAct;
738
0
                  sfbDist[sfb] = sfbDistNew[sfb];
739
740
0
                  for (k = 0; k < sfbWidth; k++)
741
0
                    quantSpec[sfbOffs + k] = quantSpecTmp[sfbOffs + k];
742
0
                }
743
0
              }
744
0
            }
745
0
          }
746
0
        }
747
748
0
      } while (stopSfb <= sfbCnt);
749
750
0
    } while (scfAct > scfMin);
751
0
  }
752
0
}
753
754
/*
755
  Function: FDKaacEnc_FDKaacEnc_assimilateMultipleScf2
756
757
*/
758
static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(
759
    PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, SHORT *quantSpec,
760
    SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, const INT *minScf,
761
    FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData,
762
0
    FIXP_DBL *sfbNRelevantLines) {
763
0
  INT sfb, startSfb, stopSfb;
764
0
  INT scfTmp[MAX_GROUPED_SFB], scfAct, scfNew;
765
0
  INT scfPrev, scfNext, scfPrevNextMin, scfPrevNextMax, scfLo, scfHi;
766
0
  INT scfMin, scfMax;
767
0
  INT *sfbOffs = psyOutChan->sfbOffsets;
768
0
  FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], sfbDistMax[MAX_GROUPED_SFB];
769
0
  FIXP_DBL distOldSum, distNewSum;
770
0
  INT deltaScfBits;
771
0
  FIXP_DBL deltaSpecPe;
772
0
  FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
773
0
  FIXP_DBL deltaPeNew = FL2FXCONST_DBL(0.0f);
774
0
  INT sfbCnt = psyOutChan->sfbCnt;
775
0
  INT bSuccess, bCheckScf;
776
0
  INT i, k;
777
778
  /* calc min and max scalfactors */
779
0
  scfMin = FDK_INT_MAX;
780
0
  scfMax = FDK_INT_MIN;
781
0
  for (sfb = 0; sfb < sfbCnt; sfb++) {
782
0
    if (scf[sfb] != FDK_INT_MIN) {
783
0
      scfMin = fixMin(scfMin, scf[sfb]);
784
0
      scfMax = fixMax(scfMax, scf[sfb]);
785
0
    }
786
0
  }
787
788
0
  stopSfb = 0;
789
0
  scfAct = FDK_INT_MIN;
790
0
  do {
791
    /* search for region with same scf values scfAct */
792
0
    scfPrev = scfAct;
793
794
0
    sfb = stopSfb;
795
0
    while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN)) sfb++;
796
0
    startSfb = sfb;
797
0
    scfAct = scf[startSfb];
798
0
    sfb++;
799
0
    while (sfb < sfbCnt &&
800
0
           ((scf[sfb] == FDK_INT_MIN) || (scf[sfb] == scf[startSfb])))
801
0
      sfb++;
802
0
    stopSfb = sfb;
803
804
0
    if (stopSfb < sfbCnt)
805
0
      scfNext = scf[stopSfb];
806
0
    else
807
0
      scfNext = scfAct;
808
809
0
    if (scfPrev == FDK_INT_MIN) scfPrev = scfAct;
810
811
0
    scfPrevNextMax = fixMax(scfPrev, scfNext);
812
0
    scfPrevNextMin = fixMin(scfPrev, scfNext);
813
814
    /* try to reduce bits by checking scf values in the range
815
       scf[startSfb]...scfHi */
816
0
    scfHi = fixMax(scfPrevNextMax, scfAct);
817
    /* try to find a better solution by reducing the scf difference to
818
       the nearest possible lower scf */
819
0
    if (scfPrevNextMax >= scfAct)
820
0
      scfLo = fixMin(scfAct, scfPrevNextMin);
821
0
    else
822
0
      scfLo = scfPrevNextMax;
823
824
0
    if (startSfb < sfbCnt &&
825
0
        scfHi - scfLo <= MAX_SCF_DELTA) { /* region found */
826
      /* 1. try to save bits by coarser quantization */
827
0
      if (scfHi > scf[startSfb]) {
828
        /* calculate the allowed distortion */
829
0
        for (sfb = startSfb; sfb < stopSfb; sfb++) {
830
0
          if (scf[sfb] != FDK_INT_MIN) {
831
            /* sfbDistMax[sfb] =
832
             * (float)pow(qcOutChannel->sfbThreshold[sfb]*sfbDist[sfb]*sfbDist[sfb],1.0f/3.0f);
833
             */
834
            /* sfbDistMax[sfb] =
835
             * fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergy[sfb]*FL2FXCONST_DBL(1.e-3f));
836
             */
837
            /* -0.15571537944 = ld64(1.e-3f)*/
838
0
            sfbDistMax[sfb] = fMult(FL2FXCONST_DBL(1.0f / 3.0f),
839
0
                                    qcOutChannel->sfbThresholdLdData[sfb]) +
840
0
                              fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]) +
841
0
                              fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]);
842
0
            sfbDistMax[sfb] =
843
0
                fixMax(sfbDistMax[sfb], qcOutChannel->sfbEnergyLdData[sfb] -
844
0
                                            FL2FXCONST_DBL(0.15571537944));
845
0
            sfbDistMax[sfb] =
846
0
                fixMin(sfbDistMax[sfb], qcOutChannel->sfbThresholdLdData[sfb]);
847
0
          }
848
0
        }
849
850
        /* loop over all possible scf values for this region */
851
0
        bCheckScf = 1;
852
0
        for (scfNew = scf[startSfb] + 1; scfNew <= scfHi; scfNew++) {
853
0
          for (k = 0; k < MAX_GROUPED_SFB; k++) scfTmp[k] = scf[k];
854
855
          /* replace scfs in region by scfNew */
856
0
          for (sfb = startSfb; sfb < stopSfb; sfb++) {
857
0
            if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfNew;
858
0
          }
859
860
          /* estimate change in bit demand for new scfs */
861
0
          deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
862
0
                                                    startSfb, stopSfb);
863
864
0
          deltaSpecPe = FDKaacEnc_calcSpecPeDiff(
865
0
              psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
866
0
              sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb);
867
868
0
          deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
869
870
          /* new bit demand small enough ? */
871
0
          if (deltaPeNew < FL2FXCONST_DBL(0.0f)) {
872
0
            bSuccess = 1;
873
874
            /* quantize and calc sum of new distortion */
875
0
            for (sfb = startSfb; sfb < stopSfb; sfb++) {
876
0
              if (scfTmp[sfb] != FDK_INT_MIN) {
877
0
                sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(
878
0
                    qcOutChannel->mdctSpectrum + sfbOffs[sfb],
879
0
                    quantSpecTmp + sfbOffs[sfb],
880
0
                    sfbOffs[sfb + 1] - sfbOffs[sfb], scfNew, dZoneQuantEnable);
881
882
0
                if (sfbDistNew[sfb] > sfbDistMax[sfb]) {
883
                  /* no improvement, skip further dist. calculations */
884
0
                  bSuccess = 0;
885
0
                  if (sfbDistNew[sfb] == qcOutChannel->sfbEnergyLdData[sfb]) {
886
                    /* if whole sfb is already quantized to 0, further
887
                       checks with even coarser quant. are useless*/
888
0
                    bCheckScf = 0;
889
0
                  }
890
0
                  break;
891
0
                }
892
0
              }
893
0
            }
894
0
            if (bCheckScf == 0) /* further calculations useless ? */
895
0
              break;
896
            /* distortion small enough ? -> use new scalefactors */
897
0
            if (bSuccess) {
898
0
              deltaPe = deltaPeNew;
899
0
              for (sfb = startSfb; sfb < stopSfb; sfb++) {
900
0
                if (scf[sfb] != FDK_INT_MIN) {
901
0
                  scf[sfb] = scfNew;
902
0
                  sfbDist[sfb] = sfbDistNew[sfb];
903
904
0
                  for (k = 0; k < sfbOffs[sfb + 1] - sfbOffs[sfb]; k++)
905
0
                    quantSpec[sfbOffs[sfb] + k] =
906
0
                        quantSpecTmp[sfbOffs[sfb] + k];
907
0
                }
908
0
              }
909
0
            }
910
0
          }
911
0
        }
912
0
      }
913
914
      /* 2. only if coarser quantization was not successful, try to find
915
         a better solution by finer quantization and reducing bits for
916
         scalefactor coding */
917
0
      if (scfAct == scf[startSfb] && scfLo < scfAct &&
918
0
          scfMax - scfMin <= MAX_SCF_DELTA) {
919
0
        int bminScfViolation = 0;
920
921
0
        for (k = 0; k < MAX_GROUPED_SFB; k++) scfTmp[k] = scf[k];
922
923
0
        scfNew = scfLo;
924
925
        /* replace scfs in region by scfNew and
926
           check if in all sfb scfNew >= minScf[sfb] */
927
0
        for (sfb = startSfb; sfb < stopSfb; sfb++) {
928
0
          if (scfTmp[sfb] != FDK_INT_MIN) {
929
0
            scfTmp[sfb] = scfNew;
930
0
            if (scfNew < minScf[sfb]) bminScfViolation = 1;
931
0
          }
932
0
        }
933
934
0
        if (!bminScfViolation) {
935
          /* estimate change in bit demand for new scfs */
936
0
          deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
937
0
                                                    startSfb, stopSfb);
938
939
0
          deltaSpecPe = FDKaacEnc_calcSpecPeDiff(
940
0
              psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
941
0
              sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb);
942
943
0
          deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
944
0
        }
945
946
        /* new bit demand small enough ? */
947
0
        if (!bminScfViolation && deltaPeNew < FL2FXCONST_DBL(0.0f)) {
948
          /* quantize and calc sum of new distortion */
949
0
          distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
950
0
          for (sfb = startSfb; sfb < stopSfb; sfb++) {
951
0
            if (scfTmp[sfb] != FDK_INT_MIN) {
952
0
              distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
953
954
0
              sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(
955
0
                  qcOutChannel->mdctSpectrum + sfbOffs[sfb],
956
0
                  quantSpecTmp + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb],
957
0
                  scfNew, dZoneQuantEnable);
958
959
0
              if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) {
960
                /* no improvement, skip further dist. calculations */
961
0
                distNewSum = distOldSum << 1;
962
0
                break;
963
0
              }
964
0
              distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
965
0
            }
966
0
          }
967
          /* distortion smaller ? -> use new scalefactors */
968
0
          if (distNewSum < fMult(FL2FXCONST_DBL(0.8f), distOldSum)) {
969
0
            deltaPe = deltaPeNew;
970
0
            for (sfb = startSfb; sfb < stopSfb; sfb++) {
971
0
              if (scf[sfb] != FDK_INT_MIN) {
972
0
                scf[sfb] = scfNew;
973
0
                sfbDist[sfb] = sfbDistNew[sfb];
974
975
0
                for (k = 0; k < sfbOffs[sfb + 1] - sfbOffs[sfb]; k++)
976
0
                  quantSpec[sfbOffs[sfb] + k] = quantSpecTmp[sfbOffs[sfb] + k];
977
0
              }
978
0
            }
979
0
          }
980
0
        }
981
0
      }
982
983
      /* 3. try to find a better solution (save bits) by only reducing the
984
         scalefactor without new quantization */
985
0
      if (scfMax - scfMin <=
986
0
          MAX_SCF_DELTA - 3) { /* 3 bec. scf is reduced 3 times,
987
                                  see for loop below */
988
989
0
        for (k = 0; k < sfbCnt; k++) scfTmp[k] = scf[k];
990
991
0
        for (i = 0; i < 3; i++) {
992
0
          scfNew = scfTmp[startSfb] - 1;
993
          /* replace scfs in region by scfNew */
994
0
          for (sfb = startSfb; sfb < stopSfb; sfb++) {
995
0
            if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfNew;
996
0
          }
997
          /* estimate change in bit demand for new scfs */
998
0
          deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
999
0
                                                    startSfb, stopSfb);
1000
0
          deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits;
1001
          /* new bit demand small enough ? */
1002
0
          if (deltaPeNew <= FL2FXCONST_DBL(0.0f)) {
1003
0
            bSuccess = 1;
1004
0
            distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
1005
0
            for (sfb = startSfb; sfb < stopSfb; sfb++) {
1006
0
              if (scfTmp[sfb] != FDK_INT_MIN) {
1007
0
                FIXP_DBL sfbEnQ;
1008
                /* calc the energy and distortion of the quantized spectrum for
1009
                   a smaller scf */
1010
0
                FDKaacEnc_calcSfbQuantEnergyAndDist(
1011
0
                    qcOutChannel->mdctSpectrum + sfbOffs[sfb],
1012
0
                    quantSpec + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb],
1013
0
                    scfNew, &sfbEnQ, &sfbDistNew[sfb]);
1014
1015
0
                distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
1016
0
                distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
1017
1018
                /*  0.00259488556167 = ld64(1.122f) */
1019
                /* -0.00778722686652 = ld64(0.7079f) */
1020
0
                if ((sfbDistNew[sfb] >
1021
0
                     (sfbDist[sfb] + FL2FXCONST_DBL(0.00259488556167f))) ||
1022
0
                    (sfbEnQ < (qcOutChannel->sfbEnergyLdData[sfb] -
1023
0
                               FL2FXCONST_DBL(0.00778722686652f)))) {
1024
0
                  bSuccess = 0;
1025
0
                  break;
1026
0
                }
1027
0
              }
1028
0
            }
1029
            /* distortion smaller ? -> use new scalefactors */
1030
0
            if (distNewSum < distOldSum && bSuccess) {
1031
0
              deltaPe = deltaPeNew;
1032
0
              for (sfb = startSfb; sfb < stopSfb; sfb++) {
1033
0
                if (scf[sfb] != FDK_INT_MIN) {
1034
0
                  scf[sfb] = scfNew;
1035
0
                  sfbDist[sfb] = sfbDistNew[sfb];
1036
0
                }
1037
0
              }
1038
0
            }
1039
0
          }
1040
0
        }
1041
0
      }
1042
0
    }
1043
0
  } while (stopSfb <= sfbCnt);
1044
0
}
1045
1046
static void FDKaacEnc_EstimateScaleFactorsChannel(
1047
    QC_OUT_CHANNEL *qcOutChannel, PSY_OUT_CHANNEL *psyOutChannel,
1048
    INT *RESTRICT scf, INT *RESTRICT globalGain,
1049
    FIXP_DBL *RESTRICT sfbFormFactorLdData, const INT invQuant,
1050
0
    SHORT *RESTRICT quantSpec, const INT dZoneQuantEnable) {
1051
0
  INT i, j, sfb, sfbOffs;
1052
0
  INT scfInt;
1053
0
  INT maxSf;
1054
0
  INT minSf;
1055
0
  FIXP_DBL threshLdData;
1056
0
  FIXP_DBL energyLdData;
1057
0
  FIXP_DBL energyPartLdData;
1058
0
  FIXP_DBL thresholdPartLdData;
1059
0
  FIXP_DBL scfFract;
1060
0
  FIXP_DBL maxSpec;
1061
0
  INT minScfCalculated[MAX_GROUPED_SFB];
1062
0
  FIXP_DBL sfbDistLdData[MAX_GROUPED_SFB];
1063
0
  C_ALLOC_SCRATCH_START(quantSpecTmp, SHORT, (1024))
1064
0
  INT minSfMaxQuant[MAX_GROUPED_SFB];
1065
1066
0
  FIXP_DBL threshConstLdData =
1067
0
      FL2FXCONST_DBL(0.04304511722f); /* log10(6.75)/log10(2.0)/64.0 */
1068
0
  FIXP_DBL convConst = FL2FXCONST_DBL(0.30102999566f); /* log10(2.0) */
1069
0
  FIXP_DBL c1Const =
1070
0
      FL2FXCONST_DBL(-0.27083183594f); /* C1 = -69.33295 => C1/2^8 */
1071
1072
0
  if (invQuant > 0) {
1073
0
    FDKmemclear(quantSpec, (1024) * sizeof(SHORT));
1074
0
  }
1075
1076
  /* scfs without energy or with thresh>energy are marked with FDK_INT_MIN */
1077
0
  for (i = 0; i < psyOutChannel->sfbCnt; i++) {
1078
0
    scf[i] = FDK_INT_MIN;
1079
0
  }
1080
1081
0
  for (i = 0; i < MAX_GROUPED_SFB; i++) {
1082
0
    minSfMaxQuant[i] = FDK_INT_MIN;
1083
0
  }
1084
1085
0
  for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
1086
0
       sfbOffs += psyOutChannel->sfbPerGroup) {
1087
0
    for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1088
0
      threshLdData = qcOutChannel->sfbThresholdLdData[sfbOffs + sfb];
1089
0
      energyLdData = qcOutChannel->sfbEnergyLdData[sfbOffs + sfb];
1090
1091
0
      sfbDistLdData[sfbOffs + sfb] = energyLdData;
1092
1093
0
      if (energyLdData > threshLdData) {
1094
0
        FIXP_DBL tmp;
1095
1096
        /* energyPart = (float)log10(sfbFormFactor[sfbOffs+sfb]); */
1097
        /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
1098
0
        energyPartLdData =
1099
0
            sfbFormFactorLdData[sfbOffs + sfb] + FL2FXCONST_DBL(0.09375f);
1100
1101
        /* influence of allowed distortion */
1102
        /* thresholdPart = (float)log10(6.75*thresh+FLT_MIN); */
1103
0
        thresholdPartLdData = threshConstLdData + threshLdData;
1104
1105
        /* scf calc */
1106
        /* scfFloat = 8.8585f * (thresholdPart - energyPart); */
1107
0
        scfFract = thresholdPartLdData - energyPartLdData;
1108
        /* conversion from log2 to log10 */
1109
0
        scfFract = fMult(convConst, scfFract);
1110
        /* (8.8585f * scfFract)/8 = 8/8 * scfFract + 0.8585 * scfFract/8 */
1111
0
        scfFract = scfFract + fMult(FL2FXCONST_DBL(0.8585f), scfFract >> 3);
1112
1113
        /* integer scalefactor */
1114
        /* scfInt = (int)floor(scfFloat); */
1115
0
        scfInt =
1116
0
            (INT)(scfFract >>
1117
0
                  ((DFRACT_BITS - 1) - 3 -
1118
0
                   LD_DATA_SHIFT)); /* 3 bits => scfFract/8.0; 6 bits => ld64 */
1119
1120
        /* maximum of spectrum */
1121
0
        maxSpec = FL2FXCONST_DBL(0.0f);
1122
1123
        /* Unroll by 4, allow dual memory access */
1124
0
        DWORD_ALIGNED(qcOutChannel->mdctSpectrum);
1125
0
        for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb];
1126
0
             j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j += 4) {
1127
0
          maxSpec = fMax(maxSpec,
1128
0
                         fMax(fMax(fAbs(qcOutChannel->mdctSpectrum[j + 0]),
1129
0
                                   fAbs(qcOutChannel->mdctSpectrum[j + 1])),
1130
0
                              fMax(fAbs(qcOutChannel->mdctSpectrum[j + 2]),
1131
0
                                   fAbs(qcOutChannel->mdctSpectrum[j + 3]))));
1132
0
        }
1133
        /* lower scf limit to avoid quantized values bigger than MAX_QUANT */
1134
        /* C1 = -69.33295f, C2 = 5.77078f = 4/log(2) */
1135
        /* minSfMaxQuant[sfbOffs+sfb] = (int)ceil(C1 + C2*log(maxSpec)); */
1136
        /* C1/2^8 + 4/log(2.0)*log(maxSpec)/2^8  => C1/2^8 +
1137
         * log(maxSpec)/log(2.0)*4/2^8 => C1/2^8 + log(maxSpec)/log(2.0)/64.0 */
1138
1139
        // minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + CalcLdData(maxSpec))
1140
        // >> ((DFRACT_BITS-1)-8))) + 1;
1141
0
        tmp = CalcLdData(maxSpec);
1142
0
        if (c1Const > FL2FXCONST_DBL(-1.f) - tmp) {
1143
0
          minSfMaxQuant[sfbOffs + sfb] =
1144
0
              ((INT)((c1Const + tmp) >> ((DFRACT_BITS - 1) - 8))) + 1;
1145
0
        } else {
1146
0
          minSfMaxQuant[sfbOffs + sfb] =
1147
0
              ((INT)(FL2FXCONST_DBL(-1.f) >> ((DFRACT_BITS - 1) - 8))) + 1;
1148
0
        }
1149
1150
0
        scfInt = fixMax(scfInt, minSfMaxQuant[sfbOffs + sfb]);
1151
1152
        /* find better scalefactor with analysis by synthesis */
1153
0
        if (invQuant > 0) {
1154
0
          scfInt = FDKaacEnc_improveScf(
1155
0
              qcOutChannel->mdctSpectrum +
1156
0
                  psyOutChannel->sfbOffsets[sfbOffs + sfb],
1157
0
              quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb],
1158
0
              quantSpecTmp + psyOutChannel->sfbOffsets[sfbOffs + sfb],
1159
0
              psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] -
1160
0
                  psyOutChannel->sfbOffsets[sfbOffs + sfb],
1161
0
              threshLdData, scfInt, minSfMaxQuant[sfbOffs + sfb],
1162
0
              &sfbDistLdData[sfbOffs + sfb], &minScfCalculated[sfbOffs + sfb],
1163
0
              dZoneQuantEnable);
1164
0
        }
1165
0
        scf[sfbOffs + sfb] = scfInt;
1166
0
      }
1167
0
    }
1168
0
  }
1169
1170
0
  if (invQuant > 0) {
1171
    /* try to decrease scf differences */
1172
0
    FIXP_DBL sfbConstPePart[MAX_GROUPED_SFB];
1173
0
    FIXP_DBL sfbNRelevantLines[MAX_GROUPED_SFB];
1174
1175
0
    for (i = 0; i < psyOutChannel->sfbCnt; i++)
1176
0
      sfbConstPePart[i] = (FIXP_DBL)FDK_INT_MIN;
1177
1178
0
    FDKaacEnc_calcSfbRelevantLines(
1179
0
        sfbFormFactorLdData, qcOutChannel->sfbEnergyLdData,
1180
0
        qcOutChannel->sfbThresholdLdData, psyOutChannel->sfbOffsets,
1181
0
        psyOutChannel->sfbCnt, psyOutChannel->sfbPerGroup,
1182
0
        psyOutChannel->maxSfbPerGroup, sfbNRelevantLines);
1183
1184
0
    FDKaacEnc_assimilateSingleScf(
1185
0
        psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, dZoneQuantEnable,
1186
0
        scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart, sfbFormFactorLdData,
1187
0
        sfbNRelevantLines, minScfCalculated, 1);
1188
1189
0
    if (invQuant > 1) {
1190
0
      FDKaacEnc_assimilateMultipleScf(
1191
0
          psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
1192
0
          dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart,
1193
0
          sfbFormFactorLdData, sfbNRelevantLines);
1194
1195
0
      FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(
1196
0
          psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
1197
0
          dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart,
1198
0
          sfbFormFactorLdData, sfbNRelevantLines);
1199
0
    }
1200
0
  }
1201
1202
  /* get min scalefac */
1203
0
  minSf = FDK_INT_MAX;
1204
0
  for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
1205
0
       sfbOffs += psyOutChannel->sfbPerGroup) {
1206
0
    for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1207
0
      if (scf[sfbOffs + sfb] != FDK_INT_MIN)
1208
0
        minSf = fixMin(minSf, scf[sfbOffs + sfb]);
1209
0
    }
1210
0
  }
1211
1212
  /* limit scf delta */
1213
0
  for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
1214
0
       sfbOffs += psyOutChannel->sfbPerGroup) {
1215
0
    for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1216
0
      if ((scf[sfbOffs + sfb] != FDK_INT_MIN) &&
1217
0
          (minSf + MAX_SCF_DELTA) < scf[sfbOffs + sfb]) {
1218
0
        scf[sfbOffs + sfb] = minSf + MAX_SCF_DELTA;
1219
0
        if (invQuant > 0) { /* changed bands need to be quantized again */
1220
0
          sfbDistLdData[sfbOffs + sfb] = FDKaacEnc_calcSfbDist(
1221
0
              qcOutChannel->mdctSpectrum +
1222
0
                  psyOutChannel->sfbOffsets[sfbOffs + sfb],
1223
0
              quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb],
1224
0
              psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] -
1225
0
                  psyOutChannel->sfbOffsets[sfbOffs + sfb],
1226
0
              scf[sfbOffs + sfb], dZoneQuantEnable);
1227
0
        }
1228
0
      }
1229
0
    }
1230
0
  }
1231
1232
  /* get max scalefac for global gain */
1233
0
  maxSf = FDK_INT_MIN;
1234
0
  for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
1235
0
       sfbOffs += psyOutChannel->sfbPerGroup) {
1236
0
    for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1237
0
      maxSf = fixMax(maxSf, scf[sfbOffs + sfb]);
1238
0
    }
1239
0
  }
1240
1241
  /* calc loop scalefactors, if spec is not all zero (i.e. maxSf == -99) */
1242
0
  if (maxSf > FDK_INT_MIN) {
1243
0
    *globalGain = maxSf;
1244
0
    for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
1245
0
         sfbOffs += psyOutChannel->sfbPerGroup) {
1246
0
      for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1247
0
        if (scf[sfbOffs + sfb] == FDK_INT_MIN) {
1248
0
          scf[sfbOffs + sfb] = 0;
1249
          /* set band explicitely to zero */
1250
0
          for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb];
1251
0
               j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) {
1252
0
            qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f);
1253
0
          }
1254
0
        } else {
1255
0
          scf[sfbOffs + sfb] = maxSf - scf[sfbOffs + sfb];
1256
0
        }
1257
0
      }
1258
0
    }
1259
0
  } else {
1260
0
    *globalGain = 0;
1261
    /* set spectrum explicitely to zero */
1262
0
    for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
1263
0
         sfbOffs += psyOutChannel->sfbPerGroup) {
1264
0
      for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1265
0
        scf[sfbOffs + sfb] = 0;
1266
        /* set band explicitely to zero */
1267
0
        for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb];
1268
0
             j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) {
1269
0
          qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f);
1270
0
        }
1271
0
      }
1272
0
    }
1273
0
  }
1274
1275
  /* free quantSpecTmp from scratch */
1276
0
  C_ALLOC_SCRATCH_END(quantSpecTmp, SHORT, (1024))
1277
0
}
1278
1279
void FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
1280
                                    QC_OUT_CHANNEL *qcOutChannel[],
1281
                                    const INT invQuant,
1282
                                    const INT dZoneQuantEnable,
1283
0
                                    const INT nChannels) {
1284
0
  int ch;
1285
1286
0
  for (ch = 0; ch < nChannels; ch++) {
1287
0
    FDKaacEnc_EstimateScaleFactorsChannel(
1288
0
        qcOutChannel[ch], psyOutChannel[ch], qcOutChannel[ch]->scf,
1289
0
        &qcOutChannel[ch]->globalGain, qcOutChannel[ch]->sfbFormFactorLdData,
1290
0
        invQuant, qcOutChannel[ch]->quantSpec, dZoneQuantEnable);
1291
0
  }
1292
0
}