1
2/* -----------------------------------------------------------------------------------------------------------
3Software 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
9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16of the MPEG specifications.
17
18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20individually for the purpose of encoding or decoding bit streams in products that are compliant with
21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27applications information and documentation.
28
292.    COPYRIGHT LICENSE
30
31Redistribution and use in source and binary forms, with or without modification, are permitted without
32payment of copyright license fees provided that you satisfy the following conditions:
33
34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35your modifications thereto in source code form.
36
37You must retain the complete text of this software license in the documentation and/or other materials
38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40modifications thereto to recipients of copies in binary form.
41
42The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43prior written permission.
44
45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46software or your modifications thereto.
47
48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49and 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
533.    NO PATENT LICENSE
54
55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57respect to this software.
58
59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60by appropriate patent licenses.
61
624.    DISCLAIMER
63
64This 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
66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69or business interruption, however caused and on any theory of liability, whether in contract, strict
70liability, or tort (including negligence), arising in any way out of the use of this software, even if
71advised of the possibility of such damage.
72
735.    CONTACT INFORMATION
74
75Fraunhofer Institute for Integrated Circuits IIS
76Attention: Audio and Multimedia Departments - FDK AAC LL
77Am Wolfsmantel 33
7891058 Erlangen, Germany
79
80www.iis.fraunhofer.de/amm
81amm-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)
102static const INT MAX_SCF_DELTA = 60;
103
104
105static const FIXP_DBL PE_C1 = FL2FXCONST_DBL(3.0f/AS_PE_FAC_FLOAT);          /* (log(8.0)/log(2)) >> AS_PE_FAC_SHIFT */
106static const FIXP_DBL PE_C2 = FL2FXCONST_DBL(1.3219281f/AS_PE_FAC_FLOAT);    /* (log(2.5)/log(2)) >> AS_PE_FAC_SHIFT */
107static 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*/
118static void
119FDKaacEnc_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
150void
151FDKaacEnc_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*/
168static void
169FDKaacEnc_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*/
214static 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*/
231static 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*/
256static 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*/
304static 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*/
358static 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*/
458static 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*/
635static 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*/
776static 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
1066static void
1067FDKaacEnc_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
1307void
1308FDKaacEnc_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