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