1
2/* -----------------------------------------------------------------------------------------------------------
3Software 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
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                      )
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*/
453static 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*/
628static 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*/
767static 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
1054static void
1055FDKaacEnc_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
1280void
1281FDKaacEnc_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