• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4 
5 � Copyright  1995 - 2013 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)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                       )
368 {
369    FIXP_DBL sfbDistLdData;
370    INT scfBest = scf;
371    INT k;
372    FIXP_DBL distFactorLdData = FL2FXCONST_DBL(-0.0050301265);   /* ld64(1/1.25) */
373 
374    /* calc real distortion */
375    sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
376                                          quantSpec,
377                                          sfbWidth,
378                                          scf);
379    *minScfCalculated = scf;
380    /* nmr > 1.25 -> try to improve nmr */
381    if (sfbDistLdData > (threshLdData-distFactorLdData)) {
382       INT scfEstimated = scf;
383       FIXP_DBL sfbDistBestLdData = sfbDistLdData;
384       INT cnt;
385       /* improve by bigger scf ? */
386       cnt = 0;
387 
388       while ((sfbDistLdData > (threshLdData-distFactorLdData)) && (cnt++ < 3)) {
389          scf++;
390          sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
391                                                quantSpecTmp,
392                                                sfbWidth,
393                                                scf);
394 
395          if (sfbDistLdData < sfbDistBestLdData) {
396             scfBest = scf;
397             sfbDistBestLdData = sfbDistLdData;
398             for (k=0; k<sfbWidth; k++)
399 	             quantSpec[k] = quantSpecTmp[k];
400          }
401       }
402       /* improve by smaller scf ? */
403       cnt = 0;
404       scf = scfEstimated;
405       sfbDistLdData = sfbDistBestLdData;
406       while ((sfbDistLdData > (threshLdData-distFactorLdData)) && (cnt++ < 1) && (scf > minScf)) {
407          scf--;
408          sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
409                                                quantSpecTmp,
410                                                sfbWidth,
411                                                scf);
412 
413          if (sfbDistLdData < sfbDistBestLdData) {
414             scfBest = scf;
415             sfbDistBestLdData = sfbDistLdData;
416             for (k=0; k<sfbWidth; k++)
417 	             quantSpec[k] = quantSpecTmp[k];
418          }
419          *minScfCalculated = scf;
420       }
421       *distLdData = sfbDistBestLdData;
422    }
423    else { /* nmr <= 1.25 -> try to find bigger scf to use less bits */
424       FIXP_DBL sfbDistBestLdData = sfbDistLdData;
425       FIXP_DBL sfbDistAllowedLdData = fixMin(sfbDistLdData-distFactorLdData,threshLdData);
426       int cnt;
427       for (cnt=0; cnt<3; cnt++) {
428          scf++;
429          sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
430                                                quantSpecTmp,
431                                                sfbWidth,
432                                                scf);
433 
434          if (sfbDistLdData < sfbDistAllowedLdData) {
435            *minScfCalculated = scfBest+1;
436            scfBest = scf;
437            sfbDistBestLdData = sfbDistLdData;
438            for (k=0; k<sfbWidth; k++)
439              quantSpec[k] = quantSpecTmp[k];
440          }
441       }
442       *distLdData = sfbDistBestLdData;
443    }
444 
445    /* return best scalefactor */
446    return scfBest;
447 }
448 
449 /*
450   Function: FDKaacEnc_assimilateSingleScf
451 
452 */
FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL * psyOutChan,QC_OUT_CHANNEL * qcOutChannel,SHORT * quantSpec,SHORT * quantSpecTmp,INT * scf,INT * minScf,FIXP_DBL * sfbDist,FIXP_DBL * sfbConstPePart,FIXP_DBL * sfbFormFactorLdData,FIXP_DBL * sfbNRelevantLines,INT * minScfCalculated,INT restartOnSuccess)453 static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,
454                                 QC_OUT_CHANNEL   *qcOutChannel,
455                                 SHORT *quantSpec,
456                                 SHORT *quantSpecTmp,
457                                 INT *scf,
458                                 INT *minScf,
459                                 FIXP_DBL *sfbDist,
460                                 FIXP_DBL *sfbConstPePart,
461                                 FIXP_DBL *sfbFormFactorLdData,
462                                 FIXP_DBL *sfbNRelevantLines,
463                                 INT *minScfCalculated,
464                                 INT restartOnSuccess)
465 {
466   INT sfbLast, sfbAct, sfbNext;
467   INT scfAct, *scfLast, *scfNext, scfMin, scfMax;
468   INT sfbWidth, sfbOffs;
469   FIXP_DBL enLdData;
470   FIXP_DBL sfbPeOld, sfbPeNew;
471   FIXP_DBL sfbDistNew;
472   INT i, k;
473   INT success = 0;
474   FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
475   FIXP_DBL deltaPeNew, deltaPeTmp;
476   INT prevScfLast[MAX_GROUPED_SFB], prevScfNext[MAX_GROUPED_SFB];
477   FIXP_DBL deltaPeLast[MAX_GROUPED_SFB];
478   INT updateMinScfCalculated;
479 
480   for (i=0; i<psyOutChan->sfbCnt; i++) {
481     prevScfLast[i] = FDK_INT_MAX;
482     prevScfNext[i] = FDK_INT_MAX;
483     deltaPeLast[i] = (FIXP_DBL)FDK_INT_MAX;
484   }
485 
486   sfbLast = -1;
487   sfbAct  = -1;
488   sfbNext = -1;
489   scfLast = 0;
490   scfNext = 0;
491   scfMin  = FDK_INT_MAX;
492   scfMax  = FDK_INT_MAX;
493   do {
494     /* search for new relevant sfb */
495     sfbNext++;
496     while ((sfbNext < psyOutChan->sfbCnt) && (scf[sfbNext] == FDK_INT_MIN))
497       sfbNext++;
498     if ((sfbLast>=0) && (sfbAct>=0) && (sfbNext<psyOutChan->sfbCnt)) {
499       /* relevant scfs to the left and to the right */
500       scfAct  = scf[sfbAct];
501       scfLast = scf + sfbLast;
502       scfNext = scf + sfbNext;
503       scfMin  = fixMin(*scfLast, *scfNext);
504       scfMax  = fixMax(*scfLast, *scfNext);
505     }
506     else if ((sfbLast==-1) && (sfbAct>=0) && (sfbNext<psyOutChan->sfbCnt)) {
507       /* first relevant scf */
508       scfAct  = scf[sfbAct];
509       scfLast = &scfAct;
510       scfNext = scf + sfbNext;
511       scfMin  = *scfNext;
512       scfMax  = *scfNext;
513     }
514     else if ((sfbLast>=0) && (sfbAct>=0) && (sfbNext==psyOutChan->sfbCnt)) {
515       /* last relevant scf */
516       scfAct  = scf[sfbAct];
517       scfLast = scf + sfbLast;
518       scfNext = &scfAct;
519       scfMin  = *scfLast;
520       scfMax  = *scfLast;
521     }
522     if (sfbAct>=0)
523       scfMin = fixMax(scfMin, minScf[sfbAct]);
524 
525     if ((sfbAct >= 0) &&
526         (sfbLast>=0 || sfbNext<psyOutChan->sfbCnt) &&
527         (scfAct > scfMin) &&
528         (scfAct <= scfMin+MAX_SCF_DELTA) &&
529         (scfAct >= scfMax-MAX_SCF_DELTA) &&
530         (*scfLast != prevScfLast[sfbAct] ||
531          *scfNext != prevScfNext[sfbAct] ||
532          deltaPe < deltaPeLast[sfbAct])) {
533       /* bigger than neighbouring scf found, try to use smaller scf */
534       success = 0;
535 
536       sfbWidth = psyOutChan->sfbOffsets[sfbAct+1] - psyOutChan->sfbOffsets[sfbAct];
537       sfbOffs = psyOutChan->sfbOffsets[sfbAct];
538 
539       /* estimate required bits for actual scf */
540       enLdData = qcOutChannel->sfbEnergyLdData[sfbAct];
541 
542       /* sfbConstPePart[sfbAct] = (float)log(6.75f*en/sfbFormFactor[sfbAct]) * LOG2_1; */
543       /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for log2 */
544       /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
545       if (sfbConstPePart[sfbAct] == (FIXP_DBL)FDK_INT_MIN) {
546         sfbConstPePart[sfbAct] = ((enLdData - sfbFormFactorLdData[sfbAct] - FL2FXCONST_DBL(0.09375f)) >> 1) + FL2FXCONST_DBL(0.02152255861f);
547       }
548 
549       sfbPeOld = FDKaacEnc_calcSingleSpecPe(scfAct,sfbConstPePart[sfbAct],sfbNRelevantLines[sfbAct])
550                 +FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext);
551 
552       deltaPeNew = deltaPe;
553       updateMinScfCalculated = 1;
554 
555       do {
556         /* estimate required bits for smaller scf */
557         scfAct--;
558         /* check only if the same check was not done before */
559         if (scfAct < minScfCalculated[sfbAct] && scfAct>=scfMax-MAX_SCF_DELTA){
560           /* estimate required bits for new scf */
561           sfbPeNew =  FDKaacEnc_calcSingleSpecPe(scfAct,sfbConstPePart[sfbAct],sfbNRelevantLines[sfbAct])
562                      +FDKaacEnc_countSingleScfBits(scfAct,*scfLast, *scfNext);
563 
564           /* use new scf if no increase in pe and
565              quantization error is smaller */
566           deltaPeTmp = deltaPe + sfbPeNew - sfbPeOld;
567           /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
568           if (deltaPeTmp < FL2FXCONST_DBL(0.0006103515625f)) {
569             /* distortion of new scf */
570             sfbDistNew = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs,
571                                                quantSpecTmp+sfbOffs,
572                                                sfbWidth,
573                                                scfAct);
574 
575             if (sfbDistNew < sfbDist[sfbAct]) {
576               /* success, replace scf by new one */
577               scf[sfbAct] = scfAct;
578               sfbDist[sfbAct] = sfbDistNew;
579 
580               for (k=0; k<sfbWidth; k++)
581                 quantSpec[sfbOffs+k] = quantSpecTmp[sfbOffs+k];
582 
583               deltaPeNew = deltaPeTmp;
584               success = 1;
585             }
586             /* mark as already checked */
587             if (updateMinScfCalculated)
588               minScfCalculated[sfbAct] = scfAct;
589           }
590           else {
591             /* from this scf value on not all new values have been checked */
592             updateMinScfCalculated = 0;
593           }
594         }
595       } while (scfAct > scfMin);
596 
597       deltaPe = deltaPeNew;
598 
599       /* save parameters to avoid multiple computations of the same sfb */
600       prevScfLast[sfbAct] = *scfLast;
601       prevScfNext[sfbAct] = *scfNext;
602       deltaPeLast[sfbAct] = deltaPe;
603     }
604 
605     if (success && restartOnSuccess) {
606       /* start again at first sfb */
607       sfbLast = -1;
608       sfbAct  = -1;
609       sfbNext = -1;
610       scfLast = 0;
611       scfNext = 0;
612       scfMin  = FDK_INT_MAX;
613       scfMax  = FDK_INT_MAX;
614       success = 0;
615     }
616     else {
617       /* shift sfbs for next band */
618       sfbLast = sfbAct;
619       sfbAct  = sfbNext;
620     }
621   } while (sfbNext < psyOutChan->sfbCnt);
622 }
623 
624 /*
625   Function: FDKaacEnc_assimilateMultipleScf
626 
627 */
FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL * psyOutChan,QC_OUT_CHANNEL * qcOutChannel,SHORT * quantSpec,SHORT * quantSpecTmp,INT * scf,INT * minScf,FIXP_DBL * sfbDist,FIXP_DBL * sfbConstPePart,FIXP_DBL * sfbFormFactorLdData,FIXP_DBL * sfbNRelevantLines)628 static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan,
629                                   QC_OUT_CHANNEL  *qcOutChannel,
630                                   SHORT *quantSpec,
631                                   SHORT *quantSpecTmp,
632                                   INT *scf,
633                                   INT *minScf,
634                                   FIXP_DBL *sfbDist,
635                                   FIXP_DBL *sfbConstPePart,
636                                   FIXP_DBL *sfbFormFactorLdData,
637                                   FIXP_DBL *sfbNRelevantLines)
638 {
639   INT sfb, startSfb, stopSfb;
640   INT scfTmp[MAX_GROUPED_SFB], scfMin, scfMax, scfAct;
641   INT possibleRegionFound;
642   INT sfbWidth, sfbOffs, i, k;
643   FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], distOldSum, distNewSum;
644   INT deltaScfBits;
645   FIXP_DBL deltaSpecPe;
646   FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
647   FIXP_DBL deltaPeNew;
648   INT sfbCnt = psyOutChan->sfbCnt;
649 
650   /* calc min and max scalfactors */
651   scfMin = FDK_INT_MAX;
652   scfMax = FDK_INT_MIN;
653   for (sfb=0; sfb<sfbCnt; sfb++) {
654     if (scf[sfb]!=FDK_INT_MIN) {
655       scfMin = fixMin(scfMin, scf[sfb]);
656       scfMax = fixMax(scfMax, scf[sfb]);
657     }
658   }
659 
660   if (scfMax != FDK_INT_MIN && scfMax <= scfMin+MAX_SCF_DELTA) {
661 
662     scfAct = scfMax;
663 
664     do {
665       /* try smaller scf */
666       scfAct--;
667       for (i=0; i<MAX_GROUPED_SFB; i++)
668         scfTmp[i] = scf[i];
669       stopSfb = 0;
670       do {
671         /* search for region where all scfs are bigger than scfAct */
672         sfb = stopSfb;
673         while (sfb<sfbCnt && (scf[sfb]==FDK_INT_MIN || scf[sfb] <= scfAct))
674           sfb++;
675         startSfb = sfb;
676         sfb++;
677         while (sfb<sfbCnt && (scf[sfb]==FDK_INT_MIN || scf[sfb] > scfAct))
678           sfb++;
679         stopSfb = sfb;
680 
681         /* check if in all sfb of a valid region scfAct >= minScf[sfb] */
682         possibleRegionFound = 0;
683         if (startSfb < sfbCnt) {
684           possibleRegionFound = 1;
685           for (sfb=startSfb; sfb<stopSfb; sfb++) {
686             if (scf[sfb] != FDK_INT_MIN)
687               if (scfAct < minScf[sfb]) {
688                 possibleRegionFound = 0;
689                 break;
690               }
691           }
692         }
693 
694         if (possibleRegionFound) { /* region found */
695 
696           /* replace scfs in region by scfAct */
697           for (sfb=startSfb; sfb<stopSfb; sfb++) {
698             if (scfTmp[sfb] != FDK_INT_MIN)
699               scfTmp[sfb] = scfAct;
700           }
701 
702           /* estimate change in bit demand for new scfs */
703           deltaScfBits = FDKaacEnc_countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb);
704 
705           deltaSpecPe = FDKaacEnc_calcSpecPeDiff(psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
706                                        sfbFormFactorLdData, sfbNRelevantLines,
707                                        startSfb, stopSfb);
708 
709           deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
710 
711           /* new bit demand small enough ? */
712           /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
713           if (deltaPeNew < FL2FXCONST_DBL(0.0006103515625f)) {
714 
715             /* quantize and calc sum of new distortion */
716             distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
717             for (sfb=startSfb; sfb<stopSfb; sfb++) {
718               if (scfTmp[sfb] != FDK_INT_MIN) {
719                 distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
720 
721                 sfbWidth = psyOutChan->sfbOffsets[sfb+1] - psyOutChan->sfbOffsets[sfb];
722                 sfbOffs = psyOutChan->sfbOffsets[sfb];
723 
724                 sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs,
725                                               quantSpecTmp+sfbOffs,
726                                               sfbWidth,
727                                               scfAct);
728 
729                 if (sfbDistNew[sfb] >qcOutChannel->sfbThresholdLdData[sfb]) {
730                   /* no improvement, skip further dist. calculations */
731                   distNewSum = distOldSum << 1;
732                   break;
733                 }
734                 distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
735               }
736             }
737             /* distortion smaller ? -> use new scalefactors */
738             if (distNewSum < distOldSum) {
739               deltaPe = deltaPeNew;
740               for (sfb=startSfb; sfb<stopSfb; sfb++) {
741                 if (scf[sfb] != FDK_INT_MIN) {
742                   sfbWidth = psyOutChan->sfbOffsets[sfb+1] -
743                              psyOutChan->sfbOffsets[sfb];
744                   sfbOffs = psyOutChan->sfbOffsets[sfb];
745                   scf[sfb] = scfAct;
746                   sfbDist[sfb] = sfbDistNew[sfb];
747 
748                   for (k=0; k<sfbWidth; k++)
749                     quantSpec[sfbOffs+k] = quantSpecTmp[sfbOffs+k];
750                 }
751               }
752             }
753 
754           }
755         }
756 
757       } while (stopSfb <= sfbCnt);
758 
759     } while (scfAct > scfMin);
760   }
761 }
762 
763 /*
764   Function: FDKaacEnc_FDKaacEnc_assimilateMultipleScf2
765 
766 */
FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL * psyOutChan,QC_OUT_CHANNEL * qcOutChannel,SHORT * quantSpec,SHORT * quantSpecTmp,INT * scf,INT * minScf,FIXP_DBL * sfbDist,FIXP_DBL * sfbConstPePart,FIXP_DBL * sfbFormFactorLdData,FIXP_DBL * sfbNRelevantLines)767 static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutChan,
768                                    QC_OUT_CHANNEL  *qcOutChannel,
769                                    SHORT *quantSpec,
770                                    SHORT *quantSpecTmp,
771                                    INT *scf,
772                                    INT *minScf,
773                                    FIXP_DBL *sfbDist,
774                                    FIXP_DBL *sfbConstPePart,
775                                    FIXP_DBL *sfbFormFactorLdData,
776                                    FIXP_DBL *sfbNRelevantLines)
777 {
778   INT sfb, startSfb, stopSfb;
779   INT scfTmp[MAX_GROUPED_SFB], scfAct, scfNew;
780   INT scfPrev, scfNext, scfPrevNextMin, scfPrevNextMax, scfLo, scfHi;
781   INT scfMin, scfMax;
782   INT *sfbOffs = psyOutChan->sfbOffsets;
783   FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], sfbDistMax[MAX_GROUPED_SFB];
784   FIXP_DBL distOldSum, distNewSum;
785   INT deltaScfBits;
786   FIXP_DBL deltaSpecPe;
787   FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
788   FIXP_DBL deltaPeNew = FL2FXCONST_DBL(0.0f);
789   INT sfbCnt = psyOutChan->sfbCnt;
790   INT bSuccess, bCheckScf;
791   INT i,k;
792 
793   /* calc min and max scalfactors */
794   scfMin = FDK_INT_MAX;
795   scfMax = FDK_INT_MIN;
796   for (sfb=0; sfb<sfbCnt; sfb++) {
797     if (scf[sfb]!=FDK_INT_MIN) {
798       scfMin = fixMin(scfMin, scf[sfb]);
799       scfMax = fixMax(scfMax, scf[sfb]);
800     }
801   }
802 
803   stopSfb = 0;
804   scfAct = FDK_INT_MIN;
805   do {
806     /* search for region with same scf values scfAct */
807     scfPrev = scfAct;
808 
809     sfb = stopSfb;
810     while (sfb<sfbCnt && (scf[sfb]==FDK_INT_MIN))
811       sfb++;
812     startSfb = sfb;
813     scfAct = scf[startSfb];
814     sfb++;
815     while (sfb<sfbCnt && ((scf[sfb]==FDK_INT_MIN) || (scf[sfb]==scf[startSfb])))
816       sfb++;
817     stopSfb = sfb;
818 
819     if (stopSfb < sfbCnt)
820       scfNext = scf[stopSfb];
821     else
822       scfNext = scfAct;
823 
824     if (scfPrev == FDK_INT_MIN)
825       scfPrev = scfAct;
826 
827     scfPrevNextMax = fixMax(scfPrev, scfNext);
828     scfPrevNextMin = fixMin(scfPrev, scfNext);
829 
830     /* try to reduce bits by checking scf values in the range
831        scf[startSfb]...scfHi */
832     scfHi = fixMax(scfPrevNextMax, scfAct);
833     /* try to find a better solution by reducing the scf difference to
834        the nearest possible lower scf */
835     if (scfPrevNextMax >= scfAct)
836       scfLo = fixMin(scfAct, scfPrevNextMin);
837     else
838       scfLo = scfPrevNextMax;
839 
840     if (startSfb < sfbCnt && scfHi-scfLo <= MAX_SCF_DELTA) { /* region found */
841       /* 1. try to save bits by coarser quantization */
842       if (scfHi > scf[startSfb]) {
843         /* calculate the allowed distortion */
844         for (sfb=startSfb; sfb<stopSfb; sfb++) {
845           if (scf[sfb] != FDK_INT_MIN) {
846             /* sfbDistMax[sfb] = (float)pow(qcOutChannel->sfbThreshold[sfb]*sfbDist[sfb]*sfbDist[sfb],1.0f/3.0f); */
847             /* sfbDistMax[sfb] = fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergy[sfb]*FL2FXCONST_DBL(1.e-3f)); */
848             /* -0.15571537944 = ld64(1.e-3f)*/
849             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]);
850             sfbDistMax[sfb] = fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergyLdData[sfb]-FL2FXCONST_DBL(0.15571537944));
851             sfbDistMax[sfb] = fixMin(sfbDistMax[sfb],qcOutChannel->sfbThresholdLdData[sfb]);
852           }
853         }
854 
855         /* loop over all possible scf values for this region */
856         bCheckScf = 1;
857         for (scfNew=scf[startSfb]+1; scfNew<=scfHi; scfNew++) {
858 	         for (k=0; k<MAX_GROUPED_SFB; k++)
859             scfTmp[k] = scf[k];
860 
861           /* replace scfs in region by scfNew */
862           for (sfb=startSfb; sfb<stopSfb; sfb++) {
863             if (scfTmp[sfb] != FDK_INT_MIN)
864               scfTmp[sfb] = scfNew;
865           }
866 
867           /* estimate change in bit demand for new scfs */
868           deltaScfBits = FDKaacEnc_countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb);
869 
870           deltaSpecPe = FDKaacEnc_calcSpecPeDiff(psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
871                                        sfbFormFactorLdData, sfbNRelevantLines,
872                                        startSfb, stopSfb);
873 
874           deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
875 
876           /* new bit demand small enough ? */
877           if (deltaPeNew < FL2FXCONST_DBL(0.0f)) {
878             bSuccess = 1;
879 
880             /* quantize and calc sum of new distortion */
881             for (sfb=startSfb; sfb<stopSfb; sfb++) {
882               if (scfTmp[sfb] != FDK_INT_MIN) {
883                 sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb],
884                                               quantSpecTmp+sfbOffs[sfb],
885                                               sfbOffs[sfb+1]-sfbOffs[sfb],
886                                               scfNew);
887 
888                 if (sfbDistNew[sfb] > sfbDistMax[sfb]) {
889                   /* no improvement, skip further dist. calculations */
890                   bSuccess = 0;
891                   if (sfbDistNew[sfb] == qcOutChannel->sfbEnergyLdData[sfb]) {
892                     /* if whole sfb is already quantized to 0, further
893                        checks with even coarser quant. are useless*/
894                     bCheckScf = 0;
895                   }
896                   break;
897                 }
898               }
899             }
900             if (bCheckScf==0) /* further calculations useless ? */
901                 break;
902             /* distortion small enough ? -> use new scalefactors */
903             if (bSuccess) {
904               deltaPe = deltaPeNew;
905               for (sfb=startSfb; sfb<stopSfb; sfb++) {
906                 if (scf[sfb] != FDK_INT_MIN) {
907                   scf[sfb] = scfNew;
908                   sfbDist[sfb] = sfbDistNew[sfb];
909 
910                   for (k=0; k<sfbOffs[sfb+1]-sfbOffs[sfb]; k++)
911                     quantSpec[sfbOffs[sfb]+k] = quantSpecTmp[sfbOffs[sfb]+k];
912                 }
913               }
914             }
915           }
916         }
917       }
918 
919       /* 2. only if coarser quantization was not successful, try to find
920          a better solution by finer quantization and reducing bits for
921          scalefactor coding */
922       if (scfAct==scf[startSfb] &&
923           scfLo < scfAct &&
924           scfMax-scfMin <= MAX_SCF_DELTA) {
925 
926         int bminScfViolation = 0;
927 
928         for (k=0; k<MAX_GROUPED_SFB; k++)
929           scfTmp[k] = scf[k];
930 
931         scfNew = scfLo;
932 
933         /* replace scfs in region by scfNew and
934            check if in all sfb scfNew >= minScf[sfb] */
935         for (sfb=startSfb; sfb<stopSfb; sfb++) {
936           if (scfTmp[sfb] != FDK_INT_MIN) {
937             scfTmp[sfb] = scfNew;
938             if (scfNew < minScf[sfb])
939               bminScfViolation = 1;
940           }
941         }
942 
943         if (!bminScfViolation) {
944           /* estimate change in bit demand for new scfs */
945           deltaScfBits = FDKaacEnc_countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb);
946 
947           deltaSpecPe = FDKaacEnc_calcSpecPeDiff(psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
948                                        sfbFormFactorLdData, sfbNRelevantLines,
949                                        startSfb, stopSfb);
950 
951           deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
952         }
953 
954         /* new bit demand small enough ? */
955         if (!bminScfViolation && deltaPeNew < FL2FXCONST_DBL(0.0f)) {
956 
957           /* quantize and calc sum of new distortion */
958           distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
959           for (sfb=startSfb; sfb<stopSfb; sfb++) {
960             if (scfTmp[sfb] != FDK_INT_MIN) {
961               distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
962 
963               sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb],
964                                                       quantSpecTmp+sfbOffs[sfb],
965                                                       sfbOffs[sfb+1]-sfbOffs[sfb],
966                                                       scfNew);
967 
968               if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) {
969                 /* no improvement, skip further dist. calculations */
970                 distNewSum = distOldSum << 1;
971                 break;
972               }
973               distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
974             }
975           }
976           /* distortion smaller ? -> use new scalefactors */
977           if (distNewSum < fMult(FL2FXCONST_DBL(0.8f),distOldSum)) {
978             deltaPe = deltaPeNew;
979             for (sfb=startSfb; sfb<stopSfb; sfb++) {
980               if (scf[sfb] != FDK_INT_MIN) {
981                 scf[sfb] = scfNew;
982                 sfbDist[sfb] = sfbDistNew[sfb];
983 
984                 for (k=0; k<sfbOffs[sfb+1]-sfbOffs[sfb]; k++)
985                   quantSpec[sfbOffs[sfb]+k] = quantSpecTmp[sfbOffs[sfb]+k];
986               }
987             }
988           }
989         }
990       }
991 
992       /* 3. try to find a better solution (save bits) by only reducing the
993          scalefactor without new quantization */
994       if (scfMax-scfMin <= MAX_SCF_DELTA-3) { /* 3 bec. scf is reduced 3 times,
995                                                  see for loop below */
996 
997         for (k=0; k<sfbCnt; k++)
998           scfTmp[k] = scf[k];
999 
1000         for (i=0; i<3; i++) {
1001           scfNew = scfTmp[startSfb]-1;
1002           /* replace scfs in region by scfNew */
1003           for (sfb=startSfb; sfb<stopSfb; sfb++) {
1004             if (scfTmp[sfb] != FDK_INT_MIN)
1005               scfTmp[sfb] = scfNew;
1006           }
1007           /* estimate change in bit demand for new scfs */
1008           deltaScfBits = FDKaacEnc_countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb);
1009           deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits;
1010           /* new bit demand small enough ? */
1011           if (deltaPeNew <= FL2FXCONST_DBL(0.0f)) {
1012 
1013             bSuccess = 1;
1014             distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
1015             for (sfb=startSfb; sfb<stopSfb; sfb++) {
1016               if (scfTmp[sfb] != FDK_INT_MIN) {
1017                 FIXP_DBL sfbEnQ;
1018                 /* calc the energy and distortion of the quantized spectrum for
1019                    a smaller scf */
1020                 FDKaacEnc_calcSfbQuantEnergyAndDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb],
1021                                           quantSpec+sfbOffs[sfb],
1022                                           sfbOffs[sfb+1]-sfbOffs[sfb], scfNew,
1023                                           &sfbEnQ, &sfbDistNew[sfb]);
1024 
1025                 distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
1026                 distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
1027 
1028                 /*  0.00259488556167 = ld64(1.122f) */
1029                 /* -0.00778722686652 = ld64(0.7079f) */
1030                 if ((sfbDistNew[sfb] > (sfbDist[sfb]+FL2FXCONST_DBL(0.00259488556167f))) || (sfbEnQ < (qcOutChannel->sfbEnergyLdData[sfb] - FL2FXCONST_DBL(0.00778722686652f)))){
1031                   bSuccess = 0;
1032                   break;
1033                 }
1034               }
1035             }
1036             /* distortion smaller ? -> use new scalefactors */
1037             if (distNewSum < distOldSum && bSuccess) {
1038               deltaPe = deltaPeNew;
1039               for (sfb=startSfb; sfb<stopSfb; sfb++) {
1040                 if (scf[sfb] != FDK_INT_MIN) {
1041                   scf[sfb] = scfNew;
1042                   sfbDist[sfb] = sfbDistNew[sfb];
1043                 }
1044               }
1045             }
1046           }
1047         }
1048       }
1049     }
1050   } while (stopSfb <= sfbCnt);
1051 
1052 }
1053 
1054 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)1055 FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL   *qcOutChannel,
1056                             PSY_OUT_CHANNEL  *psyOutChannel,
1057                             INT *RESTRICT scf,
1058                             INT *RESTRICT globalGain,
1059                             FIXP_DBL *RESTRICT sfbFormFactorLdData
1060                             ,const INT invQuant,
1061                             SHORT *RESTRICT quantSpec
1062                             )
1063 {
1064   INT i, j, sfb, sfbOffs;
1065   INT scfInt;
1066   INT maxSf;
1067   INT minSf;
1068   FIXP_DBL threshLdData;
1069   FIXP_DBL energyLdData;
1070   FIXP_DBL energyPartLdData;
1071   FIXP_DBL thresholdPartLdData;
1072   FIXP_DBL scfFract;
1073   FIXP_DBL maxSpec;
1074   FIXP_DBL absSpec;
1075   INT minScfCalculated[MAX_GROUPED_SFB];
1076   FIXP_DBL sfbDistLdData[MAX_GROUPED_SFB];
1077   C_ALLOC_SCRATCH_START(quantSpecTmp, SHORT, (1024));
1078   INT minSfMaxQuant[MAX_GROUPED_SFB];
1079 
1080   FIXP_DBL threshConstLdData=FL2FXCONST_DBL(0.04304511722f); /* log10(6.75)/log10(2.0)/64.0 */
1081   FIXP_DBL convConst=FL2FXCONST_DBL(0.30102999566f); /* log10(2.0) */
1082   FIXP_DBL c1Const=FL2FXCONST_DBL(-0.27083183594f); /* C1 = -69.33295 => C1/2^8 */
1083 
1084 
1085 
1086   if (invQuant>0) {
1087     FDKmemclear(quantSpec, (1024)*sizeof(SHORT));
1088   }
1089 
1090   /* scfs without energy or with thresh>energy are marked with FDK_INT_MIN */
1091   for(i=0; i<psyOutChannel->sfbCnt; i++) {
1092     scf[i] = FDK_INT_MIN;
1093   }
1094 
1095   for (i=0; i<MAX_GROUPED_SFB; i++) {
1096     minSfMaxQuant[i] = FDK_INT_MIN;
1097   }
1098 
1099   for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) {
1100     for(sfb=0; sfb<psyOutChannel->maxSfbPerGroup; sfb++) {
1101 
1102       threshLdData = qcOutChannel->sfbThresholdLdData[sfbOffs+sfb];
1103       energyLdData = qcOutChannel->sfbEnergyLdData[sfbOffs+sfb];
1104 
1105       sfbDistLdData[sfbOffs+sfb] = energyLdData;
1106 
1107 
1108       if (energyLdData > threshLdData) {
1109         FIXP_DBL tmp;
1110 
1111         /* energyPart = (float)log10(sfbFormFactor[sfbOffs+sfb]); */
1112         /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
1113         energyPartLdData = sfbFormFactorLdData[sfbOffs+sfb] + FL2FXCONST_DBL(0.09375f);
1114 
1115         /* influence of allowed distortion */
1116         /* thresholdPart = (float)log10(6.75*thresh+FLT_MIN); */
1117         thresholdPartLdData = threshConstLdData + threshLdData;
1118 
1119         /* scf calc */
1120         /* scfFloat = 8.8585f * (thresholdPart - energyPart); */
1121         scfFract = thresholdPartLdData - energyPartLdData;
1122         /* conversion from log2 to log10 */
1123         scfFract = fMult(convConst,scfFract);
1124         /* (8.8585f * scfFract)/8 = 8/8 * scfFract + 0.8585 * scfFract/8 */
1125         scfFract = scfFract + fMult(FL2FXCONST_DBL(0.8585f),scfFract >> 3);
1126 
1127         /* integer scalefactor */
1128         /* scfInt = (int)floor(scfFloat); */
1129         scfInt = (INT)(scfFract>>((DFRACT_BITS-1)-3-LD_DATA_SHIFT)); /* 3 bits => scfFract/8.0; 6 bits => ld64 */
1130 
1131         /* maximum of spectrum */
1132         maxSpec = FL2FXCONST_DBL(0.0f);
1133 
1134         for(j=psyOutChannel->sfbOffsets[sfbOffs+sfb]; j<psyOutChannel->sfbOffsets[sfbOffs+sfb+1]; j++ ){
1135           absSpec = fixp_abs(qcOutChannel->mdctSpectrum[j]);
1136           maxSpec = (absSpec > maxSpec) ? absSpec : maxSpec;
1137         }
1138 
1139         /* lower scf limit to avoid quantized values bigger than MAX_QUANT */
1140         /* C1 = -69.33295f, C2 = 5.77078f = 4/log(2) */
1141         /* minSfMaxQuant[sfbOffs+sfb] = (int)ceil(C1 + C2*log(maxSpec)); */
1142         /* 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 */
1143 
1144         //minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + CalcLdData(maxSpec)) >> ((DFRACT_BITS-1)-8))) + 1;
1145         tmp = CalcLdData(maxSpec);
1146         if (c1Const>FL2FXCONST_DBL(-1.f)-tmp) {
1147           minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + tmp) >> ((DFRACT_BITS-1)-8))) + 1;
1148         }
1149         else {
1150           minSfMaxQuant[sfbOffs+sfb] = ((INT) (FL2FXCONST_DBL(-1.f) >> ((DFRACT_BITS-1)-8))) + 1;
1151         }
1152 
1153         scfInt = fixMax(scfInt, minSfMaxQuant[sfbOffs+sfb]);
1154 
1155 
1156         /* find better scalefactor with analysis by synthesis */
1157         if (invQuant>0) {
1158           scfInt = FDKaacEnc_improveScf(qcOutChannel->mdctSpectrum+psyOutChannel->sfbOffsets[sfbOffs+sfb],
1159                               quantSpec+psyOutChannel->sfbOffsets[sfbOffs+sfb],
1160                               quantSpecTmp+psyOutChannel->sfbOffsets[sfbOffs+sfb],
1161                               psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb],
1162                               threshLdData, scfInt, minSfMaxQuant[sfbOffs+sfb],
1163                               &sfbDistLdData[sfbOffs+sfb], &minScfCalculated[sfbOffs+sfb]
1164                               );
1165         }
1166         scf[sfbOffs+sfb] = scfInt;
1167       }
1168     }
1169   }
1170 
1171 
1172   if (invQuant>1) {
1173     /* try to decrease scf differences */
1174     FIXP_DBL sfbConstPePart[MAX_GROUPED_SFB];
1175     FIXP_DBL sfbNRelevantLines[MAX_GROUPED_SFB];
1176 
1177     for (i=0; i<psyOutChannel->sfbCnt; i++)
1178       sfbConstPePart[i] = (FIXP_DBL)FDK_INT_MIN;
1179 
1180     FDKaacEnc_calcSfbRelevantLines( sfbFormFactorLdData,
1181                           qcOutChannel->sfbEnergyLdData,
1182                           qcOutChannel->sfbThresholdLdData,
1183                           psyOutChannel->sfbOffsets,
1184                           psyOutChannel->sfbCnt,
1185                           psyOutChannel->sfbPerGroup,
1186                           psyOutChannel->maxSfbPerGroup,
1187                           sfbNRelevantLines);
1188 
1189 
1190     FDKaacEnc_assimilateSingleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, scf,
1191                         minSfMaxQuant, sfbDistLdData, sfbConstPePart,
1192                         sfbFormFactorLdData, sfbNRelevantLines, minScfCalculated, 1);
1193 
1194 
1195     FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, scf,
1196                           minSfMaxQuant, sfbDistLdData, sfbConstPePart,
1197                           sfbFormFactorLdData, sfbNRelevantLines);
1198 
1199 
1200     FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, scf,
1201                            minSfMaxQuant, sfbDistLdData, sfbConstPePart,
1202                            sfbFormFactorLdData, sfbNRelevantLines);
1203 
1204   }
1205 
1206 
1207   /* get min scalefac */
1208   minSf = FDK_INT_MAX;
1209   for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) {
1210     for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1211       if (scf[sfbOffs+sfb]!=FDK_INT_MIN)
1212         minSf = fixMin(minSf,scf[sfbOffs+sfb]);
1213     }
1214   }
1215 
1216   /* limit scf delta */
1217   for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) {
1218     for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1219       if ((scf[sfbOffs+sfb] != FDK_INT_MIN) && (minSf+MAX_SCF_DELTA) < scf[sfbOffs+sfb]) {
1220         scf[sfbOffs+sfb] = minSf + MAX_SCF_DELTA;
1221         if (invQuant > 0) { /* changed bands need to be quantized again */
1222           sfbDistLdData[sfbOffs+sfb] =
1223                FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+psyOutChannel->sfbOffsets[sfbOffs+sfb],
1224                                      quantSpec+psyOutChannel->sfbOffsets[sfbOffs+sfb],
1225                                      psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb],
1226                                      scf[sfbOffs+sfb]
1227                                      );
1228         }
1229       }
1230     }
1231   }
1232 
1233 
1234   /* get max scalefac for global gain */
1235   maxSf = FDK_INT_MIN;
1236   for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) {
1237     for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
1238       maxSf = fixMax(maxSf,scf[sfbOffs+sfb]);
1239     }
1240   }
1241 
1242   /* calc loop scalefactors, if spec is not all zero (i.e. maxSf == -99) */
1243   if( maxSf > FDK_INT_MIN ) {
1244     *globalGain = maxSf;
1245     for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; 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]; j<psyOutChannel->sfbOffsets[sfbOffs+sfb+1]; j++ ) {
1251             qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f);
1252           }
1253         }
1254         else {
1255           scf[sfbOffs+sfb] = maxSf - scf[sfbOffs+sfb];
1256         }
1257       }
1258     }
1259   }
1260   else{
1261     *globalGain = 0;
1262     /* set spectrum explicitely to zero */
1263     for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; 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]; j<psyOutChannel->sfbOffsets[sfbOffs+sfb+1]; j++ ) {
1268           qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f);
1269         }
1270       }
1271     }
1272   }
1273 
1274   /* free quantSpecTmp from scratch */
1275   C_ALLOC_SCRATCH_END(quantSpecTmp, SHORT, (1024));
1276 
1277 
1278 }
1279 
1280 void
FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL * psyOutChannel[],QC_OUT_CHANNEL * qcOutChannel[],const int invQuant,const int nChannels)1281 FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
1282                      QC_OUT_CHANNEL* qcOutChannel[],
1283                      const int invQuant,
1284                      const int nChannels)
1285 {
1286   int ch;
1287 
1288   for (ch = 0; ch < nChannels; ch++)
1289   {
1290       FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(qcOutChannel[ch],
1291                                   psyOutChannel[ch],
1292                                   qcOutChannel[ch]->scf,
1293                                   &qcOutChannel[ch]->globalGain,
1294                                   qcOutChannel[ch]->sfbFormFactorLdData
1295                                   ,invQuant,
1296                                   qcOutChannel[ch]->quantSpec
1297                                   );
1298   }
1299 
1300 }
1301 
1302