1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4 
5 � Copyright  1995 - 2015 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6   All rights reserved.
7 
8  1.    INTRODUCTION
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17 
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24 
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28 
29 2.    COPYRIGHT LICENSE
30 
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33 
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36 
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41 
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44 
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47 
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52 
53 3.    NO PATENT LICENSE
54 
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58 
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61 
62 4.    DISCLAIMER
63 
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72 
73 5.    CONTACT INFORMATION
74 
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79 
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
83 
84 /******************************** MPEG Audio Encoder **************************
85 
86    Initial author:       M. Werner
87    contents/description: Scale factor estimation
88 
89 ******************************************************************************/
90 
91 #include "sf_estim.h"
92 #include "aacEnc_rom.h"
93 #include "quantize.h"
94 #include "bit_cnt.h"
95 
96 
97 
98 
99 #define AS_PE_FAC_SHIFT 7
100 #define DIST_FAC_SHIFT  3
101 #define AS_PE_FAC_FLOAT (float)(1 << AS_PE_FAC_SHIFT)
102 static const INT MAX_SCF_DELTA = 60;
103 
104 
105 static const FIXP_DBL PE_C1 = FL2FXCONST_DBL(3.0f/AS_PE_FAC_FLOAT);          /* (log(8.0)/log(2)) >> AS_PE_FAC_SHIFT */
106 static const FIXP_DBL PE_C2 = FL2FXCONST_DBL(1.3219281f/AS_PE_FAC_FLOAT);    /* (log(2.5)/log(2)) >> AS_PE_FAC_SHIFT */
107 static const FIXP_DBL PE_C3 = FL2FXCONST_DBL(0.5593573f);                    /* 1-C2/C1 */
108 
109 
110 /*
111   Function; FDKaacEnc_FDKaacEnc_CalcFormFactorChannel
112 
113   Description: Calculates the formfactor
114 
115   sf: scale factor of the mdct spectrum
116   sfbFormFactorLdData is scaled with the factor 1/(((2^sf)^0.5) * (2^FORM_FAC_SHIFT))
117 */
118 static void
FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(FIXP_DBL * RESTRICT sfbFormFactorLdData,PSY_OUT_CHANNEL * RESTRICT psyOutChan)119 FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(FIXP_DBL *RESTRICT sfbFormFactorLdData,
120                       PSY_OUT_CHANNEL *RESTRICT psyOutChan)
121 {
122   INT j, sfb, sfbGrp;
123   FIXP_DBL formFactor;
124 
125   int tmp0 = psyOutChan->sfbCnt;
126   int tmp1 = psyOutChan->maxSfbPerGroup;
127   int step = psyOutChan->sfbPerGroup;
128   for(sfbGrp = 0; sfbGrp < tmp0; sfbGrp += step) {
129     for (sfb = 0; sfb < tmp1; sfb++) {
130       formFactor = FL2FXCONST_DBL(0.0f);
131       /* calc sum of sqrt(spec) */
132       for(j=psyOutChan->sfbOffsets[sfbGrp+sfb]; j<psyOutChan->sfbOffsets[sfbGrp+sfb+1]; j++ ) {
133          formFactor += sqrtFixp(fixp_abs(psyOutChan->mdctSpectrum[j]))>>FORM_FAC_SHIFT;
134       }
135       sfbFormFactorLdData[sfbGrp+sfb] = CalcLdData(formFactor);
136     }
137     /* set sfbFormFactor for sfbs with zero spec to zero. Just for debugging. */
138     for ( ; sfb < psyOutChan->sfbPerGroup; sfb++) {
139       sfbFormFactorLdData[sfbGrp+sfb] = FL2FXCONST_DBL(-1.0f);
140     }
141   }
142 }
143 
144 /*
145   Function: FDKaacEnc_CalcFormFactor
146 
147   Description: Calls FDKaacEnc_FDKaacEnc_CalcFormFactorChannel() for each channel
148 */
149 
150 void
FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL * qcOutChannel[(2)],PSY_OUT_CHANNEL * psyOutChannel[(2)],const INT nChannels)151 FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL   *qcOutChannel[(2)],
152                PSY_OUT_CHANNEL  *psyOutChannel[(2)],
153                const INT        nChannels)
154 {
155   INT j;
156   for (j=0; j<nChannels; j++) {
157     FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(qcOutChannel[j]->sfbFormFactorLdData, psyOutChannel[j]);
158   }
159 }
160 
161 /*
162   Function: FDKaacEnc_calcSfbRelevantLines
163 
164   Description: Calculates sfbNRelevantLines
165 
166   sfbNRelevantLines is scaled with the factor 1/((2^FORM_FAC_SHIFT) * 2.0)
167 */
168 static void
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)169 FDKaacEnc_calcSfbRelevantLines( const FIXP_DBL *const sfbFormFactorLdData,
170                       const FIXP_DBL *const sfbEnergyLdData,
171                       const FIXP_DBL *const sfbThresholdLdData,
172                       const INT *const sfbOffsets,
173                       const INT sfbCnt,
174                       const INT sfbPerGroup,
175                       const INT maxSfbPerGroup,
176                       FIXP_DBL *sfbNRelevantLines)
177 {
178   INT sfbOffs, sfb;
179   FIXP_DBL sfbWidthLdData;
180   FIXP_DBL asPeFacLdData = FL2FXCONST_DBL(0.109375);   /* AS_PE_FAC_SHIFT*ld64(2) */
181   FIXP_DBL accu;
182 
183   /* sfbNRelevantLines[i] = 2^( (sfbFormFactorLdData[i] - 0.25 * (sfbEnergyLdData[i] - ld64(sfbWidth[i]/(2^7)) - AS_PE_FAC_SHIFT*ld64(2)) * 64); */
184 
185   FDKmemclear(sfbNRelevantLines, sfbCnt * sizeof(FIXP_DBL));
186 
187   for (sfbOffs=0; sfbOffs<sfbCnt; sfbOffs+=sfbPerGroup) {
188     for(sfb=0; sfb<maxSfbPerGroup; sfb++) {
189       /* calc sum of sqrt(spec) */
190       if((FIXP_DBL)sfbEnergyLdData[sfbOffs+sfb] > (FIXP_DBL)sfbThresholdLdData[sfbOffs+sfb]) {
191         INT sfbWidth = sfbOffsets[sfbOffs+sfb+1] - sfbOffsets[sfbOffs+sfb];
192 
193         /* avgFormFactorLdData = sqrtFixp(sqrtFixp(sfbEnergyLdData[sfbOffs+sfb]/sfbWidth)); */
194         /* sfbNRelevantLines[sfbOffs+sfb] = sfbFormFactor[sfbOffs+sfb] / avgFormFactorLdData; */
195         sfbWidthLdData = (FIXP_DBL)(sfbWidth << (DFRACT_BITS-1-AS_PE_FAC_SHIFT));
196         sfbWidthLdData = CalcLdData(sfbWidthLdData);
197 
198         accu = sfbEnergyLdData[sfbOffs+sfb] - sfbWidthLdData - asPeFacLdData;
199         accu = sfbFormFactorLdData[sfbOffs+sfb] - (accu >> 2);
200 
201         sfbNRelevantLines[sfbOffs+sfb] = CalcInvLdData(accu) >> 1;
202       }
203     }
204   }
205 }
206 
207 /*
208   Function: FDKaacEnc_countSingleScfBits
209 
210   Description:
211 
212   scfBitsFract is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
213 */
FDKaacEnc_countSingleScfBits(INT scf,INT scfLeft,INT scfRight)214 static FIXP_DBL FDKaacEnc_countSingleScfBits(INT scf, INT scfLeft, INT scfRight)
215 {
216   FIXP_DBL scfBitsFract;
217 
218   scfBitsFract = (FIXP_DBL) (  FDKaacEnc_bitCountScalefactorDelta(scfLeft-scf)
219                              + FDKaacEnc_bitCountScalefactorDelta(scf-scfRight) );
220 
221   scfBitsFract = scfBitsFract << (DFRACT_BITS-1-(2*AS_PE_FAC_SHIFT));
222 
223   return scfBitsFract; /* output scaled by 1/(2^(2*AS_PE_FAC)) */
224 }
225 
226 /*
227   Function: FDKaacEnc_calcSingleSpecPe
228 
229   specPe is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
230 */
FDKaacEnc_calcSingleSpecPe(INT scf,FIXP_DBL sfbConstPePart,FIXP_DBL nLines)231 static FIXP_DBL FDKaacEnc_calcSingleSpecPe(INT scf, FIXP_DBL sfbConstPePart, FIXP_DBL nLines)
232 {
233   FIXP_DBL specPe = FL2FXCONST_DBL(0.0f);
234   FIXP_DBL ldRatio;
235   FIXP_DBL scfFract;
236 
237   scfFract = (FIXP_DBL)(scf << (DFRACT_BITS-1-AS_PE_FAC_SHIFT));
238 
239   ldRatio = sfbConstPePart - fMult(FL2FXCONST_DBL(0.375f),scfFract);
240 
241   if (ldRatio >= PE_C1) {
242     specPe = fMult(FL2FXCONST_DBL(0.7f),fMult(nLines,ldRatio));
243   }
244   else {
245     specPe = fMult(FL2FXCONST_DBL(0.7f),fMult(nLines,(PE_C2 + fMult(PE_C3,ldRatio))));
246   }
247 
248   return specPe; /* output scaled by 1/(2^(2*AS_PE_FAC)) */
249 }
250 
251 /*
252   Function: FDKaacEnc_countScfBitsDiff
253 
254   scfBitsDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
255 */
FDKaacEnc_countScfBitsDiff(INT * scfOld,INT * scfNew,INT sfbCnt,INT startSfb,INT stopSfb)256 static FIXP_DBL FDKaacEnc_countScfBitsDiff(INT *scfOld,
257                                  INT *scfNew,
258                                  INT sfbCnt,
259                                  INT startSfb,
260                                  INT stopSfb)
261 {
262   FIXP_DBL scfBitsFract;
263   INT scfBitsDiff = 0;
264   INT sfb = 0, sfbLast;
265   INT sfbPrev, sfbNext;
266 
267   /* search for first relevant sfb */
268   sfbLast = startSfb;
269   while ((sfbLast<stopSfb) && (scfOld[sfbLast]==FDK_INT_MIN))
270     sfbLast++;
271   /* search for previous relevant sfb and count diff */
272   sfbPrev = startSfb - 1;
273   while ((sfbPrev>=0) && (scfOld[sfbPrev]==FDK_INT_MIN))
274     sfbPrev--;
275   if (sfbPrev>=0)
276     scfBitsDiff += FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbPrev]-scfNew[sfbLast]) -
277                    FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbPrev]-scfOld[sfbLast]);
278   /* now loop through all sfbs and count diffs of relevant sfbs */
279   for (sfb=sfbLast+1; sfb<stopSfb; sfb++) {
280     if (scfOld[sfb]!=FDK_INT_MIN) {
281       scfBitsDiff += FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast]-scfNew[sfb]) -
282                      FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast]-scfOld[sfb]);
283       sfbLast = sfb;
284     }
285   }
286   /* search for next relevant sfb and count diff */
287   sfbNext = stopSfb;
288   while ((sfbNext<sfbCnt) && (scfOld[sfbNext]==FDK_INT_MIN))
289     sfbNext++;
290   if (sfbNext<sfbCnt)
291     scfBitsDiff += FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast]-scfNew[sfbNext]) -
292                    FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast]-scfOld[sfbNext]);
293 
294   scfBitsFract = (FIXP_DBL) (scfBitsDiff << (DFRACT_BITS-1-(2*AS_PE_FAC_SHIFT)));
295 
296   return scfBitsFract;
297 }
298 
299 /*
300   Function: FDKaacEnc_calcSpecPeDiff
301 
302   specPeDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
303 */
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)304 static FIXP_DBL FDKaacEnc_calcSpecPeDiff(PSY_OUT_CHANNEL *psyOutChan,
305                                QC_OUT_CHANNEL  *qcOutChannel,
306                                INT *scfOld,
307                                INT *scfNew,
308                                FIXP_DBL *sfbConstPePart,
309                                FIXP_DBL *sfbFormFactorLdData,
310                                FIXP_DBL *sfbNRelevantLines,
311                                INT startSfb,
312                                INT stopSfb)
313 {
314   FIXP_DBL specPeDiff = FL2FXCONST_DBL(0.0f);
315   FIXP_DBL scfFract = FL2FXCONST_DBL(0.0f);
316   INT sfb;
317 
318   /* loop through all sfbs and count pe difference */
319   for (sfb=startSfb; sfb<stopSfb; sfb++) {
320     if (scfOld[sfb]!=FDK_INT_MIN) {
321       FIXP_DBL ldRatioOld, ldRatioNew, pOld, pNew;
322 
323       /* sfbConstPePart[sfb] = (float)log(psyOutChan->sfbEnergy[sfb] * 6.75f / sfbFormFactor[sfb]) * LOG2_1; */
324       /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for log2 */
325       /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
326       if (sfbConstPePart[sfb] == (FIXP_DBL)FDK_INT_MIN)
327         sfbConstPePart[sfb] = ((psyOutChan->sfbEnergyLdData[sfb] - sfbFormFactorLdData[sfb] - FL2FXCONST_DBL(0.09375f)) >> 1) + FL2FXCONST_DBL(0.02152255861f);
328 
329       scfFract = (FIXP_DBL) (scfOld[sfb] << (DFRACT_BITS-1-AS_PE_FAC_SHIFT));
330       ldRatioOld = sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f),scfFract);
331 
332       scfFract = (FIXP_DBL) (scfNew[sfb] << (DFRACT_BITS-1-AS_PE_FAC_SHIFT));
333       ldRatioNew = sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f),scfFract);
334 
335       if (ldRatioOld >= PE_C1)
336         pOld = ldRatioOld;
337       else
338         pOld = PE_C2 + fMult(PE_C3,ldRatioOld);
339 
340       if (ldRatioNew >= PE_C1)
341         pNew = ldRatioNew;
342       else
343         pNew = PE_C2 + fMult(PE_C3,ldRatioNew);
344 
345       specPeDiff += fMult(FL2FXCONST_DBL(0.7f),fMult(sfbNRelevantLines[sfb],(pNew - pOld)));
346     }
347   }
348 
349   return specPeDiff;
350 }
351 
352 /*
353   Function: FDKaacEnc_improveScf
354 
355   Description: Calculate the distortion by quantization and inverse quantization of the spectrum with
356                various scalefactors. The scalefactor which provides the best results will be used.
357 */
FDKaacEnc_improveScf(FIXP_DBL * spec,SHORT * quantSpec,SHORT * quantSpecTmp,INT sfbWidth,FIXP_DBL threshLdData,INT scf,INT minScf,FIXP_DBL * distLdData,INT * minScfCalculated,INT dZoneQuantEnable)358 static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
359                       SHORT *quantSpec,
360                       SHORT *quantSpecTmp,
361                       INT sfbWidth,
362                       FIXP_DBL  threshLdData,
363                       INT scf,
364                       INT minScf,
365                       FIXP_DBL  *distLdData,
366                       INT *minScfCalculated,
367                       INT dZoneQuantEnable
368                       )
369 {
370    FIXP_DBL sfbDistLdData;
371    INT scfBest = scf;
372    INT k;
373    FIXP_DBL distFactorLdData = FL2FXCONST_DBL(-0.0050301265);   /* ld64(1/1.25) */
374 
375    /* calc real distortion */
376    sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
377                                          quantSpec,
378                                          sfbWidth,
379                                          scf,
380                                          dZoneQuantEnable);
381    *minScfCalculated = scf;
382    /* nmr > 1.25 -> try to improve nmr */
383    if (sfbDistLdData > (threshLdData-distFactorLdData)) {
384       INT scfEstimated = scf;
385       FIXP_DBL sfbDistBestLdData = sfbDistLdData;
386       INT cnt;
387       /* improve by bigger scf ? */
388       cnt = 0;
389 
390       while ((sfbDistLdData > (threshLdData-distFactorLdData)) && (cnt++ < 3)) {
391          scf++;
392          sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
393                                                quantSpecTmp,
394                                                sfbWidth,
395                                                scf,
396                                                dZoneQuantEnable);
397 
398          if (sfbDistLdData < sfbDistBestLdData) {
399             scfBest = scf;
400             sfbDistBestLdData = sfbDistLdData;
401             for (k=0; k<sfbWidth; k++)
402 	             quantSpec[k] = quantSpecTmp[k];
403          }
404       }
405       /* improve by smaller scf ? */
406       cnt = 0;
407       scf = scfEstimated;
408       sfbDistLdData = sfbDistBestLdData;
409       while ((sfbDistLdData > (threshLdData-distFactorLdData)) && (cnt++ < 1) && (scf > minScf)) {
410          scf--;
411          sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
412                                                quantSpecTmp,
413                                                sfbWidth,
414                                                scf,
415                                                dZoneQuantEnable);
416 
417          if (sfbDistLdData < sfbDistBestLdData) {
418             scfBest = scf;
419             sfbDistBestLdData = sfbDistLdData;
420             for (k=0; k<sfbWidth; k++)
421 	             quantSpec[k] = quantSpecTmp[k];
422          }
423          *minScfCalculated = scf;
424       }
425       *distLdData = sfbDistBestLdData;
426    }
427    else { /* nmr <= 1.25 -> try to find bigger scf to use less bits */
428       FIXP_DBL sfbDistBestLdData = sfbDistLdData;
429       FIXP_DBL sfbDistAllowedLdData = fixMin(sfbDistLdData-distFactorLdData,threshLdData);
430       int cnt;
431       for (cnt=0; cnt<3; cnt++) {
432          scf++;
433          sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
434                                                quantSpecTmp,
435                                                sfbWidth,
436                                                scf,
437                                                dZoneQuantEnable);
438 
439          if (sfbDistLdData < sfbDistAllowedLdData) {
440            *minScfCalculated = scfBest+1;
441            scfBest = scf;
442            sfbDistBestLdData = sfbDistLdData;
443            for (k=0; k<sfbWidth; k++)
444              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(PSY_OUT_CHANNEL * psyOutChan,QC_OUT_CHANNEL * qcOutChannel,SHORT * quantSpec,SHORT * quantSpecTmp,INT dZoneQuantEnable,INT * scf,INT * minScf,FIXP_DBL * sfbDist,FIXP_DBL * sfbConstPePart,FIXP_DBL * sfbFormFactorLdData,FIXP_DBL * sfbNRelevantLines,INT * minScfCalculated,INT restartOnSuccess)458 static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,
459                                 QC_OUT_CHANNEL   *qcOutChannel,
460                                 SHORT *quantSpec,
461                                 SHORT *quantSpecTmp,
462                                 INT dZoneQuantEnable,
463                                 INT *scf,
464                                 INT *minScf,
465                                 FIXP_DBL *sfbDist,
466                                 FIXP_DBL *sfbConstPePart,
467                                 FIXP_DBL *sfbFormFactorLdData,
468                                 FIXP_DBL *sfbNRelevantLines,
469                                 INT *minScfCalculated,
470                                 INT restartOnSuccess)
471 {
472   INT sfbLast, sfbAct, sfbNext;
473   INT scfAct, *scfLast, *scfNext, scfMin, scfMax;
474   INT sfbWidth, sfbOffs;
475   FIXP_DBL enLdData;
476   FIXP_DBL sfbPeOld, sfbPeNew;
477   FIXP_DBL sfbDistNew;
478   INT i, k;
479   INT success = 0;
480   FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
481   FIXP_DBL deltaPeNew, deltaPeTmp;
482   INT prevScfLast[MAX_GROUPED_SFB], prevScfNext[MAX_GROUPED_SFB];
483   FIXP_DBL deltaPeLast[MAX_GROUPED_SFB];
484   INT updateMinScfCalculated;
485 
486   for (i=0; i<psyOutChan->sfbCnt; i++) {
487     prevScfLast[i] = FDK_INT_MAX;
488     prevScfNext[i] = FDK_INT_MAX;
489     deltaPeLast[i] = (FIXP_DBL)FDK_INT_MAX;
490   }
491 
492   sfbLast = -1;
493   sfbAct  = -1;
494   sfbNext = -1;
495   scfLast = 0;
496   scfNext = 0;
497   scfMin  = FDK_INT_MAX;
498   scfMax  = FDK_INT_MAX;
499   do {
500     /* search for new relevant sfb */
501     sfbNext++;
502     while ((sfbNext < psyOutChan->sfbCnt) && (scf[sfbNext] == FDK_INT_MIN))
503       sfbNext++;
504     if ((sfbLast>=0) && (sfbAct>=0) && (sfbNext<psyOutChan->sfbCnt)) {
505       /* relevant scfs to the left and to the right */
506       scfAct  = scf[sfbAct];
507       scfLast = scf + sfbLast;
508       scfNext = scf + sfbNext;
509       scfMin  = fixMin(*scfLast, *scfNext);
510       scfMax  = fixMax(*scfLast, *scfNext);
511     }
512     else if ((sfbLast==-1) && (sfbAct>=0) && (sfbNext<psyOutChan->sfbCnt)) {
513       /* first relevant scf */
514       scfAct  = scf[sfbAct];
515       scfLast = &scfAct;
516       scfNext = scf + sfbNext;
517       scfMin  = *scfNext;
518       scfMax  = *scfNext;
519     }
520     else if ((sfbLast>=0) && (sfbAct>=0) && (sfbNext==psyOutChan->sfbCnt)) {
521       /* last relevant scf */
522       scfAct  = scf[sfbAct];
523       scfLast = scf + sfbLast;
524       scfNext = &scfAct;
525       scfMin  = *scfLast;
526       scfMax  = *scfLast;
527     }
528     if (sfbAct>=0)
529       scfMin = fixMax(scfMin, minScf[sfbAct]);
530 
531     if ((sfbAct >= 0) &&
532         (sfbLast>=0 || sfbNext<psyOutChan->sfbCnt) &&
533         (scfAct > scfMin) &&
534         (scfAct <= scfMin+MAX_SCF_DELTA) &&
535         (scfAct >= scfMax-MAX_SCF_DELTA) &&
536         (*scfLast != prevScfLast[sfbAct] ||
537          *scfNext != prevScfNext[sfbAct] ||
538          deltaPe < deltaPeLast[sfbAct])) {
539       /* bigger than neighbouring scf found, try to use smaller scf */
540       success = 0;
541 
542       sfbWidth = psyOutChan->sfbOffsets[sfbAct+1] - psyOutChan->sfbOffsets[sfbAct];
543       sfbOffs = psyOutChan->sfbOffsets[sfbAct];
544 
545       /* estimate required bits for actual scf */
546       enLdData = qcOutChannel->sfbEnergyLdData[sfbAct];
547 
548       /* sfbConstPePart[sfbAct] = (float)log(6.75f*en/sfbFormFactor[sfbAct]) * LOG2_1; */
549       /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for log2 */
550       /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
551       if (sfbConstPePart[sfbAct] == (FIXP_DBL)FDK_INT_MIN) {
552         sfbConstPePart[sfbAct] = ((enLdData - sfbFormFactorLdData[sfbAct] - FL2FXCONST_DBL(0.09375f)) >> 1) + FL2FXCONST_DBL(0.02152255861f);
553       }
554 
555       sfbPeOld = FDKaacEnc_calcSingleSpecPe(scfAct,sfbConstPePart[sfbAct],sfbNRelevantLines[sfbAct])
556                 +FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext);
557 
558       deltaPeNew = deltaPe;
559       updateMinScfCalculated = 1;
560 
561       do {
562         /* estimate required bits for smaller scf */
563         scfAct--;
564         /* check only if the same check was not done before */
565         if (scfAct < minScfCalculated[sfbAct] && scfAct>=scfMax-MAX_SCF_DELTA){
566           /* estimate required bits for new scf */
567           sfbPeNew =  FDKaacEnc_calcSingleSpecPe(scfAct,sfbConstPePart[sfbAct],sfbNRelevantLines[sfbAct])
568                      +FDKaacEnc_countSingleScfBits(scfAct,*scfLast, *scfNext);
569 
570           /* use new scf if no increase in pe and
571              quantization error is smaller */
572           deltaPeTmp = deltaPe + sfbPeNew - sfbPeOld;
573           /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
574           if (deltaPeTmp < FL2FXCONST_DBL(0.0006103515625f)) {
575             /* distortion of new scf */
576             sfbDistNew = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs,
577                                                quantSpecTmp+sfbOffs,
578                                                sfbWidth,
579                                                scfAct,
580                                                dZoneQuantEnable);
581 
582             if (sfbDistNew < sfbDist[sfbAct]) {
583               /* success, replace scf by new one */
584               scf[sfbAct] = scfAct;
585               sfbDist[sfbAct] = sfbDistNew;
586 
587               for (k=0; k<sfbWidth; k++)
588                 quantSpec[sfbOffs+k] = quantSpecTmp[sfbOffs+k];
589 
590               deltaPeNew = deltaPeTmp;
591               success = 1;
592             }
593             /* mark as already checked */
594             if (updateMinScfCalculated)
595               minScfCalculated[sfbAct] = scfAct;
596           }
597           else {
598             /* from this scf value on not all new values have been checked */
599             updateMinScfCalculated = 0;
600           }
601         }
602       } while (scfAct > scfMin);
603 
604       deltaPe = deltaPeNew;
605 
606       /* save parameters to avoid multiple computations of the same sfb */
607       prevScfLast[sfbAct] = *scfLast;
608       prevScfNext[sfbAct] = *scfNext;
609       deltaPeLast[sfbAct] = deltaPe;
610     }
611 
612     if (success && restartOnSuccess) {
613       /* start again at first sfb */
614       sfbLast = -1;
615       sfbAct  = -1;
616       sfbNext = -1;
617       scfLast = 0;
618       scfNext = 0;
619       scfMin  = FDK_INT_MAX;
620       scfMax  = FDK_INT_MAX;
621       success = 0;
622     }
623     else {
624       /* shift sfbs for next band */
625       sfbLast = sfbAct;
626       sfbAct  = sfbNext;
627     }
628   } while (sfbNext < psyOutChan->sfbCnt);
629 }
630 
631 /*
632   Function: FDKaacEnc_assimilateMultipleScf
633 
634 */
FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL * psyOutChan,QC_OUT_CHANNEL * qcOutChannel,SHORT * quantSpec,SHORT * quantSpecTmp,INT dZoneQuantEnable,INT * scf,INT * minScf,FIXP_DBL * sfbDist,FIXP_DBL * sfbConstPePart,FIXP_DBL * sfbFormFactorLdData,FIXP_DBL * sfbNRelevantLines)635 static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan,
636                                   QC_OUT_CHANNEL  *qcOutChannel,
637                                   SHORT *quantSpec,
638                                   SHORT *quantSpecTmp,
639                                   INT dZoneQuantEnable,
640                                   INT *scf,
641                                   INT *minScf,
642                                   FIXP_DBL *sfbDist,
643                                   FIXP_DBL *sfbConstPePart,
644                                   FIXP_DBL *sfbFormFactorLdData,
645                                   FIXP_DBL *sfbNRelevantLines)
646 {
647   INT sfb, startSfb, stopSfb;
648   INT scfTmp[MAX_GROUPED_SFB], scfMin, scfMax, scfAct;
649   INT possibleRegionFound;
650   INT sfbWidth, sfbOffs, i, k;
651   FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], distOldSum, distNewSum;
652   INT deltaScfBits;
653   FIXP_DBL deltaSpecPe;
654   FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
655   FIXP_DBL deltaPeNew;
656   INT sfbCnt = psyOutChan->sfbCnt;
657 
658   /* calc min and max scalfactors */
659   scfMin = FDK_INT_MAX;
660   scfMax = FDK_INT_MIN;
661   for (sfb=0; sfb<sfbCnt; sfb++) {
662     if (scf[sfb]!=FDK_INT_MIN) {
663       scfMin = fixMin(scfMin, scf[sfb]);
664       scfMax = fixMax(scfMax, scf[sfb]);
665     }
666   }
667 
668   if (scfMax != FDK_INT_MIN && scfMax <= scfMin+MAX_SCF_DELTA) {
669 
670     scfAct = scfMax;
671 
672     do {
673       /* try smaller scf */
674       scfAct--;
675       for (i=0; i<MAX_GROUPED_SFB; i++)
676         scfTmp[i] = scf[i];
677       stopSfb = 0;
678       do {
679         /* search for region where all scfs are bigger than scfAct */
680         sfb = stopSfb;
681         while (sfb<sfbCnt && (scf[sfb]==FDK_INT_MIN || scf[sfb] <= scfAct))
682           sfb++;
683         startSfb = sfb;
684         sfb++;
685         while (sfb<sfbCnt && (scf[sfb]==FDK_INT_MIN || scf[sfb] > scfAct))
686           sfb++;
687         stopSfb = sfb;
688 
689         /* check if in all sfb of a valid region scfAct >= minScf[sfb] */
690         possibleRegionFound = 0;
691         if (startSfb < sfbCnt) {
692           possibleRegionFound = 1;
693           for (sfb=startSfb; sfb<stopSfb; sfb++) {
694             if (scf[sfb] != FDK_INT_MIN)
695               if (scfAct < minScf[sfb]) {
696                 possibleRegionFound = 0;
697                 break;
698               }
699           }
700         }
701 
702         if (possibleRegionFound) { /* region found */
703 
704           /* replace scfs in region by scfAct */
705           for (sfb=startSfb; sfb<stopSfb; sfb++) {
706             if (scfTmp[sfb] != FDK_INT_MIN)
707               scfTmp[sfb] = scfAct;
708           }
709 
710           /* estimate change in bit demand for new scfs */
711           deltaScfBits = FDKaacEnc_countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb);
712 
713           deltaSpecPe = FDKaacEnc_calcSpecPeDiff(psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
714                                        sfbFormFactorLdData, sfbNRelevantLines,
715                                        startSfb, stopSfb);
716 
717           deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
718 
719           /* new bit demand small enough ? */
720           /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
721           if (deltaPeNew < FL2FXCONST_DBL(0.0006103515625f)) {
722 
723             /* quantize and calc sum of new distortion */
724             distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
725             for (sfb=startSfb; sfb<stopSfb; sfb++) {
726               if (scfTmp[sfb] != FDK_INT_MIN) {
727                 distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
728 
729                 sfbWidth = psyOutChan->sfbOffsets[sfb+1] - psyOutChan->sfbOffsets[sfb];
730                 sfbOffs = psyOutChan->sfbOffsets[sfb];
731 
732                 sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs,
733                                               quantSpecTmp+sfbOffs,
734                                               sfbWidth,
735                                               scfAct,
736                                               dZoneQuantEnable);
737 
738                 if (sfbDistNew[sfb] >qcOutChannel->sfbThresholdLdData[sfb]) {
739                   /* no improvement, skip further dist. calculations */
740                   distNewSum = distOldSum << 1;
741                   break;
742                 }
743                 distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
744               }
745             }
746             /* distortion smaller ? -> use new scalefactors */
747             if (distNewSum < distOldSum) {
748               deltaPe = deltaPeNew;
749               for (sfb=startSfb; sfb<stopSfb; sfb++) {
750                 if (scf[sfb] != FDK_INT_MIN) {
751                   sfbWidth = psyOutChan->sfbOffsets[sfb+1] -
752                              psyOutChan->sfbOffsets[sfb];
753                   sfbOffs = psyOutChan->sfbOffsets[sfb];
754                   scf[sfb] = scfAct;
755                   sfbDist[sfb] = sfbDistNew[sfb];
756 
757                   for (k=0; k<sfbWidth; k++)
758                     quantSpec[sfbOffs+k] = quantSpecTmp[sfbOffs+k];
759                 }
760               }
761             }
762 
763           }
764         }
765 
766       } while (stopSfb <= sfbCnt);
767 
768     } while (scfAct > scfMin);
769   }
770 }
771 
772 /*
773   Function: FDKaacEnc_FDKaacEnc_assimilateMultipleScf2
774 
775 */
FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL * psyOutChan,QC_OUT_CHANNEL * qcOutChannel,SHORT * quantSpec,SHORT * quantSpecTmp,INT dZoneQuantEnable,INT * scf,INT * minScf,FIXP_DBL * sfbDist,FIXP_DBL * sfbConstPePart,FIXP_DBL * sfbFormFactorLdData,FIXP_DBL * sfbNRelevantLines)776 static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutChan,
777                                    QC_OUT_CHANNEL  *qcOutChannel,
778                                    SHORT *quantSpec,
779                                    SHORT *quantSpecTmp,
780                                    INT dZoneQuantEnable,
781                                    INT *scf,
782                                    INT *minScf,
783                                    FIXP_DBL *sfbDist,
784                                    FIXP_DBL *sfbConstPePart,
785                                    FIXP_DBL *sfbFormFactorLdData,
786                                    FIXP_DBL *sfbNRelevantLines)
787 {
788   INT sfb, startSfb, stopSfb;
789   INT scfTmp[MAX_GROUPED_SFB], scfAct, scfNew;
790   INT scfPrev, scfNext, scfPrevNextMin, scfPrevNextMax, scfLo, scfHi;
791   INT scfMin, scfMax;
792   INT *sfbOffs = psyOutChan->sfbOffsets;
793   FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], sfbDistMax[MAX_GROUPED_SFB];
794   FIXP_DBL distOldSum, distNewSum;
795   INT deltaScfBits;
796   FIXP_DBL deltaSpecPe;
797   FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
798   FIXP_DBL deltaPeNew = FL2FXCONST_DBL(0.0f);
799   INT sfbCnt = psyOutChan->sfbCnt;
800   INT bSuccess, bCheckScf;
801   INT i,k;
802 
803   /* calc min and max scalfactors */
804   scfMin = FDK_INT_MAX;
805   scfMax = FDK_INT_MIN;
806   for (sfb=0; sfb<sfbCnt; sfb++) {
807     if (scf[sfb]!=FDK_INT_MIN) {
808       scfMin = fixMin(scfMin, scf[sfb]);
809       scfMax = fixMax(scfMax, scf[sfb]);
810     }
811   }
812 
813   stopSfb = 0;
814   scfAct = FDK_INT_MIN;
815   do {
816     /* search for region with same scf values scfAct */
817     scfPrev = scfAct;
818 
819     sfb = stopSfb;
820     while (sfb<sfbCnt && (scf[sfb]==FDK_INT_MIN))
821       sfb++;
822     startSfb = sfb;
823     scfAct = scf[startSfb];
824     sfb++;
825     while (sfb<sfbCnt && ((scf[sfb]==FDK_INT_MIN) || (scf[sfb]==scf[startSfb])))
826       sfb++;
827     stopSfb = sfb;
828 
829     if (stopSfb < sfbCnt)
830       scfNext = scf[stopSfb];
831     else
832       scfNext = scfAct;
833 
834     if (scfPrev == FDK_INT_MIN)
835       scfPrev = scfAct;
836 
837     scfPrevNextMax = fixMax(scfPrev, scfNext);
838     scfPrevNextMin = fixMin(scfPrev, scfNext);
839 
840     /* try to reduce bits by checking scf values in the range
841        scf[startSfb]...scfHi */
842     scfHi = fixMax(scfPrevNextMax, scfAct);
843     /* try to find a better solution by reducing the scf difference to
844        the nearest possible lower scf */
845     if (scfPrevNextMax >= scfAct)
846       scfLo = fixMin(scfAct, scfPrevNextMin);
847     else
848       scfLo = scfPrevNextMax;
849 
850     if (startSfb < sfbCnt && scfHi-scfLo <= MAX_SCF_DELTA) { /* region found */
851       /* 1. try to save bits by coarser quantization */
852       if (scfHi > scf[startSfb]) {
853         /* calculate the allowed distortion */
854         for (sfb=startSfb; sfb<stopSfb; sfb++) {
855           if (scf[sfb] != FDK_INT_MIN) {
856             /* sfbDistMax[sfb] = (float)pow(qcOutChannel->sfbThreshold[sfb]*sfbDist[sfb]*sfbDist[sfb],1.0f/3.0f); */
857             /* sfbDistMax[sfb] = fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergy[sfb]*FL2FXCONST_DBL(1.e-3f)); */
858             /* -0.15571537944 = ld64(1.e-3f)*/
859             sfbDistMax[sfb] = fMult(FL2FXCONST_DBL(1.0f/3.0f),qcOutChannel->sfbThresholdLdData[sfb])+fMult(FL2FXCONST_DBL(1.0f/3.0f),sfbDist[sfb])+fMult(FL2FXCONST_DBL(1.0f/3.0f),sfbDist[sfb]);
860             sfbDistMax[sfb] = fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergyLdData[sfb]-FL2FXCONST_DBL(0.15571537944));
861             sfbDistMax[sfb] = fixMin(sfbDistMax[sfb],qcOutChannel->sfbThresholdLdData[sfb]);
862           }
863         }
864 
865         /* loop over all possible scf values for this region */
866         bCheckScf = 1;
867         for (scfNew=scf[startSfb]+1; scfNew<=scfHi; scfNew++) {
868 	         for (k=0; k<MAX_GROUPED_SFB; k++)
869             scfTmp[k] = scf[k];
870 
871           /* replace scfs in region by scfNew */
872           for (sfb=startSfb; sfb<stopSfb; sfb++) {
873             if (scfTmp[sfb] != FDK_INT_MIN)
874               scfTmp[sfb] = scfNew;
875           }
876 
877           /* estimate change in bit demand for new scfs */
878           deltaScfBits = FDKaacEnc_countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb);
879 
880           deltaSpecPe = FDKaacEnc_calcSpecPeDiff(psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
881                                        sfbFormFactorLdData, sfbNRelevantLines,
882                                        startSfb, stopSfb);
883 
884           deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
885 
886           /* new bit demand small enough ? */
887           if (deltaPeNew < FL2FXCONST_DBL(0.0f)) {
888             bSuccess = 1;
889 
890             /* quantize and calc sum of new distortion */
891             for (sfb=startSfb; sfb<stopSfb; sfb++) {
892               if (scfTmp[sfb] != FDK_INT_MIN) {
893                 sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb],
894                                               quantSpecTmp+sfbOffs[sfb],
895                                               sfbOffs[sfb+1]-sfbOffs[sfb],
896                                               scfNew,
897                                               dZoneQuantEnable);
898 
899                 if (sfbDistNew[sfb] > sfbDistMax[sfb]) {
900                   /* no improvement, skip further dist. calculations */
901                   bSuccess = 0;
902                   if (sfbDistNew[sfb] == qcOutChannel->sfbEnergyLdData[sfb]) {
903                     /* if whole sfb is already quantized to 0, further
904                        checks with even coarser quant. are useless*/
905                     bCheckScf = 0;
906                   }
907                   break;
908                 }
909               }
910             }
911             if (bCheckScf==0) /* further calculations useless ? */
912                 break;
913             /* distortion small enough ? -> use new scalefactors */
914             if (bSuccess) {
915               deltaPe = deltaPeNew;
916               for (sfb=startSfb; sfb<stopSfb; sfb++) {
917                 if (scf[sfb] != FDK_INT_MIN) {
918                   scf[sfb] = scfNew;
919                   sfbDist[sfb] = sfbDistNew[sfb];
920 
921                   for (k=0; k<sfbOffs[sfb+1]-sfbOffs[sfb]; k++)
922                     quantSpec[sfbOffs[sfb]+k] = quantSpecTmp[sfbOffs[sfb]+k];
923                 }
924               }
925             }
926           }
927         }
928       }
929 
930       /* 2. only if coarser quantization was not successful, try to find
931          a better solution by finer quantization and reducing bits for
932          scalefactor coding */
933       if (scfAct==scf[startSfb] &&
934           scfLo < scfAct &&
935           scfMax-scfMin <= MAX_SCF_DELTA) {
936 
937         int bminScfViolation = 0;
938 
939         for (k=0; k<MAX_GROUPED_SFB; k++)
940           scfTmp[k] = scf[k];
941 
942         scfNew = scfLo;
943 
944         /* replace scfs in region by scfNew and
945            check if in all sfb scfNew >= minScf[sfb] */
946         for (sfb=startSfb; sfb<stopSfb; sfb++) {
947           if (scfTmp[sfb] != FDK_INT_MIN) {
948             scfTmp[sfb] = scfNew;
949             if (scfNew < minScf[sfb])
950               bminScfViolation = 1;
951           }
952         }
953 
954         if (!bminScfViolation) {
955           /* estimate change in bit demand for new scfs */
956           deltaScfBits = FDKaacEnc_countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb);
957 
958           deltaSpecPe = FDKaacEnc_calcSpecPeDiff(psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
959                                        sfbFormFactorLdData, sfbNRelevantLines,
960                                        startSfb, stopSfb);
961 
962           deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
963         }
964 
965         /* new bit demand small enough ? */
966         if (!bminScfViolation && deltaPeNew < FL2FXCONST_DBL(0.0f)) {
967 
968           /* quantize and calc sum of new distortion */
969           distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
970           for (sfb=startSfb; sfb<stopSfb; sfb++) {
971             if (scfTmp[sfb] != FDK_INT_MIN) {
972               distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
973 
974               sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb],
975                                                       quantSpecTmp+sfbOffs[sfb],
976                                                       sfbOffs[sfb+1]-sfbOffs[sfb],
977                                                       scfNew,
978                                                       dZoneQuantEnable);
979 
980               if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) {
981                 /* no improvement, skip further dist. calculations */
982                 distNewSum = distOldSum << 1;
983                 break;
984               }
985               distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
986             }
987           }
988           /* distortion smaller ? -> use new scalefactors */
989           if (distNewSum < fMult(FL2FXCONST_DBL(0.8f),distOldSum)) {
990             deltaPe = deltaPeNew;
991             for (sfb=startSfb; sfb<stopSfb; sfb++) {
992               if (scf[sfb] != FDK_INT_MIN) {
993                 scf[sfb] = scfNew;
994                 sfbDist[sfb] = sfbDistNew[sfb];
995 
996                 for (k=0; k<sfbOffs[sfb+1]-sfbOffs[sfb]; k++)
997                   quantSpec[sfbOffs[sfb]+k] = quantSpecTmp[sfbOffs[sfb]+k];
998               }
999             }
1000           }
1001         }
1002       }
1003 
1004       /* 3. try to find a better solution (save bits) by only reducing the
1005          scalefactor without new quantization */
1006       if (scfMax-scfMin <= MAX_SCF_DELTA-3) { /* 3 bec. scf is reduced 3 times,
1007                                                  see for loop below */
1008 
1009         for (k=0; k<sfbCnt; k++)
1010           scfTmp[k] = scf[k];
1011 
1012         for (i=0; i<3; i++) {
1013           scfNew = scfTmp[startSfb]-1;
1014           /* replace scfs in region by scfNew */
1015           for (sfb=startSfb; sfb<stopSfb; sfb++) {
1016             if (scfTmp[sfb] != FDK_INT_MIN)
1017               scfTmp[sfb] = scfNew;
1018           }
1019           /* estimate change in bit demand for new scfs */
1020           deltaScfBits = FDKaacEnc_countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb);
1021           deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits;
1022           /* new bit demand small enough ? */
1023           if (deltaPeNew <= FL2FXCONST_DBL(0.0f)) {
1024 
1025             bSuccess = 1;
1026             distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
1027             for (sfb=startSfb; sfb<stopSfb; sfb++) {
1028               if (scfTmp[sfb] != FDK_INT_MIN) {
1029                 FIXP_DBL sfbEnQ;
1030                 /* calc the energy and distortion of the quantized spectrum for
1031                    a smaller scf */
1032                 FDKaacEnc_calcSfbQuantEnergyAndDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb],
1033                                           quantSpec+sfbOffs[sfb],
1034                                           sfbOffs[sfb+1]-sfbOffs[sfb], scfNew,
1035                                           &sfbEnQ, &sfbDistNew[sfb]);
1036 
1037                 distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
1038                 distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
1039 
1040                 /*  0.00259488556167 = ld64(1.122f) */
1041                 /* -0.00778722686652 = ld64(0.7079f) */
1042                 if ((sfbDistNew[sfb] > (sfbDist[sfb]+FL2FXCONST_DBL(0.00259488556167f))) || (sfbEnQ < (qcOutChannel->sfbEnergyLdData[sfb] - FL2FXCONST_DBL(0.00778722686652f)))){
1043                   bSuccess = 0;
1044                   break;
1045                 }
1046               }
1047             }
1048             /* distortion smaller ? -> use new scalefactors */
1049             if (distNewSum < distOldSum && bSuccess) {
1050               deltaPe = deltaPeNew;
1051               for (sfb=startSfb; sfb<stopSfb; sfb++) {
1052                 if (scf[sfb] != FDK_INT_MIN) {
1053                   scf[sfb] = scfNew;
1054                   sfbDist[sfb] = sfbDistNew[sfb];
1055                 }
1056               }
1057             }
1058           }
1059         }
1060       }
1061     }
1062   } while (stopSfb <= sfbCnt);
1063 
1064 }
1065 
1066 static void
FDKaacEnc_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)1067 FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL   *qcOutChannel,
1068                             PSY_OUT_CHANNEL  *psyOutChannel,
1069                             INT *RESTRICT scf,
1070                             INT *RESTRICT globalGain,
1071                             FIXP_DBL *RESTRICT sfbFormFactorLdData
1072                             ,const INT invQuant,
1073                             SHORT *RESTRICT quantSpec,
1074                             const INT dZoneQuantEnable
1075                             )
1076 {
1077   INT i, j, sfb, sfbOffs;
1078   INT scfInt;
1079   INT maxSf;
1080   INT minSf;
1081   FIXP_DBL threshLdData;
1082   FIXP_DBL energyLdData;
1083   FIXP_DBL energyPartLdData;
1084   FIXP_DBL thresholdPartLdData;
1085   FIXP_DBL scfFract;
1086   FIXP_DBL maxSpec;
1087   FIXP_DBL absSpec;
1088   INT minScfCalculated[MAX_GROUPED_SFB];
1089   FIXP_DBL sfbDistLdData[MAX_GROUPED_SFB];
1090   C_ALLOC_SCRATCH_START(quantSpecTmp, SHORT, (1024));
1091   INT minSfMaxQuant[MAX_GROUPED_SFB];
1092 
1093   FIXP_DBL threshConstLdData=FL2FXCONST_DBL(0.04304511722f); /* log10(6.75)/log10(2.0)/64.0 */
1094   FIXP_DBL convConst=FL2FXCONST_DBL(0.30102999566f); /* log10(2.0) */
1095   FIXP_DBL c1Const=FL2FXCONST_DBL(-0.27083183594f); /* C1 = -69.33295 => C1/2^8 */
1096 
1097 
1098 
1099   if (invQuant>0) {
1100     FDKmemclear(quantSpec, (1024)*sizeof(SHORT));
1101   }
1102 
1103   /* scfs without energy or with thresh>energy are marked with FDK_INT_MIN */
1104   for(i=0; i<psyOutChannel->sfbCnt; i++) {
1105     scf[i] = FDK_INT_MIN;
1106   }
1107 
1108   for (i=0; i<MAX_GROUPED_SFB; i++) {
1109     minSfMaxQuant[i] = FDK_INT_MIN;
1110   }
1111 
1112   for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) {
1113     for(sfb=0; sfb<psyOutChannel->maxSfbPerGroup; sfb++) {
1114 
1115       threshLdData = qcOutChannel->sfbThresholdLdData[sfbOffs+sfb];
1116       energyLdData = qcOutChannel->sfbEnergyLdData[sfbOffs+sfb];
1117 
1118       sfbDistLdData[sfbOffs+sfb] = energyLdData;
1119 
1120 
1121       if (energyLdData > threshLdData) {
1122         FIXP_DBL tmp;
1123 
1124         /* energyPart = (float)log10(sfbFormFactor[sfbOffs+sfb]); */
1125         /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
1126         energyPartLdData = sfbFormFactorLdData[sfbOffs+sfb] + FL2FXCONST_DBL(0.09375f);
1127 
1128         /* influence of allowed distortion */
1129         /* thresholdPart = (float)log10(6.75*thresh+FLT_MIN); */
1130         thresholdPartLdData = threshConstLdData + threshLdData;
1131 
1132         /* scf calc */
1133         /* scfFloat = 8.8585f * (thresholdPart - energyPart); */
1134         scfFract = thresholdPartLdData - energyPartLdData;
1135         /* conversion from log2 to log10 */
1136         scfFract = fMult(convConst,scfFract);
1137         /* (8.8585f * scfFract)/8 = 8/8 * scfFract + 0.8585 * scfFract/8 */
1138         scfFract = scfFract + fMult(FL2FXCONST_DBL(0.8585f),scfFract >> 3);
1139 
1140         /* integer scalefactor */
1141         /* scfInt = (int)floor(scfFloat); */
1142         scfInt = (INT)(scfFract>>((DFRACT_BITS-1)-3-LD_DATA_SHIFT)); /* 3 bits => scfFract/8.0; 6 bits => ld64 */
1143 
1144         /* maximum of spectrum */
1145         maxSpec = FL2FXCONST_DBL(0.0f);
1146 
1147         for(j=psyOutChannel->sfbOffsets[sfbOffs+sfb]; j<psyOutChannel->sfbOffsets[sfbOffs+sfb+1]; j++ ){
1148           absSpec = fixp_abs(qcOutChannel->mdctSpectrum[j]);
1149           maxSpec = (absSpec > maxSpec) ? absSpec : maxSpec;
1150         }
1151 
1152         /* lower scf limit to avoid quantized values bigger than MAX_QUANT */
1153         /* C1 = -69.33295f, C2 = 5.77078f = 4/log(2) */
1154         /* minSfMaxQuant[sfbOffs+sfb] = (int)ceil(C1 + C2*log(maxSpec)); */
1155         /* C1/2^8 + 4/log(2.0)*log(maxSpec)/2^8  => C1/2^8 + log(maxSpec)/log(2.0)*4/2^8 => C1/2^8 + log(maxSpec)/log(2.0)/64.0 */
1156 
1157         //minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + CalcLdData(maxSpec)) >> ((DFRACT_BITS-1)-8))) + 1;
1158         tmp = CalcLdData(maxSpec);
1159         if (c1Const>FL2FXCONST_DBL(-1.f)-tmp) {
1160           minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + tmp) >> ((DFRACT_BITS-1)-8))) + 1;
1161         }
1162         else {
1163           minSfMaxQuant[sfbOffs+sfb] = ((INT) (FL2FXCONST_DBL(-1.f) >> ((DFRACT_BITS-1)-8))) + 1;
1164         }
1165 
1166         scfInt = fixMax(scfInt, minSfMaxQuant[sfbOffs+sfb]);
1167 
1168 
1169         /* find better scalefactor with analysis by synthesis */
1170         if (invQuant>0) {
1171           scfInt = FDKaacEnc_improveScf(qcOutChannel->mdctSpectrum+psyOutChannel->sfbOffsets[sfbOffs+sfb],
1172                               quantSpec+psyOutChannel->sfbOffsets[sfbOffs+sfb],
1173                               quantSpecTmp+psyOutChannel->sfbOffsets[sfbOffs+sfb],
1174                               psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb],
1175                               threshLdData, scfInt, minSfMaxQuant[sfbOffs+sfb],
1176                               &sfbDistLdData[sfbOffs+sfb], &minScfCalculated[sfbOffs+sfb],
1177                               dZoneQuantEnable
1178                               );
1179         }
1180         scf[sfbOffs+sfb] = scfInt;
1181       }
1182     }
1183   }
1184 
1185 
1186   if (invQuant>1) {
1187     /* try to decrease scf differences */
1188     FIXP_DBL sfbConstPePart[MAX_GROUPED_SFB];
1189     FIXP_DBL sfbNRelevantLines[MAX_GROUPED_SFB];
1190 
1191     for (i=0; i<psyOutChannel->sfbCnt; i++)
1192       sfbConstPePart[i] = (FIXP_DBL)FDK_INT_MIN;
1193 
1194     FDKaacEnc_calcSfbRelevantLines( sfbFormFactorLdData,
1195                           qcOutChannel->sfbEnergyLdData,
1196                           qcOutChannel->sfbThresholdLdData,
1197                           psyOutChannel->sfbOffsets,
1198                           psyOutChannel->sfbCnt,
1199                           psyOutChannel->sfbPerGroup,
1200                           psyOutChannel->maxSfbPerGroup,
1201                           sfbNRelevantLines);
1202 
1203 
1204     FDKaacEnc_assimilateSingleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
1205                         dZoneQuantEnable,
1206                         scf,
1207                         minSfMaxQuant, sfbDistLdData, sfbConstPePart,
1208                         sfbFormFactorLdData, sfbNRelevantLines, minScfCalculated, 1);
1209 
1210     if(invQuant > 1) {
1211       FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
1212                         dZoneQuantEnable,
1213                         scf,
1214                         minSfMaxQuant, sfbDistLdData, sfbConstPePart,
1215                         sfbFormFactorLdData, sfbNRelevantLines);
1216 
1217       FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
1218                         dZoneQuantEnable,
1219                         scf,
1220                         minSfMaxQuant, sfbDistLdData, sfbConstPePart,
1221                         sfbFormFactorLdData, sfbNRelevantLines);
1222 
1223 
1224       FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
1225                         dZoneQuantEnable,
1226                         scf,
1227                         minSfMaxQuant, sfbDistLdData, sfbConstPePart,
1228                         sfbFormFactorLdData, sfbNRelevantLines);
1229     }
1230   }
1231 
1232 
1233   /* get min scalefac */
1234   minSf = FDK_INT_MAX;
1235   for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) {
1236     for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1237       if (scf[sfbOffs+sfb]!=FDK_INT_MIN)
1238         minSf = fixMin(minSf,scf[sfbOffs+sfb]);
1239     }
1240   }
1241 
1242   /* limit scf delta */
1243   for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) {
1244     for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1245       if ((scf[sfbOffs+sfb] != FDK_INT_MIN) && (minSf+MAX_SCF_DELTA) < scf[sfbOffs+sfb]) {
1246         scf[sfbOffs+sfb] = minSf + MAX_SCF_DELTA;
1247         if (invQuant > 0) { /* changed bands need to be quantized again */
1248           sfbDistLdData[sfbOffs+sfb] =
1249                FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+psyOutChannel->sfbOffsets[sfbOffs+sfb],
1250                                      quantSpec+psyOutChannel->sfbOffsets[sfbOffs+sfb],
1251                                      psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb],
1252                                      scf[sfbOffs+sfb],
1253                                      dZoneQuantEnable
1254                                      );
1255         }
1256       }
1257     }
1258   }
1259 
1260 
1261   /* get max scalefac for global gain */
1262   maxSf = FDK_INT_MIN;
1263   for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) {
1264     for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1265       maxSf = fixMax(maxSf,scf[sfbOffs+sfb]);
1266     }
1267   }
1268 
1269   /* calc loop scalefactors, if spec is not all zero (i.e. maxSf == -99) */
1270   if( maxSf > FDK_INT_MIN ) {
1271     *globalGain = maxSf;
1272     for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) {
1273       for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1274         if( scf[sfbOffs+sfb] == FDK_INT_MIN ) {
1275           scf[sfbOffs+sfb] = 0;
1276           /* set band explicitely to zero */
1277           for(j=psyOutChannel->sfbOffsets[sfbOffs+sfb]; j<psyOutChannel->sfbOffsets[sfbOffs+sfb+1]; j++ ) {
1278             qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f);
1279           }
1280         }
1281         else {
1282           scf[sfbOffs+sfb] = maxSf - scf[sfbOffs+sfb];
1283         }
1284       }
1285     }
1286   }
1287   else{
1288     *globalGain = 0;
1289     /* set spectrum explicitely to zero */
1290     for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) {
1291       for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1292         scf[sfbOffs+sfb] = 0;
1293         /* set band explicitely to zero */
1294         for(j=psyOutChannel->sfbOffsets[sfbOffs+sfb]; j<psyOutChannel->sfbOffsets[sfbOffs+sfb+1]; j++ ) {
1295           qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f);
1296         }
1297       }
1298     }
1299   }
1300 
1301   /* free quantSpecTmp from scratch */
1302   C_ALLOC_SCRATCH_END(quantSpecTmp, SHORT, (1024));
1303 
1304 
1305 }
1306 
1307 void
FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL * psyOutChannel[],QC_OUT_CHANNEL * qcOutChannel[],const int invQuant,const INT dZoneQuantEnable,const int nChannels)1308 FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
1309                      QC_OUT_CHANNEL* qcOutChannel[],
1310                      const int invQuant,
1311                      const INT dZoneQuantEnable,
1312                      const int nChannels)
1313 {
1314   int ch;
1315 
1316   for (ch = 0; ch < nChannels; ch++)
1317   {
1318       FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(qcOutChannel[ch],
1319                                   psyOutChannel[ch],
1320                                   qcOutChannel[ch]->scf,
1321                                   &qcOutChannel[ch]->globalGain,
1322                                   qcOutChannel[ch]->sfbFormFactorLdData
1323                                   ,invQuant,
1324                                   qcOutChannel[ch]->quantSpec,
1325                                   dZoneQuantEnable
1326                                   );
1327   }
1328 
1329 }
1330 
1331