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