2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
5 © Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
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.
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.
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.
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.
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:
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.
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.
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
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.
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."
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.
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
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.
73 5. CONTACT INFORMATION
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
78 91058 Erlangen, Germany
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
84 /******************************** MPEG Audio Encoder **************************
86 Initial author: M. Werner
87 contents/description: Scale factor estimation
89 ******************************************************************************/
92 #include "aacEnc_rom.h"
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;
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 */
111 Function; FDKaacEnc_FDKaacEnc_CalcFormFactorChannel
113 Description: Calculates the formfactor
115 sf: scale factor of the mdct spectrum
116 sfbFormFactorLdData is scaled with the factor 1/(((2^sf)^0.5) * (2^FORM_FAC_SHIFT))
119 FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(FIXP_DBL
*RESTRICT sfbFormFactorLdData
,
120 PSY_OUT_CHANNEL
*RESTRICT psyOutChan
)
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
;
135 sfbFormFactorLdData
[sfbGrp
+sfb
] = CalcLdData(formFactor
);
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
);
145 Function: FDKaacEnc_CalcFormFactor
147 Description: Calls FDKaacEnc_FDKaacEnc_CalcFormFactorChannel() for each channel
151 FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL
*qcOutChannel
[(2)],
152 PSY_OUT_CHANNEL
*psyOutChannel
[(2)],
156 for (j
=0; j
<nChannels
; j
++) {
157 FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(qcOutChannel
[j
]->sfbFormFactorLdData
, psyOutChannel
[j
]);
162 Function: FDKaacEnc_calcSfbRelevantLines
164 Description: Calculates sfbNRelevantLines
166 sfbNRelevantLines is scaled with the factor 1/((2^FORM_FAC_SHIFT) * 2.0)
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
,
174 const INT sfbPerGroup
,
175 const INT maxSfbPerGroup
,
176 FIXP_DBL
*sfbNRelevantLines
)
179 FIXP_DBL sfbWidthLdData
;
180 FIXP_DBL asPeFacLdData
= FL2FXCONST_DBL(0.109375); /* AS_PE_FAC_SHIFT*ld64(2) */
183 /* sfbNRelevantLines[i] = 2^( (sfbFormFactorLdData[i] - 0.25 * (sfbEnergyLdData[i] - ld64(sfbWidth[i]/(2^7)) - AS_PE_FAC_SHIFT*ld64(2)) * 64); */
185 FDKmemclear(sfbNRelevantLines
, sfbCnt
* sizeof(FIXP_DBL
));
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
];
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
);
198 accu
= sfbEnergyLdData
[sfbOffs
+sfb
] - sfbWidthLdData
- asPeFacLdData
;
199 accu
= sfbFormFactorLdData
[sfbOffs
+sfb
] - (accu
>> 2);
201 sfbNRelevantLines
[sfbOffs
+sfb
] = CalcInvLdData(accu
) >> 1;
208 Function: FDKaacEnc_countSingleScfBits
212 scfBitsFract is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
214 static FIXP_DBL
FDKaacEnc_countSingleScfBits(INT scf
, INT scfLeft
, INT scfRight
)
216 FIXP_DBL scfBitsFract
;
218 scfBitsFract
= (FIXP_DBL
) ( FDKaacEnc_bitCountScalefactorDelta(scfLeft
-scf
)
219 + FDKaacEnc_bitCountScalefactorDelta(scf
-scfRight
) );
221 scfBitsFract
= scfBitsFract
<< (DFRACT_BITS
-1-(2*AS_PE_FAC_SHIFT
));
223 return scfBitsFract
; /* output scaled by 1/(2^(2*AS_PE_FAC)) */
227 Function: FDKaacEnc_calcSingleSpecPe
229 specPe is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
231 static FIXP_DBL
FDKaacEnc_calcSingleSpecPe(INT scf
, FIXP_DBL sfbConstPePart
, FIXP_DBL nLines
)
233 FIXP_DBL specPe
= FL2FXCONST_DBL(0.0f
);
237 scfFract
= (FIXP_DBL
)(scf
<< (DFRACT_BITS
-1-AS_PE_FAC_SHIFT
));
239 ldRatio
= sfbConstPePart
- fMult(FL2FXCONST_DBL(0.375f
),scfFract
);
241 if (ldRatio
>= PE_C1
) {
242 specPe
= fMult(FL2FXCONST_DBL(0.7f
),fMult(nLines
,ldRatio
));
245 specPe
= fMult(FL2FXCONST_DBL(0.7f
),fMult(nLines
,(PE_C2
+ fMult(PE_C3
,ldRatio
))));
248 return specPe
; /* output scaled by 1/(2^(2*AS_PE_FAC)) */
252 Function: FDKaacEnc_countScfBitsDiff
254 scfBitsDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
256 static FIXP_DBL
FDKaacEnc_countScfBitsDiff(INT
*scfOld
,
262 FIXP_DBL scfBitsFract
;
264 INT sfb
= 0, sfbLast
;
265 INT sfbPrev
, sfbNext
;
267 /* search for first relevant sfb */
269 while ((sfbLast
<stopSfb
) && (scfOld
[sfbLast
]==FDK_INT_MIN
))
271 /* search for previous relevant sfb and count diff */
272 sfbPrev
= startSfb
- 1;
273 while ((sfbPrev
>=0) && (scfOld
[sfbPrev
]==FDK_INT_MIN
))
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
]);
286 /* search for next relevant sfb and count diff */
288 while ((sfbNext
<sfbCnt
) && (scfOld
[sfbNext
]==FDK_INT_MIN
))
291 scfBitsDiff
+= FDKaacEnc_bitCountScalefactorDelta(scfNew
[sfbLast
]-scfNew
[sfbNext
]) -
292 FDKaacEnc_bitCountScalefactorDelta(scfOld
[sfbLast
]-scfOld
[sfbNext
]);
294 scfBitsFract
= (FIXP_DBL
) (scfBitsDiff
<< (DFRACT_BITS
-1-(2*AS_PE_FAC_SHIFT
)));
300 Function: FDKaacEnc_calcSpecPeDiff
302 specPeDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
304 static FIXP_DBL
FDKaacEnc_calcSpecPeDiff(PSY_OUT_CHANNEL
*psyOutChan
,
305 QC_OUT_CHANNEL
*qcOutChannel
,
308 FIXP_DBL
*sfbConstPePart
,
309 FIXP_DBL
*sfbFormFactorLdData
,
310 FIXP_DBL
*sfbNRelevantLines
,
314 FIXP_DBL specPeDiff
= FL2FXCONST_DBL(0.0f
);
315 FIXP_DBL scfFract
= FL2FXCONST_DBL(0.0f
);
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
;
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
);
329 scfFract
= (FIXP_DBL
) (scfOld
[sfb
] << (DFRACT_BITS
-1-AS_PE_FAC_SHIFT
));
330 ldRatioOld
= sfbConstPePart
[sfb
] - fMult(FL2FXCONST_DBL(0.375f
),scfFract
);
332 scfFract
= (FIXP_DBL
) (scfNew
[sfb
] << (DFRACT_BITS
-1-AS_PE_FAC_SHIFT
));
333 ldRatioNew
= sfbConstPePart
[sfb
] - fMult(FL2FXCONST_DBL(0.375f
),scfFract
);
335 if (ldRatioOld
>= PE_C1
)
338 pOld
= PE_C2
+ fMult(PE_C3
,ldRatioOld
);
340 if (ldRatioNew
>= PE_C1
)
343 pNew
= PE_C2
+ fMult(PE_C3
,ldRatioNew
);
345 specPeDiff
+= fMult(FL2FXCONST_DBL(0.7f
),fMult(sfbNRelevantLines
[sfb
],(pNew
- pOld
)));
353 Function: FDKaacEnc_improveScf
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.
358 static INT
FDKaacEnc_improveScf(FIXP_DBL
*spec
,
362 FIXP_DBL threshLdData
,
365 FIXP_DBL
*distLdData
,
366 INT
*minScfCalculated
369 FIXP_DBL sfbDistLdData
;
372 FIXP_DBL distFactorLdData
= FL2FXCONST_DBL(-0.0050301265); /* ld64(1/1.25) */
374 /* calc real distortion */
375 sfbDistLdData
= FDKaacEnc_calcSfbDist(spec
,
379 *minScfCalculated
= scf
;
380 /* nmr > 1.25 -> try to improve nmr */
381 if (sfbDistLdData
> (threshLdData
-distFactorLdData
)) {
382 INT scfEstimated
= scf
;
383 FIXP_DBL sfbDistBestLdData
= sfbDistLdData
;
385 /* improve by bigger scf ? */
388 while ((sfbDistLdData
> (threshLdData
-distFactorLdData
)) && (cnt
++ < 3)) {
390 sfbDistLdData
= FDKaacEnc_calcSfbDist(spec
,
395 if (sfbDistLdData
< sfbDistBestLdData
) {
397 sfbDistBestLdData
= sfbDistLdData
;
398 for (k
=0; k
<sfbWidth
; k
++)
399 quantSpec
[k
] = quantSpecTmp
[k
];
402 /* improve by smaller scf ? */
405 sfbDistLdData
= sfbDistBestLdData
;
406 while ((sfbDistLdData
> (threshLdData
-distFactorLdData
)) && (cnt
++ < 1) && (scf
> minScf
)) {
408 sfbDistLdData
= FDKaacEnc_calcSfbDist(spec
,
413 if (sfbDistLdData
< sfbDistBestLdData
) {
415 sfbDistBestLdData
= sfbDistLdData
;
416 for (k
=0; k
<sfbWidth
; k
++)
417 quantSpec
[k
] = quantSpecTmp
[k
];
419 *minScfCalculated
= scf
;
421 *distLdData
= sfbDistBestLdData
;
423 else { /* nmr <= 1.25 -> try to find bigger scf to use less bits */
424 FIXP_DBL sfbDistBestLdData
= sfbDistLdData
;
425 FIXP_DBL sfbDistAllowedLdData
= fixMin(sfbDistLdData
-distFactorLdData
,threshLdData
);
427 for (cnt
=0; cnt
<3; cnt
++) {
429 sfbDistLdData
= FDKaacEnc_calcSfbDist(spec
,
434 if (sfbDistLdData
< sfbDistAllowedLdData
) {
435 *minScfCalculated
= scfBest
+1;
437 sfbDistBestLdData
= sfbDistLdData
;
438 for (k
=0; k
<sfbWidth
; k
++)
439 quantSpec
[k
] = quantSpecTmp
[k
];
442 *distLdData
= sfbDistBestLdData
;
445 /* return best scalefactor */
450 Function: FDKaacEnc_assimilateSingleScf
453 static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL
*psyOutChan
,
454 QC_OUT_CHANNEL
*qcOutChannel
,
460 FIXP_DBL
*sfbConstPePart
,
461 FIXP_DBL
*sfbFormFactorLdData
,
462 FIXP_DBL
*sfbNRelevantLines
,
463 INT
*minScfCalculated
,
464 INT restartOnSuccess
)
466 INT sfbLast
, sfbAct
, sfbNext
;
467 INT scfAct
, *scfLast
, *scfNext
, scfMin
, scfMax
;
468 INT sfbWidth
, sfbOffs
;
470 FIXP_DBL sfbPeOld
, sfbPeNew
;
474 FIXP_DBL deltaPe
= FL2FXCONST_DBL(0.0f
);
475 FIXP_DBL deltaPeNew
, deltaPeTmp
;
476 INT prevScfLast
[MAX_GROUPED_SFB
], prevScfNext
[MAX_GROUPED_SFB
];
477 FIXP_DBL deltaPeLast
[MAX_GROUPED_SFB
];
478 INT updateMinScfCalculated
;
480 for (i
=0; i
<psyOutChan
->sfbCnt
; i
++) {
481 prevScfLast
[i
] = FDK_INT_MAX
;
482 prevScfNext
[i
] = FDK_INT_MAX
;
483 deltaPeLast
[i
] = (FIXP_DBL
)FDK_INT_MAX
;
491 scfMin
= FDK_INT_MAX
;
492 scfMax
= FDK_INT_MAX
;
494 /* search for new relevant sfb */
496 while ((sfbNext
< psyOutChan
->sfbCnt
) && (scf
[sfbNext
] == FDK_INT_MIN
))
498 if ((sfbLast
>=0) && (sfbAct
>=0) && (sfbNext
<psyOutChan
->sfbCnt
)) {
499 /* relevant scfs to the left and to the right */
500 scfAct
= scf
[sfbAct
];
501 scfLast
= scf
+ sfbLast
;
502 scfNext
= scf
+ sfbNext
;
503 scfMin
= fixMin(*scfLast
, *scfNext
);
504 scfMax
= fixMax(*scfLast
, *scfNext
);
506 else if ((sfbLast
==-1) && (sfbAct
>=0) && (sfbNext
<psyOutChan
->sfbCnt
)) {
507 /* first relevant scf */
508 scfAct
= scf
[sfbAct
];
510 scfNext
= scf
+ sfbNext
;
514 else if ((sfbLast
>=0) && (sfbAct
>=0) && (sfbNext
==psyOutChan
->sfbCnt
)) {
515 /* last relevant scf */
516 scfAct
= scf
[sfbAct
];
517 scfLast
= scf
+ sfbLast
;
523 scfMin
= fixMax(scfMin
, minScf
[sfbAct
]);
526 (sfbLast
>=0 || sfbNext
<psyOutChan
->sfbCnt
) &&
528 (scfAct
<= scfMin
+MAX_SCF_DELTA
) &&
529 (scfAct
>= scfMax
-MAX_SCF_DELTA
) &&
530 (*scfLast
!= prevScfLast
[sfbAct
] ||
531 *scfNext
!= prevScfNext
[sfbAct
] ||
532 deltaPe
< deltaPeLast
[sfbAct
])) {
533 /* bigger than neighbouring scf found, try to use smaller scf */
536 sfbWidth
= psyOutChan
->sfbOffsets
[sfbAct
+1] - psyOutChan
->sfbOffsets
[sfbAct
];
537 sfbOffs
= psyOutChan
->sfbOffsets
[sfbAct
];
539 /* estimate required bits for actual scf */
540 enLdData
= qcOutChannel
->sfbEnergyLdData
[sfbAct
];
542 /* sfbConstPePart[sfbAct] = (float)log(6.75f*en/sfbFormFactor[sfbAct]) * LOG2_1; */
543 /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for log2 */
544 /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
545 if (sfbConstPePart
[sfbAct
] == (FIXP_DBL
)FDK_INT_MIN
) {
546 sfbConstPePart
[sfbAct
] = ((enLdData
- sfbFormFactorLdData
[sfbAct
] - FL2FXCONST_DBL(0.09375f
)) >> 1) + FL2FXCONST_DBL(0.02152255861f
);
549 sfbPeOld
= FDKaacEnc_calcSingleSpecPe(scfAct
,sfbConstPePart
[sfbAct
],sfbNRelevantLines
[sfbAct
])
550 +FDKaacEnc_countSingleScfBits(scfAct
, *scfLast
, *scfNext
);
552 deltaPeNew
= deltaPe
;
553 updateMinScfCalculated
= 1;
556 /* estimate required bits for smaller scf */
558 /* check only if the same check was not done before */
559 if (scfAct
< minScfCalculated
[sfbAct
] && scfAct
>=scfMax
-MAX_SCF_DELTA
){
560 /* estimate required bits for new scf */
561 sfbPeNew
= FDKaacEnc_calcSingleSpecPe(scfAct
,sfbConstPePart
[sfbAct
],sfbNRelevantLines
[sfbAct
])
562 +FDKaacEnc_countSingleScfBits(scfAct
,*scfLast
, *scfNext
);
564 /* use new scf if no increase in pe and
565 quantization error is smaller */
566 deltaPeTmp
= deltaPe
+ sfbPeNew
- sfbPeOld
;
567 /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
568 if (deltaPeTmp
< FL2FXCONST_DBL(0.0006103515625f
)) {
569 /* distortion of new scf */
570 sfbDistNew
= FDKaacEnc_calcSfbDist(qcOutChannel
->mdctSpectrum
+sfbOffs
,
571 quantSpecTmp
+sfbOffs
,
575 if (sfbDistNew
< sfbDist
[sfbAct
]) {
576 /* success, replace scf by new one */
577 scf
[sfbAct
] = scfAct
;
578 sfbDist
[sfbAct
] = sfbDistNew
;
580 for (k
=0; k
<sfbWidth
; k
++)
581 quantSpec
[sfbOffs
+k
] = quantSpecTmp
[sfbOffs
+k
];
583 deltaPeNew
= deltaPeTmp
;
586 /* mark as already checked */
587 if (updateMinScfCalculated
)
588 minScfCalculated
[sfbAct
] = scfAct
;
591 /* from this scf value on not all new values have been checked */
592 updateMinScfCalculated
= 0;
595 } while (scfAct
> scfMin
);
597 deltaPe
= deltaPeNew
;
599 /* save parameters to avoid multiple computations of the same sfb */
600 prevScfLast
[sfbAct
] = *scfLast
;
601 prevScfNext
[sfbAct
] = *scfNext
;
602 deltaPeLast
[sfbAct
] = deltaPe
;
605 if (success
&& restartOnSuccess
) {
606 /* start again at first sfb */
612 scfMin
= FDK_INT_MAX
;
613 scfMax
= FDK_INT_MAX
;
617 /* shift sfbs for next band */
621 } while (sfbNext
< psyOutChan
->sfbCnt
);
625 Function: FDKaacEnc_assimilateMultipleScf
628 static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL
*psyOutChan
,
629 QC_OUT_CHANNEL
*qcOutChannel
,
635 FIXP_DBL
*sfbConstPePart
,
636 FIXP_DBL
*sfbFormFactorLdData
,
637 FIXP_DBL
*sfbNRelevantLines
)
639 INT sfb
, startSfb
, stopSfb
;
640 INT scfTmp
[MAX_GROUPED_SFB
], scfMin
, scfMax
, scfAct
;
641 INT possibleRegionFound
;
642 INT sfbWidth
, sfbOffs
, i
, k
;
643 FIXP_DBL sfbDistNew
[MAX_GROUPED_SFB
], distOldSum
, distNewSum
;
645 FIXP_DBL deltaSpecPe
;
646 FIXP_DBL deltaPe
= FL2FXCONST_DBL(0.0f
);
648 INT sfbCnt
= psyOutChan
->sfbCnt
;
650 /* calc min and max scalfactors */
651 scfMin
= FDK_INT_MAX
;
652 scfMax
= FDK_INT_MIN
;
653 for (sfb
=0; sfb
<sfbCnt
; sfb
++) {
654 if (scf
[sfb
]!=FDK_INT_MIN
) {
655 scfMin
= fixMin(scfMin
, scf
[sfb
]);
656 scfMax
= fixMax(scfMax
, scf
[sfb
]);
660 if (scfMax
!= FDK_INT_MIN
&& scfMax
<= scfMin
+MAX_SCF_DELTA
) {
665 /* try smaller scf */
667 for (i
=0; i
<MAX_GROUPED_SFB
; i
++)
671 /* search for region where all scfs are bigger than scfAct */
673 while (sfb
<sfbCnt
&& (scf
[sfb
]==FDK_INT_MIN
|| scf
[sfb
] <= scfAct
))
677 while (sfb
<sfbCnt
&& (scf
[sfb
]==FDK_INT_MIN
|| scf
[sfb
] > scfAct
))
681 /* check if in all sfb of a valid region scfAct >= minScf[sfb] */
682 possibleRegionFound
= 0;
683 if (startSfb
< sfbCnt
) {
684 possibleRegionFound
= 1;
685 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
686 if (scf
[sfb
] != FDK_INT_MIN
)
687 if (scfAct
< minScf
[sfb
]) {
688 possibleRegionFound
= 0;
694 if (possibleRegionFound
) { /* region found */
696 /* replace scfs in region by scfAct */
697 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
698 if (scfTmp
[sfb
] != FDK_INT_MIN
)
699 scfTmp
[sfb
] = scfAct
;
702 /* estimate change in bit demand for new scfs */
703 deltaScfBits
= FDKaacEnc_countScfBitsDiff(scf
,scfTmp
,sfbCnt
,startSfb
,stopSfb
);
705 deltaSpecPe
= FDKaacEnc_calcSpecPeDiff(psyOutChan
, qcOutChannel
, scf
, scfTmp
, sfbConstPePart
,
706 sfbFormFactorLdData
, sfbNRelevantLines
,
709 deltaPeNew
= deltaPe
+ (FIXP_DBL
)deltaScfBits
+ deltaSpecPe
;
711 /* new bit demand small enough ? */
712 /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
713 if (deltaPeNew
< FL2FXCONST_DBL(0.0006103515625f
)) {
715 /* quantize and calc sum of new distortion */
716 distOldSum
= distNewSum
= FL2FXCONST_DBL(0.0f
);
717 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
718 if (scfTmp
[sfb
] != FDK_INT_MIN
) {
719 distOldSum
+= CalcInvLdData(sfbDist
[sfb
]) >> DIST_FAC_SHIFT
;
721 sfbWidth
= psyOutChan
->sfbOffsets
[sfb
+1] - psyOutChan
->sfbOffsets
[sfb
];
722 sfbOffs
= psyOutChan
->sfbOffsets
[sfb
];
724 sfbDistNew
[sfb
] = FDKaacEnc_calcSfbDist(qcOutChannel
->mdctSpectrum
+sfbOffs
,
725 quantSpecTmp
+sfbOffs
,
729 if (sfbDistNew
[sfb
] >qcOutChannel
->sfbThresholdLdData
[sfb
]) {
730 /* no improvement, skip further dist. calculations */
731 distNewSum
= distOldSum
<< 1;
734 distNewSum
+= CalcInvLdData(sfbDistNew
[sfb
]) >> DIST_FAC_SHIFT
;
737 /* distortion smaller ? -> use new scalefactors */
738 if (distNewSum
< distOldSum
) {
739 deltaPe
= deltaPeNew
;
740 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
741 if (scf
[sfb
] != FDK_INT_MIN
) {
742 sfbWidth
= psyOutChan
->sfbOffsets
[sfb
+1] -
743 psyOutChan
->sfbOffsets
[sfb
];
744 sfbOffs
= psyOutChan
->sfbOffsets
[sfb
];
746 sfbDist
[sfb
] = sfbDistNew
[sfb
];
748 for (k
=0; k
<sfbWidth
; k
++)
749 quantSpec
[sfbOffs
+k
] = quantSpecTmp
[sfbOffs
+k
];
757 } while (stopSfb
<= sfbCnt
);
759 } while (scfAct
> scfMin
);
764 Function: FDKaacEnc_FDKaacEnc_assimilateMultipleScf2
767 static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL
*psyOutChan
,
768 QC_OUT_CHANNEL
*qcOutChannel
,
774 FIXP_DBL
*sfbConstPePart
,
775 FIXP_DBL
*sfbFormFactorLdData
,
776 FIXP_DBL
*sfbNRelevantLines
)
778 INT sfb
, startSfb
, stopSfb
;
779 INT scfTmp
[MAX_GROUPED_SFB
], scfAct
, scfNew
;
780 INT scfPrev
, scfNext
, scfPrevNextMin
, scfPrevNextMax
, scfLo
, scfHi
;
782 INT
*sfbOffs
= psyOutChan
->sfbOffsets
;
783 FIXP_DBL sfbDistNew
[MAX_GROUPED_SFB
], sfbDistMax
[MAX_GROUPED_SFB
];
784 FIXP_DBL distOldSum
, distNewSum
;
786 FIXP_DBL deltaSpecPe
;
787 FIXP_DBL deltaPe
= FL2FXCONST_DBL(0.0f
);
788 FIXP_DBL deltaPeNew
= FL2FXCONST_DBL(0.0f
);
789 INT sfbCnt
= psyOutChan
->sfbCnt
;
790 INT bSuccess
, bCheckScf
;
793 /* calc min and max scalfactors */
794 scfMin
= FDK_INT_MAX
;
795 scfMax
= FDK_INT_MIN
;
796 for (sfb
=0; sfb
<sfbCnt
; sfb
++) {
797 if (scf
[sfb
]!=FDK_INT_MIN
) {
798 scfMin
= fixMin(scfMin
, scf
[sfb
]);
799 scfMax
= fixMax(scfMax
, scf
[sfb
]);
804 scfAct
= FDK_INT_MIN
;
806 /* search for region with same scf values scfAct */
810 while (sfb
<sfbCnt
&& (scf
[sfb
]==FDK_INT_MIN
))
813 scfAct
= scf
[startSfb
];
815 while (sfb
<sfbCnt
&& ((scf
[sfb
]==FDK_INT_MIN
) || (scf
[sfb
]==scf
[startSfb
])))
819 if (stopSfb
< sfbCnt
)
820 scfNext
= scf
[stopSfb
];
824 if (scfPrev
== FDK_INT_MIN
)
827 scfPrevNextMax
= fixMax(scfPrev
, scfNext
);
828 scfPrevNextMin
= fixMin(scfPrev
, scfNext
);
830 /* try to reduce bits by checking scf values in the range
831 scf[startSfb]...scfHi */
832 scfHi
= fixMax(scfPrevNextMax
, scfAct
);
833 /* try to find a better solution by reducing the scf difference to
834 the nearest possible lower scf */
835 if (scfPrevNextMax
>= scfAct
)
836 scfLo
= fixMin(scfAct
, scfPrevNextMin
);
838 scfLo
= scfPrevNextMax
;
840 if (startSfb
< sfbCnt
&& scfHi
-scfLo
<= MAX_SCF_DELTA
) { /* region found */
841 /* 1. try to save bits by coarser quantization */
842 if (scfHi
> scf
[startSfb
]) {
843 /* calculate the allowed distortion */
844 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
845 if (scf
[sfb
] != FDK_INT_MIN
) {
846 /* sfbDistMax[sfb] = (float)pow(qcOutChannel->sfbThreshold[sfb]*sfbDist[sfb]*sfbDist[sfb],1.0f/3.0f); */
847 /* sfbDistMax[sfb] = fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergy[sfb]*FL2FXCONST_DBL(1.e-3f)); */
848 /* -0.15571537944 = ld64(1.e-3f)*/
849 sfbDistMax
[sfb
] = fMult(FL2FXCONST_DBL(1.0f
/3.0f
),qcOutChannel
->sfbThresholdLdData
[sfb
])+fMult(FL2FXCONST_DBL(1.0f
/3.0f
),sfbDist
[sfb
])+fMult(FL2FXCONST_DBL(1.0f
/3.0f
),sfbDist
[sfb
]);
850 sfbDistMax
[sfb
] = fixMax(sfbDistMax
[sfb
],qcOutChannel
->sfbEnergyLdData
[sfb
]-FL2FXCONST_DBL(0.15571537944));
851 sfbDistMax
[sfb
] = fixMin(sfbDistMax
[sfb
],qcOutChannel
->sfbThresholdLdData
[sfb
]);
855 /* loop over all possible scf values for this region */
857 for (scfNew
=scf
[startSfb
]+1; scfNew
<=scfHi
; scfNew
++) {
858 for (k
=0; k
<MAX_GROUPED_SFB
; k
++)
861 /* replace scfs in region by scfNew */
862 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
863 if (scfTmp
[sfb
] != FDK_INT_MIN
)
864 scfTmp
[sfb
] = scfNew
;
867 /* estimate change in bit demand for new scfs */
868 deltaScfBits
= FDKaacEnc_countScfBitsDiff(scf
,scfTmp
,sfbCnt
,startSfb
,stopSfb
);
870 deltaSpecPe
= FDKaacEnc_calcSpecPeDiff(psyOutChan
, qcOutChannel
, scf
, scfTmp
, sfbConstPePart
,
871 sfbFormFactorLdData
, sfbNRelevantLines
,
874 deltaPeNew
= deltaPe
+ (FIXP_DBL
)deltaScfBits
+ deltaSpecPe
;
876 /* new bit demand small enough ? */
877 if (deltaPeNew
< FL2FXCONST_DBL(0.0f
)) {
880 /* quantize and calc sum of new distortion */
881 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
882 if (scfTmp
[sfb
] != FDK_INT_MIN
) {
883 sfbDistNew
[sfb
] = FDKaacEnc_calcSfbDist(qcOutChannel
->mdctSpectrum
+sfbOffs
[sfb
],
884 quantSpecTmp
+sfbOffs
[sfb
],
885 sfbOffs
[sfb
+1]-sfbOffs
[sfb
],
888 if (sfbDistNew
[sfb
] > sfbDistMax
[sfb
]) {
889 /* no improvement, skip further dist. calculations */
891 if (sfbDistNew
[sfb
] == qcOutChannel
->sfbEnergyLdData
[sfb
]) {
892 /* if whole sfb is already quantized to 0, further
893 checks with even coarser quant. are useless*/
900 if (bCheckScf
==0) /* further calculations useless ? */
902 /* distortion small enough ? -> use new scalefactors */
904 deltaPe
= deltaPeNew
;
905 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
906 if (scf
[sfb
] != FDK_INT_MIN
) {
908 sfbDist
[sfb
] = sfbDistNew
[sfb
];
910 for (k
=0; k
<sfbOffs
[sfb
+1]-sfbOffs
[sfb
]; k
++)
911 quantSpec
[sfbOffs
[sfb
]+k
] = quantSpecTmp
[sfbOffs
[sfb
]+k
];
919 /* 2. only if coarser quantization was not successful, try to find
920 a better solution by finer quantization and reducing bits for
921 scalefactor coding */
922 if (scfAct
==scf
[startSfb
] &&
924 scfMax
-scfMin
<= MAX_SCF_DELTA
) {
926 int bminScfViolation
= 0;
928 for (k
=0; k
<MAX_GROUPED_SFB
; k
++)
933 /* replace scfs in region by scfNew and
934 check if in all sfb scfNew >= minScf[sfb] */
935 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
936 if (scfTmp
[sfb
] != FDK_INT_MIN
) {
937 scfTmp
[sfb
] = scfNew
;
938 if (scfNew
< minScf
[sfb
])
939 bminScfViolation
= 1;
943 if (!bminScfViolation
) {
944 /* estimate change in bit demand for new scfs */
945 deltaScfBits
= FDKaacEnc_countScfBitsDiff(scf
,scfTmp
,sfbCnt
,startSfb
,stopSfb
);
947 deltaSpecPe
= FDKaacEnc_calcSpecPeDiff(psyOutChan
, qcOutChannel
, scf
, scfTmp
, sfbConstPePart
,
948 sfbFormFactorLdData
, sfbNRelevantLines
,
951 deltaPeNew
= deltaPe
+ (FIXP_DBL
)deltaScfBits
+ deltaSpecPe
;
954 /* new bit demand small enough ? */
955 if (!bminScfViolation
&& deltaPeNew
< FL2FXCONST_DBL(0.0f
)) {
957 /* quantize and calc sum of new distortion */
958 distOldSum
= distNewSum
= FL2FXCONST_DBL(0.0f
);
959 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
960 if (scfTmp
[sfb
] != FDK_INT_MIN
) {
961 distOldSum
+= CalcInvLdData(sfbDist
[sfb
]) >> DIST_FAC_SHIFT
;
963 sfbDistNew
[sfb
] = FDKaacEnc_calcSfbDist(qcOutChannel
->mdctSpectrum
+sfbOffs
[sfb
],
964 quantSpecTmp
+sfbOffs
[sfb
],
965 sfbOffs
[sfb
+1]-sfbOffs
[sfb
],
968 if (sfbDistNew
[sfb
] > qcOutChannel
->sfbThresholdLdData
[sfb
]) {
969 /* no improvement, skip further dist. calculations */
970 distNewSum
= distOldSum
<< 1;
973 distNewSum
+= CalcInvLdData(sfbDistNew
[sfb
]) >> DIST_FAC_SHIFT
;
976 /* distortion smaller ? -> use new scalefactors */
977 if (distNewSum
< fMult(FL2FXCONST_DBL(0.8f
),distOldSum
)) {
978 deltaPe
= deltaPeNew
;
979 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
980 if (scf
[sfb
] != FDK_INT_MIN
) {
982 sfbDist
[sfb
] = sfbDistNew
[sfb
];
984 for (k
=0; k
<sfbOffs
[sfb
+1]-sfbOffs
[sfb
]; k
++)
985 quantSpec
[sfbOffs
[sfb
]+k
] = quantSpecTmp
[sfbOffs
[sfb
]+k
];
992 /* 3. try to find a better solution (save bits) by only reducing the
993 scalefactor without new quantization */
994 if (scfMax
-scfMin
<= MAX_SCF_DELTA
-3) { /* 3 bec. scf is reduced 3 times,
995 see for loop below */
997 for (k
=0; k
<sfbCnt
; k
++)
1000 for (i
=0; i
<3; i
++) {
1001 scfNew
= scfTmp
[startSfb
]-1;
1002 /* replace scfs in region by scfNew */
1003 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
1004 if (scfTmp
[sfb
] != FDK_INT_MIN
)
1005 scfTmp
[sfb
] = scfNew
;
1007 /* estimate change in bit demand for new scfs */
1008 deltaScfBits
= FDKaacEnc_countScfBitsDiff(scf
,scfTmp
,sfbCnt
,startSfb
,stopSfb
);
1009 deltaPeNew
= deltaPe
+ (FIXP_DBL
)deltaScfBits
;
1010 /* new bit demand small enough ? */
1011 if (deltaPeNew
<= FL2FXCONST_DBL(0.0f
)) {
1014 distOldSum
= distNewSum
= FL2FXCONST_DBL(0.0f
);
1015 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
1016 if (scfTmp
[sfb
] != FDK_INT_MIN
) {
1018 /* calc the energy and distortion of the quantized spectrum for
1020 FDKaacEnc_calcSfbQuantEnergyAndDist(qcOutChannel
->mdctSpectrum
+sfbOffs
[sfb
],
1021 quantSpec
+sfbOffs
[sfb
],
1022 sfbOffs
[sfb
+1]-sfbOffs
[sfb
], scfNew
,
1023 &sfbEnQ
, &sfbDistNew
[sfb
]);
1025 distOldSum
+= CalcInvLdData(sfbDist
[sfb
]) >> DIST_FAC_SHIFT
;
1026 distNewSum
+= CalcInvLdData(sfbDistNew
[sfb
]) >> DIST_FAC_SHIFT
;
1028 /* 0.00259488556167 = ld64(1.122f) */
1029 /* -0.00778722686652 = ld64(0.7079f) */
1030 if ((sfbDistNew
[sfb
] > (sfbDist
[sfb
]+FL2FXCONST_DBL(0.00259488556167f
))) || (sfbEnQ
< (qcOutChannel
->sfbEnergyLdData
[sfb
] - FL2FXCONST_DBL(0.00778722686652f
)))){
1036 /* distortion smaller ? -> use new scalefactors */
1037 if (distNewSum
< distOldSum
&& bSuccess
) {
1038 deltaPe
= deltaPeNew
;
1039 for (sfb
=startSfb
; sfb
<stopSfb
; sfb
++) {
1040 if (scf
[sfb
] != FDK_INT_MIN
) {
1042 sfbDist
[sfb
] = sfbDistNew
[sfb
];
1050 } while (stopSfb
<= sfbCnt
);
1055 FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL
*qcOutChannel
,
1056 PSY_OUT_CHANNEL
*psyOutChannel
,
1058 INT
*RESTRICT globalGain
,
1059 FIXP_DBL
*RESTRICT sfbFormFactorLdData
1060 ,const INT invQuant
,
1061 SHORT
*RESTRICT quantSpec
1064 INT i
, j
, sfb
, sfbOffs
;
1068 FIXP_DBL threshLdData
;
1069 FIXP_DBL energyLdData
;
1070 FIXP_DBL energyPartLdData
;
1071 FIXP_DBL thresholdPartLdData
;
1075 INT minScfCalculated
[MAX_GROUPED_SFB
];
1076 FIXP_DBL sfbDistLdData
[MAX_GROUPED_SFB
];
1077 C_ALLOC_SCRATCH_START(quantSpecTmp
, SHORT
, (1024));
1078 INT minSfMaxQuant
[MAX_GROUPED_SFB
];
1080 FIXP_DBL threshConstLdData
=FL2FXCONST_DBL(0.04304511722f
); /* log10(6.75)/log10(2.0)/64.0 */
1081 FIXP_DBL convConst
=FL2FXCONST_DBL(0.30102999566f
); /* log10(2.0) */
1082 FIXP_DBL c1Const
=FL2FXCONST_DBL(-0.27083183594f
); /* C1 = -69.33295 => C1/2^8 */
1087 FDKmemclear(quantSpec
, (1024)*sizeof(SHORT
));
1090 /* scfs without energy or with thresh>energy are marked with FDK_INT_MIN */
1091 for(i
=0; i
<psyOutChannel
->sfbCnt
; i
++) {
1092 scf
[i
] = FDK_INT_MIN
;
1095 for (i
=0; i
<MAX_GROUPED_SFB
; i
++) {
1096 minSfMaxQuant
[i
] = FDK_INT_MIN
;
1099 for (sfbOffs
=0; sfbOffs
<psyOutChannel
->sfbCnt
; sfbOffs
+=psyOutChannel
->sfbPerGroup
) {
1100 for(sfb
=0; sfb
<psyOutChannel
->maxSfbPerGroup
; sfb
++) {
1102 threshLdData
= qcOutChannel
->sfbThresholdLdData
[sfbOffs
+sfb
];
1103 energyLdData
= qcOutChannel
->sfbEnergyLdData
[sfbOffs
+sfb
];
1105 sfbDistLdData
[sfbOffs
+sfb
] = energyLdData
;
1108 if (energyLdData
> threshLdData
) {
1111 /* energyPart = (float)log10(sfbFormFactor[sfbOffs+sfb]); */
1112 /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
1113 energyPartLdData
= sfbFormFactorLdData
[sfbOffs
+sfb
] + FL2FXCONST_DBL(0.09375f
);
1115 /* influence of allowed distortion */
1116 /* thresholdPart = (float)log10(6.75*thresh+FLT_MIN); */
1117 thresholdPartLdData
= threshConstLdData
+ threshLdData
;
1120 /* scfFloat = 8.8585f * (thresholdPart - energyPart); */
1121 scfFract
= thresholdPartLdData
- energyPartLdData
;
1122 /* conversion from log2 to log10 */
1123 scfFract
= fMult(convConst
,scfFract
);
1124 /* (8.8585f * scfFract)/8 = 8/8 * scfFract + 0.8585 * scfFract/8 */
1125 scfFract
= scfFract
+ fMult(FL2FXCONST_DBL(0.8585f
),scfFract
>> 3);
1127 /* integer scalefactor */
1128 /* scfInt = (int)floor(scfFloat); */
1129 scfInt
= (INT
)(scfFract
>>((DFRACT_BITS
-1)-3-LD_DATA_SHIFT
)); /* 3 bits => scfFract/8.0; 6 bits => ld64 */
1131 /* maximum of spectrum */
1132 maxSpec
= FL2FXCONST_DBL(0.0f
);
1134 for(j
=psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
]; j
<psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
+1]; j
++ ){
1135 absSpec
= fixp_abs(qcOutChannel
->mdctSpectrum
[j
]);
1136 maxSpec
= (absSpec
> maxSpec
) ? absSpec
: maxSpec
;
1139 /* lower scf limit to avoid quantized values bigger than MAX_QUANT */
1140 /* C1 = -69.33295f, C2 = 5.77078f = 4/log(2) */
1141 /* minSfMaxQuant[sfbOffs+sfb] = (int)ceil(C1 + C2*log(maxSpec)); */
1142 /* C1/2^8 + 4/log(2.0)*log(maxSpec)/2^8 => C1/2^8 + log(maxSpec)/log(2.0)*4/2^8 => C1/2^8 + log(maxSpec)/log(2.0)/64.0 */
1144 //minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + CalcLdData(maxSpec)) >> ((DFRACT_BITS-1)-8))) + 1;
1145 tmp
= CalcLdData(maxSpec
);
1146 if (c1Const
>FL2FXCONST_DBL(-1.f
)-tmp
) {
1147 minSfMaxQuant
[sfbOffs
+sfb
] = ((INT
) ((c1Const
+ tmp
) >> ((DFRACT_BITS
-1)-8))) + 1;
1150 minSfMaxQuant
[sfbOffs
+sfb
] = ((INT
) (FL2FXCONST_DBL(-1.f
) >> ((DFRACT_BITS
-1)-8))) + 1;
1153 scfInt
= fixMax(scfInt
, minSfMaxQuant
[sfbOffs
+sfb
]);
1156 /* find better scalefactor with analysis by synthesis */
1158 scfInt
= FDKaacEnc_improveScf(qcOutChannel
->mdctSpectrum
+psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
],
1159 quantSpec
+psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
],
1160 quantSpecTmp
+psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
],
1161 psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
+1]-psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
],
1162 threshLdData
, scfInt
, minSfMaxQuant
[sfbOffs
+sfb
],
1163 &sfbDistLdData
[sfbOffs
+sfb
], &minScfCalculated
[sfbOffs
+sfb
]
1166 scf
[sfbOffs
+sfb
] = scfInt
;
1173 /* try to decrease scf differences */
1174 FIXP_DBL sfbConstPePart
[MAX_GROUPED_SFB
];
1175 FIXP_DBL sfbNRelevantLines
[MAX_GROUPED_SFB
];
1177 for (i
=0; i
<psyOutChannel
->sfbCnt
; i
++)
1178 sfbConstPePart
[i
] = (FIXP_DBL
)FDK_INT_MIN
;
1180 FDKaacEnc_calcSfbRelevantLines( sfbFormFactorLdData
,
1181 qcOutChannel
->sfbEnergyLdData
,
1182 qcOutChannel
->sfbThresholdLdData
,
1183 psyOutChannel
->sfbOffsets
,
1184 psyOutChannel
->sfbCnt
,
1185 psyOutChannel
->sfbPerGroup
,
1186 psyOutChannel
->maxSfbPerGroup
,
1190 FDKaacEnc_assimilateSingleScf(psyOutChannel
, qcOutChannel
, quantSpec
, quantSpecTmp
, scf
,
1191 minSfMaxQuant
, sfbDistLdData
, sfbConstPePart
,
1192 sfbFormFactorLdData
, sfbNRelevantLines
, minScfCalculated
, 1);
1195 FDKaacEnc_assimilateMultipleScf(psyOutChannel
, qcOutChannel
, quantSpec
, quantSpecTmp
, scf
,
1196 minSfMaxQuant
, sfbDistLdData
, sfbConstPePart
,
1197 sfbFormFactorLdData
, sfbNRelevantLines
);
1200 FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(psyOutChannel
, qcOutChannel
, quantSpec
, quantSpecTmp
, scf
,
1201 minSfMaxQuant
, sfbDistLdData
, sfbConstPePart
,
1202 sfbFormFactorLdData
, sfbNRelevantLines
);
1207 /* get min scalefac */
1208 minSf
= FDK_INT_MAX
;
1209 for (sfbOffs
=0; sfbOffs
<psyOutChannel
->sfbCnt
; sfbOffs
+=psyOutChannel
->sfbPerGroup
) {
1210 for (sfb
= 0; sfb
< psyOutChannel
->maxSfbPerGroup
; sfb
++) {
1211 if (scf
[sfbOffs
+sfb
]!=FDK_INT_MIN
)
1212 minSf
= fixMin(minSf
,scf
[sfbOffs
+sfb
]);
1216 /* limit scf delta */
1217 for (sfbOffs
=0; sfbOffs
<psyOutChannel
->sfbCnt
; sfbOffs
+=psyOutChannel
->sfbPerGroup
) {
1218 for (sfb
= 0; sfb
< psyOutChannel
->maxSfbPerGroup
; sfb
++) {
1219 if ((scf
[sfbOffs
+sfb
] != FDK_INT_MIN
) && (minSf
+MAX_SCF_DELTA
) < scf
[sfbOffs
+sfb
]) {
1220 scf
[sfbOffs
+sfb
] = minSf
+ MAX_SCF_DELTA
;
1221 if (invQuant
> 0) { /* changed bands need to be quantized again */
1222 sfbDistLdData
[sfbOffs
+sfb
] =
1223 FDKaacEnc_calcSfbDist(qcOutChannel
->mdctSpectrum
+psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
],
1224 quantSpec
+psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
],
1225 psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
+1]-psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
],
1234 /* get max scalefac for global gain */
1235 maxSf
= FDK_INT_MIN
;
1236 for (sfbOffs
=0; sfbOffs
<psyOutChannel
->sfbCnt
; sfbOffs
+=psyOutChannel
->sfbPerGroup
) {
1237 for (sfb
= 0; sfb
< psyOutChannel
->maxSfbPerGroup
; sfb
++) {
1238 maxSf
= fixMax(maxSf
,scf
[sfbOffs
+sfb
]);
1242 /* calc loop scalefactors, if spec is not all zero (i.e. maxSf == -99) */
1243 if( maxSf
> FDK_INT_MIN
) {
1244 *globalGain
= maxSf
;
1245 for (sfbOffs
=0; sfbOffs
<psyOutChannel
->sfbCnt
; sfbOffs
+=psyOutChannel
->sfbPerGroup
) {
1246 for (sfb
= 0; sfb
< psyOutChannel
->maxSfbPerGroup
; sfb
++) {
1247 if( scf
[sfbOffs
+sfb
] == FDK_INT_MIN
) {
1248 scf
[sfbOffs
+sfb
] = 0;
1249 /* set band explicitely to zero */
1250 for(j
=psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
]; j
<psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
+1]; j
++ ) {
1251 qcOutChannel
->mdctSpectrum
[j
] = FL2FXCONST_DBL(0.0f
);
1255 scf
[sfbOffs
+sfb
] = maxSf
- scf
[sfbOffs
+sfb
];
1262 /* set spectrum explicitely to zero */
1263 for (sfbOffs
=0; sfbOffs
<psyOutChannel
->sfbCnt
; sfbOffs
+=psyOutChannel
->sfbPerGroup
) {
1264 for (sfb
= 0; sfb
< psyOutChannel
->maxSfbPerGroup
; sfb
++) {
1265 scf
[sfbOffs
+sfb
] = 0;
1266 /* set band explicitely to zero */
1267 for(j
=psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
]; j
<psyOutChannel
->sfbOffsets
[sfbOffs
+sfb
+1]; j
++ ) {
1268 qcOutChannel
->mdctSpectrum
[j
] = FL2FXCONST_DBL(0.0f
);
1274 /* free quantSpecTmp from scratch */
1275 C_ALLOC_SCRATCH_END(quantSpecTmp
, SHORT
, (1024));
1281 FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL
*psyOutChannel
[],
1282 QC_OUT_CHANNEL
* qcOutChannel
[],
1284 const int nChannels
)
1288 for (ch
= 0; ch
< nChannels
; ch
++)
1290 FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(qcOutChannel
[ch
],
1292 qcOutChannel
[ch
]->scf
,
1293 &qcOutChannel
[ch
]->globalGain
,
1294 qcOutChannel
[ch
]->sfbFormFactorLdData
1296 qcOutChannel
[ch
]->quantSpec