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