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 Authors: M. Neuendorf, N. Rettelbach, M. Multrus
87 Contents/Description: PS parameter extraction, encoding
89 ******************************************************************************/
92 \brief PS parameter extraction, encoding functions
99 #include "ps_encode.h"
103 #include "ps_const.h"
104 #include "sbr_misc.h"
106 #include "genericStds.h"
108 inline void FDKsbrEnc_addFIXP_DBL(const FIXP_DBL
*X
, const FIXP_DBL
*Y
, FIXP_DBL
*Z
, INT n
)
110 for (INT i
=0; i
<n
; i
++)
111 Z
[i
] = (X
[i
]>>1) + (Y
[i
]>>1);
114 #define LOG10_2_10 3.01029995664f /* 10.0f*log10(2.f) */
116 static const INT iidGroupBordersLoRes
[QMF_GROUPS_LO_RES
+ SUBQMF_GROUPS_LO_RES
+ 1] =
118 0, 1, 2, 3, 4, 5, /* 6 subqmf subbands - 0th qmf subband */
119 6, 7, /* 2 subqmf subbands - 1st qmf subband */
120 8, 9, /* 2 subqmf subbands - 2nd qmf subband */
121 10, 11, 12, 13, 14, 15, 16, 18, 21, 25, 30, 42, 71
124 static const UCHAR iidGroupWidthLdLoRes
[QMF_GROUPS_LO_RES
+ SUBQMF_GROUPS_LO_RES
] =
129 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 4, 5
133 static const INT subband2parameter20
[QMF_GROUPS_LO_RES
+ SUBQMF_GROUPS_LO_RES
] =
135 1, 0, 0, 1, 2, 3, /* 6 subqmf subbands - 0th qmf subband */
136 4, 5, /* 2 subqmf subbands - 1st qmf subband */
137 6, 7, /* 2 subqmf subbands - 2nd qmf subband */
138 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
143 MAX_TIME_DIFF_FRAMES
= 20,
144 MAX_PS_NOHEADER_CNT
= 10,
146 DO_NOT_USE_THIS_MODE
= 0x7FFFFF
151 static const FIXP_DBL iidQuant_fx
[15] = {
152 0xce000000, 0xdc000000, 0xe4000000, 0xec000000, 0xf2000000, 0xf8000000, 0xfc000000, 0x00000000,
153 0x04000000, 0x08000000, 0x0e000000, 0x14000000, 0x1c000000, 0x24000000, 0x32000000
156 static const FIXP_DBL iidQuantFine_fx
[31] = {
157 0x9c000001, 0xa6000001, 0xb0000001, 0xba000001, 0xc4000000, 0xce000000, 0xd4000000, 0xda000000,
158 0xe0000000, 0xe6000000, 0xec000000, 0xf0000000, 0xf4000000, 0xf8000000, 0xfc000000, 0x00000000,
159 0x04000000, 0x08000000, 0x0c000000, 0x10000000, 0x14000000, 0x1a000000, 0x20000000, 0x26000000,
160 0x2c000000, 0x32000000, 0x3c000000, 0x45ffffff, 0x4fffffff, 0x59ffffff, 0x63ffffff
165 static const FIXP_DBL iccQuant
[8] = {
166 0x7fffffff, 0x77ef9d7f, 0x6babc97f, 0x4ceaf27f, 0x2f0ed3c0, 0x00000000, 0xb49ba601, 0x80000000
169 static FDK_PSENC_ERROR
InitPSData(
170 HANDLE_PS_DATA hPsData
173 FDK_PSENC_ERROR error
= PSENC_OK
;
175 if(hPsData
== NULL
) {
176 error
= PSENC_INVALID_HANDLE
;
180 FDKmemclear(hPsData
,sizeof(PS_DATA
));
182 for (i
=0; i
<PS_MAX_BANDS
; i
++) {
183 hPsData
->iidIdxLast
[i
] = 0;
184 hPsData
->iccIdxLast
[i
] = 0;
187 hPsData
->iidEnable
= hPsData
->iidEnableLast
= 0;
188 hPsData
->iccEnable
= hPsData
->iccEnableLast
= 0;
189 hPsData
->iidQuantMode
= hPsData
->iidQuantModeLast
= PS_IID_RES_COARSE
;
190 hPsData
->iccQuantMode
= hPsData
->iccQuantModeLast
= PS_ICC_ROT_A
;
192 for(env
=0; env
<PS_MAX_ENVELOPES
; env
++) {
193 hPsData
->iccDiffMode
[env
] = PS_DELTA_FREQ
;
194 hPsData
->iccDiffMode
[env
] = PS_DELTA_FREQ
;
196 for (i
=0; i
<PS_MAX_BANDS
; i
++) {
197 hPsData
->iidIdx
[env
][i
] = 0;
198 hPsData
->iccIdx
[env
][i
] = 0;
202 hPsData
->nEnvelopesLast
= 0;
204 hPsData
->headerCnt
= MAX_PS_NOHEADER_CNT
;
205 hPsData
->iidTimeCnt
= MAX_TIME_DIFF_FRAMES
;
206 hPsData
->iccTimeCnt
= MAX_TIME_DIFF_FRAMES
;
207 hPsData
->noEnvCnt
= MAX_NOENV_CNT
;
213 static FIXP_DBL
quantizeCoef( const FIXP_DBL
*RESTRICT input
,
215 const FIXP_DBL
*RESTRICT quantTable
,
217 const INT nQuantSteps
,
218 INT
*RESTRICT quantOut
)
221 FIXP_DBL quantErr
= FL2FXCONST_DBL(0.f
);
223 for (band
=0; band
<nBands
;band
++) {
224 for(idx
=0; idx
<nQuantSteps
-1; idx
++){
225 if( fixp_abs((input
[band
]>>1)-(quantTable
[idx
+1]>>1)) >
226 fixp_abs((input
[band
]>>1)-(quantTable
[idx
]>>1)) )
231 quantErr
+= (fixp_abs(input
[band
]-quantTable
[idx
])>>PS_QUANT_SCALE
); /* don't scale before subtraction; diff smaller (64-25)/64 */
232 quantOut
[band
] = idx
- idxOffset
;
238 static INT
getICCMode(const INT nBands
,
244 case PS_BANDS_COARSE
:
245 mode
= PS_RES_COARSE
;
253 if(rotType
==PS_ICC_ROT_B
){
261 static INT
getIIDMode(const INT nBands
,
267 case PS_BANDS_COARSE
:
268 mode
= PS_RES_COARSE
;
278 if(iidRes
== PS_IID_RES_FINE
){
286 static INT
envelopeReducible(FIXP_DBL iid
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
],
287 FIXP_DBL icc
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
],
291 #define THRESH_SCALE 7
293 INT reducible
= 1; /* true */
295 FIXP_DBL dIid
= FL2FXCONST_DBL(0.f
);
296 FIXP_DBL dIcc
= FL2FXCONST_DBL(0.f
);
298 FIXP_DBL iidErrThreshold
, iccErrThreshold
;
299 FIXP_DBL iidMeanError
, iccMeanError
;
301 /* square values to prevent sqrt,
302 multiply bands to prevent division; bands shifted DFRACT_BITS instead (DFRACT_BITS-1) because fMultDiv2 used*/
303 iidErrThreshold
= fMultDiv2 ( FL2FXCONST_DBL(6.5f
*6.5f
/(IID_SCALE_FT
*IID_SCALE_FT
)), (FIXP_DBL
)(psBands
<<((DFRACT_BITS
)-THRESH_SCALE
)) );
304 iccErrThreshold
= fMultDiv2 ( FL2FXCONST_DBL(0.75f
*0.75f
), (FIXP_DBL
)(psBands
<<((DFRACT_BITS
)-THRESH_SCALE
)) );
306 if (nEnvelopes
<= 1) {
310 /* mean error criterion */
311 for (e
=0; (e
< nEnvelopes
/2) && (reducible
!=0 ) ; e
++) {
312 iidMeanError
= iccMeanError
= FL2FXCONST_DBL(0.f
);
313 for(b
=0; b
<psBands
; b
++) {
314 dIid
= (iid
[2*e
][b
]>>1) - (iid
[2*e
+1][b
]>>1); /* scale 1 bit; squared -> 2 bit */
315 dIcc
= (icc
[2*e
][b
]>>1) - (icc
[2*e
+1][b
]>>1);
316 iidMeanError
+= fPow2Div2(dIid
)>>(5-1); /* + (bands=20) scale = 5 */
317 iccMeanError
+= fPow2Div2(dIcc
)>>(5-1);
318 } /* --> scaling = 7 bit = THRESH_SCALE !! */
320 /* instead sqrt values are squared!
321 instead of division, multiply threshold with psBands
322 scaling necessary!! */
324 /* quit as soon as threshold is reached */
325 if ( (iidMeanError
> (iidErrThreshold
)) ||
326 (iccMeanError
> (iccErrThreshold
)) ) {
330 } /* nEnvelopes != 1 */
336 static void processIidData(PS_DATA
*psData
,
337 FIXP_DBL iid
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
],
339 const INT nEnvelopes
,
340 const FIXP_DBL quantErrorThreshold
)
342 INT iidIdxFine
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
];
343 INT iidIdxCoarse
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
];
345 FIXP_DBL errIID
= FL2FXCONST_DBL(0.f
);
346 FIXP_DBL errIIDFine
= FL2FXCONST_DBL(0.f
);
350 INT bitsCoarseTot
= 0;
353 INT diffMode
[PS_MAX_ENVELOPES
], diffModeFine
[PS_MAX_ENVELOPES
];
357 bitsIidFreq
= bitsIidTime
= 0;
359 /* Quantize IID coefficients */
360 for(env
=0;env
<nEnvelopes
; env
++) {
361 errIID
+= quantizeCoef(iid
[env
], psBands
, iidQuant_fx
, 7, 15, iidIdxCoarse
[env
]);
362 errIIDFine
+= quantizeCoef(iid
[env
], psBands
, iidQuantFine_fx
, 15, 31, iidIdxFine
[env
]);
365 /* normalize error to number of envelopes, ps bands
366 errIID /= psBands*nEnvelopes;
367 errIIDFine /= psBands*nEnvelopes; */
370 /* Check if IID coefficients should be used in this frame */
371 psData
->iidEnable
= 0;
372 for(env
=0;env
<nEnvelopes
; env
++) {
373 for(band
=0;band
<psBands
;band
++) {
374 loudnDiff
+= fixp_abs(iidIdxCoarse
[env
][band
]);
379 if(loudnDiff
> fMultI(FL2FXCONST_DBL(0.7f
),iidTransmit
)){ /* 0.7f empiric value */
380 psData
->iidEnable
= 1;
383 /* if iid not active -> RESET data */
384 if(psData
->iidEnable
==0) {
385 psData
->iidTimeCnt
= MAX_TIME_DIFF_FRAMES
;
386 for(env
=0;env
<nEnvelopes
; env
++) {
387 psData
->iidDiffMode
[env
] = PS_DELTA_FREQ
;
388 FDKmemclear(psData
->iidIdx
[env
], sizeof(INT
)*psBands
);
393 /* count COARSE quantization bits for first envelope*/
394 bitsIidFreq
= FDKsbrEnc_EncodeIid(NULL
, iidIdxCoarse
[0], NULL
, psBands
, PS_IID_RES_COARSE
, PS_DELTA_FREQ
, &error
);
396 if( (psData
->iidTimeCnt
>=MAX_TIME_DIFF_FRAMES
) || (psData
->iidQuantModeLast
==PS_IID_RES_FINE
) ) {
397 bitsIidTime
= DO_NOT_USE_THIS_MODE
;
400 bitsIidTime
= FDKsbrEnc_EncodeIid(NULL
, iidIdxCoarse
[0], psData
->iidIdxLast
, psBands
, PS_IID_RES_COARSE
, PS_DELTA_TIME
, &error
);
403 /* decision DELTA_FREQ vs DELTA_TIME */
404 if(bitsIidTime
>bitsIidFreq
) {
405 diffMode
[0] = PS_DELTA_FREQ
;
406 bitsCoarseTot
= bitsIidFreq
;
409 diffMode
[0] = PS_DELTA_TIME
;
410 bitsCoarseTot
= bitsIidTime
;
413 /* count COARSE quantization bits for following envelopes*/
414 for(env
=1;env
<nEnvelopes
; env
++) {
415 bitsIidFreq
= FDKsbrEnc_EncodeIid(NULL
, iidIdxCoarse
[env
], NULL
, psBands
, PS_IID_RES_COARSE
, PS_DELTA_FREQ
, &error
);
416 bitsIidTime
= FDKsbrEnc_EncodeIid(NULL
, iidIdxCoarse
[env
], iidIdxCoarse
[env
-1], psBands
, PS_IID_RES_COARSE
, PS_DELTA_TIME
, &error
);
418 /* decision DELTA_FREQ vs DELTA_TIME */
419 if(bitsIidTime
>bitsIidFreq
) {
420 diffMode
[env
] = PS_DELTA_FREQ
;
421 bitsCoarseTot
+= bitsIidFreq
;
424 diffMode
[env
] = PS_DELTA_TIME
;
425 bitsCoarseTot
+= bitsIidTime
;
430 /* count FINE quantization bits for first envelope*/
431 bitsIidFreq
= FDKsbrEnc_EncodeIid(NULL
, iidIdxFine
[0], NULL
, psBands
, PS_IID_RES_FINE
, PS_DELTA_FREQ
, &error
);
433 if( (psData
->iidTimeCnt
>=MAX_TIME_DIFF_FRAMES
) || (psData
->iidQuantModeLast
==PS_IID_RES_COARSE
) ) {
434 bitsIidTime
= DO_NOT_USE_THIS_MODE
;
437 bitsIidTime
= FDKsbrEnc_EncodeIid(NULL
, iidIdxFine
[0], psData
->iidIdxLast
, psBands
, PS_IID_RES_FINE
, PS_DELTA_TIME
, &error
);
440 /* decision DELTA_FREQ vs DELTA_TIME */
441 if(bitsIidTime
>bitsIidFreq
) {
442 diffModeFine
[0] = PS_DELTA_FREQ
;
443 bitsFineTot
= bitsIidFreq
;
446 diffModeFine
[0] = PS_DELTA_TIME
;
447 bitsFineTot
= bitsIidTime
;
450 /* count FINE quantization bits for following envelopes*/
451 for(env
=1;env
<nEnvelopes
; env
++) {
452 bitsIidFreq
= FDKsbrEnc_EncodeIid(NULL
, iidIdxFine
[env
], NULL
, psBands
, PS_IID_RES_FINE
, PS_DELTA_FREQ
, &error
);
453 bitsIidTime
= FDKsbrEnc_EncodeIid(NULL
, iidIdxFine
[env
], iidIdxFine
[env
-1], psBands
, PS_IID_RES_FINE
, PS_DELTA_TIME
, &error
);
455 /* decision DELTA_FREQ vs DELTA_TIME */
456 if(bitsIidTime
>bitsIidFreq
) {
457 diffModeFine
[env
] = PS_DELTA_FREQ
;
458 bitsFineTot
+= bitsIidFreq
;
461 diffModeFine
[env
] = PS_DELTA_TIME
;
462 bitsFineTot
+= bitsIidTime
;
466 if(bitsFineTot
== bitsCoarseTot
){
467 /* if same number of bits is needed, use the quantization with lower error */
468 if(errIIDFine
< errIID
){
469 bitsCoarseTot
= DO_NOT_USE_THIS_MODE
;
471 bitsFineTot
= DO_NOT_USE_THIS_MODE
;
474 /* const FIXP_DBL minThreshold = FL2FXCONST_DBL(0.2f/(IID_SCALE_FT*PS_QUANT_SCALE_FT)*(psBands*nEnvelopes)); */
475 const FIXP_DBL minThreshold
= (FIXP_DBL
)((LONG
)0x00019999 * (psBands
*nEnvelopes
));
477 /* decision RES_FINE vs RES_COARSE */
478 /* test if errIIDFine*quantErrorThreshold < errIID */
479 /* shiftVal 2 comes from scaling of quantErrorThreshold */
480 if(fixMax(((errIIDFine
>>1)+(minThreshold
>>1))>>1, fMult(quantErrorThreshold
,errIIDFine
)) < (errIID
>>2) ) {
481 bitsCoarseTot
= DO_NOT_USE_THIS_MODE
;
483 else if(fixMax(((errIID
>>1)+(minThreshold
>>1))>>1, fMult(quantErrorThreshold
,errIID
)) < (errIIDFine
>>2) ) {
484 bitsFineTot
= DO_NOT_USE_THIS_MODE
;
488 /* decision RES_FINE vs RES_COARSE */
489 if(bitsFineTot
<bitsCoarseTot
) {
490 psData
->iidQuantMode
= PS_IID_RES_FINE
;
491 for(env
=0;env
<nEnvelopes
; env
++) {
492 psData
->iidDiffMode
[env
] = diffModeFine
[env
];
493 FDKmemcpy(psData
->iidIdx
[env
], iidIdxFine
[env
], psBands
*sizeof(INT
));
497 psData
->iidQuantMode
= PS_IID_RES_COARSE
;
498 for(env
=0;env
<nEnvelopes
; env
++) {
499 psData
->iidDiffMode
[env
] = diffMode
[env
];
500 FDKmemcpy(psData
->iidIdx
[env
], iidIdxCoarse
[env
], psBands
*sizeof(INT
));
504 /* Count DELTA_TIME encoding streaks */
505 for(env
=0;env
<nEnvelopes
; env
++) {
506 if(psData
->iidDiffMode
[env
]==PS_DELTA_TIME
)
507 psData
->iidTimeCnt
++;
509 psData
->iidTimeCnt
=0;
514 static INT
similarIid(PS_DATA
*psData
,
516 const INT nEnvelopes
)
518 const INT diffThr
= (psData
->iidQuantMode
== PS_IID_RES_COARSE
) ? 2 : 3;
519 const INT sumDiffThr
= diffThr
* psBands
/4;
525 if ((nEnvelopes
== psData
->nEnvelopesLast
) && (nEnvelopes
==1)) {
527 for (env
=0; env
<nEnvelopes
; env
++) {
531 diff
= fixp_abs(psData
->iidIdx
[env
][b
] - psData
->iidIdxLast
[b
]);
533 if ( (diff
> diffThr
) /* more than x quantization steps in any band */
534 || (sumDiff
> sumDiffThr
) ) { /* more than x quantisations steps overall difference */
538 } while ((b
<psBands
) && (similar
>0));
540 } /* nEnvelopes==1 */
546 static INT
similarIcc(PS_DATA
*psData
,
548 const INT nEnvelopes
)
550 const INT diffThr
= 2;
551 const INT sumDiffThr
= diffThr
* psBands
/4;
557 if ((nEnvelopes
== psData
->nEnvelopesLast
) && (nEnvelopes
==1)) {
559 for (env
=0; env
<nEnvelopes
; env
++) {
563 diff
= fixp_abs(psData
->iccIdx
[env
][b
] - psData
->iccIdxLast
[b
]);
565 if ( (diff
> diffThr
) /* more than x quantisation step in any band */
566 || (sumDiff
> sumDiffThr
) ) { /* more than x quantisations steps overall difference */
570 } while ((b
<psBands
) && (similar
>0));
572 } /* nEnvelopes==1 */
577 static void processIccData(PS_DATA
*psData
,
578 FIXP_DBL icc
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
], /* const input values: unable to declare as const, since it does not poINT to const memory */
580 const INT nEnvelopes
)
582 FIXP_DBL errICC
= FL2FXCONST_DBL(0.f
);
584 INT bitsIccFreq
, bitsIccTime
;
586 INT inCoherence
=0, iccTransmit
=0;
589 iccIdxLast
= psData
->iccIdxLast
;
591 /* Quantize ICC coefficients */
592 for(env
=0;env
<nEnvelopes
; env
++) {
593 errICC
+= quantizeCoef(icc
[env
], psBands
, iccQuant
, 0, 8, psData
->iccIdx
[env
]);
596 /* Check if ICC coefficients should be used */
597 psData
->iccEnable
= 0;
598 for(env
=0;env
<nEnvelopes
; env
++) {
599 for(band
=0;band
<psBands
;band
++) {
600 inCoherence
+= psData
->iccIdx
[env
][band
];
604 if(inCoherence
> fMultI(FL2FXCONST_DBL(0.5f
),iccTransmit
)){ /* 0.5f empiric value */
605 psData
->iccEnable
= 1;
608 if(psData
->iccEnable
==0) {
609 psData
->iccTimeCnt
= MAX_TIME_DIFF_FRAMES
;
610 for(env
=0;env
<nEnvelopes
; env
++) {
611 psData
->iccDiffMode
[env
] = PS_DELTA_FREQ
;
612 FDKmemclear(psData
->iccIdx
[env
], sizeof(INT
)*psBands
);
617 for(env
=0;env
<nEnvelopes
; env
++) {
618 bitsIccFreq
= FDKsbrEnc_EncodeIcc(NULL
, psData
->iccIdx
[env
], NULL
, psBands
, PS_DELTA_FREQ
, &error
);
620 if(psData
->iccTimeCnt
<MAX_TIME_DIFF_FRAMES
) {
621 bitsIccTime
= FDKsbrEnc_EncodeIcc(NULL
, psData
->iccIdx
[env
], iccIdxLast
, psBands
, PS_DELTA_TIME
, &error
);
624 bitsIccTime
= DO_NOT_USE_THIS_MODE
;
627 if(bitsIccFreq
>bitsIccTime
) {
628 psData
->iccDiffMode
[env
] = PS_DELTA_TIME
;
629 psData
->iccTimeCnt
++;
632 psData
->iccDiffMode
[env
] = PS_DELTA_FREQ
;
633 psData
->iccTimeCnt
=0;
635 iccIdxLast
= psData
->iccIdx
[env
];
639 static void calculateIID(FIXP_DBL ldPwrL
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
],
640 FIXP_DBL ldPwrR
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
],
641 FIXP_DBL iid
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
],
647 for(env
=0; env
<nEnvelopes
;env
++) {
648 for (i
=0; i
<psBands
; i
++) {
650 /* iid[env][i] = 10.0f*(float)log10(pwrL[env][i]/pwrR[env][i]);
652 FIXP_DBL IID
= fMultDiv2( FL2FXCONST_DBL(LOG10_2_10
/IID_SCALE_FT
), (ldPwrL
[env
][i
]-ldPwrR
[env
][i
]) );
654 IID
= fixMin( IID
, (FIXP_DBL
)(MAXVAL_DBL
>>(LD_DATA_SHIFT
+1)) );
655 IID
= fixMax( IID
, (FIXP_DBL
)(MINVAL_DBL
>>(LD_DATA_SHIFT
+1)) );
656 iid
[env
][i
] = IID
<< (LD_DATA_SHIFT
+1);
661 static void calculateICC(FIXP_DBL ldPwrL
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
],
662 FIXP_DBL ldPwrR
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
],
663 FIXP_DBL pwrCr
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
],
664 FIXP_DBL pwrCi
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
],
665 FIXP_DBL icc
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
],
671 INT border
= psBands
;
674 case PS_BANDS_COARSE
:
684 for(env
=0; env
<nEnvelopes
;env
++) {
685 for (i
=0; i
<border
; i
++) {
687 /* icc[env][i] = min( pwrCr[env][i] / (float) sqrt(pwrL[env][i] * pwrR[env][i]) , 1.f);
689 FIXP_DBL ICC
, invNrg
= CalcInvLdData ( -((ldPwrL
[env
][i
]>>1) + (ldPwrR
[env
][i
]>>1) + (FIXP_DBL
)1) );
690 INT scale
, invScale
= CountLeadingBits(invNrg
);
692 scale
= (DFRACT_BITS
-1) - invScale
;
693 ICC
= fMult(pwrCr
[env
][i
], invNrg
<<invScale
) ;
694 icc
[env
][i
] = SATURATE_LEFT_SHIFT(ICC
, scale
, DFRACT_BITS
);
697 for (; i
<psBands
; i
++) {
699 FIXP_DBL cNrgR
, cNrgI
, ICC
;
701 sc1
= CountLeadingBits( fixMax(fixp_abs(pwrCr
[env
][i
]),fixp_abs(pwrCi
[env
][i
])) ) ;
702 cNrgR
= fPow2Div2((pwrCr
[env
][i
]<<sc1
)); /* squared nrg's expect explicit scaling */
703 cNrgI
= fPow2Div2((pwrCi
[env
][i
]<<sc1
));
705 ICC
= CalcInvLdData( (CalcLdData((cNrgR
+ cNrgI
)>>1)>>1) - (FIXP_DBL
)((sc1
-1)<<(DFRACT_BITS
-1-LD_DATA_SHIFT
)) );
707 FIXP_DBL invNrg
= CalcInvLdData ( -((ldPwrL
[env
][i
]>>1) + (ldPwrR
[env
][i
]>>1) + (FIXP_DBL
)1) );
708 sc1
= CountLeadingBits(invNrg
);
711 sc2
= CountLeadingBits(ICC
);
712 ICC
= fMult(ICC
<<sc2
,invNrg
);
714 sc1
= ( (DFRACT_BITS
-1) - sc1
- sc2
);
719 if (ICC
>= ((FIXP_DBL
)MAXVAL_DBL
>>sc1
) )
720 ICC
= (FIXP_DBL
)MAXVAL_DBL
;
730 void FDKsbrEnc_initPsBandNrgScale(HANDLE_PS_ENCODE hPsEncode
)
733 INT nIidGroups
= hPsEncode
->nQmfIidGroups
+ hPsEncode
->nSubQmfIidGroups
;
735 FDKmemclear(hPsEncode
->psBandNrgScale
, PS_MAX_BANDS
*sizeof(SCHAR
));
737 for (group
=0; group
< nIidGroups
; group
++) {
738 /* Translate group to bin */
739 bin
= hPsEncode
->subband2parameterIndex
[group
];
741 /* Translate from 20 bins to 10 bins */
742 if (hPsEncode
->psEncMode
== PS_BANDS_COARSE
) {
746 hPsEncode
->psBandNrgScale
[bin
] = (hPsEncode
->psBandNrgScale
[bin
]==0)
747 ? (hPsEncode
->iidGroupWidthLd
[group
] + 5)
748 : (fixMax(hPsEncode
->iidGroupWidthLd
[group
],hPsEncode
->psBandNrgScale
[bin
]) + 1) ;
753 FDK_PSENC_ERROR
FDKsbrEnc_CreatePSEncode(
754 HANDLE_PS_ENCODE
*phPsEncode
757 FDK_PSENC_ERROR error
= PSENC_OK
;
759 if (phPsEncode
==NULL
) {
760 error
= PSENC_INVALID_HANDLE
;
763 HANDLE_PS_ENCODE hPsEncode
= NULL
;
764 if (NULL
==(hPsEncode
= GetRam_PsEncode())) {
765 error
= PSENC_MEMORY_ERROR
;
768 FDKmemclear(hPsEncode
,sizeof(PS_ENCODE
));
769 *phPsEncode
= hPsEncode
; /* return allocated handle */
775 FDK_PSENC_ERROR
FDKsbrEnc_InitPSEncode(
776 HANDLE_PS_ENCODE hPsEncode
,
777 const PS_BANDS psEncMode
,
778 const FIXP_DBL iidQuantErrorThreshold
781 FDK_PSENC_ERROR error
= PSENC_OK
;
783 if (NULL
==hPsEncode
) {
784 error
= PSENC_INVALID_HANDLE
;
787 if (PSENC_OK
!= (InitPSData(&hPsEncode
->psData
))) {
792 case PS_BANDS_COARSE
:
794 hPsEncode
->nQmfIidGroups
= QMF_GROUPS_LO_RES
;
795 hPsEncode
->nSubQmfIidGroups
= SUBQMF_GROUPS_LO_RES
;
796 FDKmemcpy(hPsEncode
->iidGroupBorders
, iidGroupBordersLoRes
, (hPsEncode
->nQmfIidGroups
+ hPsEncode
->nSubQmfIidGroups
+ 1)*sizeof(INT
));
797 FDKmemcpy(hPsEncode
->subband2parameterIndex
, subband2parameter20
, (hPsEncode
->nQmfIidGroups
+ hPsEncode
->nSubQmfIidGroups
) *sizeof(INT
));
798 FDKmemcpy(hPsEncode
->iidGroupWidthLd
, iidGroupWidthLdLoRes
, (hPsEncode
->nQmfIidGroups
+ hPsEncode
->nSubQmfIidGroups
) *sizeof(UCHAR
));
801 error
= PSENC_INIT_ERROR
;
805 hPsEncode
->psEncMode
= psEncMode
;
806 hPsEncode
->iidQuantErrorThreshold
= iidQuantErrorThreshold
;
807 FDKsbrEnc_initPsBandNrgScale(hPsEncode
);
814 FDK_PSENC_ERROR
FDKsbrEnc_DestroyPSEncode(
815 HANDLE_PS_ENCODE
*phPsEncode
818 FDK_PSENC_ERROR error
= PSENC_OK
;
820 if (NULL
!=phPsEncode
) {
821 FreeRam_PsEncode(phPsEncode
);
828 FIXP_DBL pwrL
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
];
829 FIXP_DBL pwrR
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
];
830 FIXP_DBL ldPwrL
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
];
831 FIXP_DBL ldPwrR
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
];
832 FIXP_DBL pwrCr
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
];
833 FIXP_DBL pwrCi
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
];
838 FDK_PSENC_ERROR
FDKsbrEnc_PSEncode(
839 HANDLE_PS_ENCODE hPsEncode
,
840 HANDLE_PS_OUT hPsOut
,
843 FIXP_DBL
*hybridData
[HYBRID_FRAMESIZE
][MAX_PS_CHANNELS
][2],
848 FDK_PSENC_ERROR error
= PSENC_OK
;
850 HANDLE_PS_DATA hPsData
= &hPsEncode
->psData
;
851 FIXP_DBL iid
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
];
852 FIXP_DBL icc
[PS_MAX_ENVELOPES
][PS_MAX_BANDS
];
853 int envBorder
[PS_MAX_ENVELOPES
+1];
855 int group
, bin
, col
, subband
, band
;
859 int psBands
= (int) hPsEncode
->psEncMode
;
860 int nIidGroups
= hPsEncode
->nQmfIidGroups
+ hPsEncode
->nSubQmfIidGroups
;
861 int nEnvelopes
= fixMin(maxEnvelopes
, (UINT
)PS_MAX_ENVELOPES
);
863 C_ALLOC_SCRATCH_START(pwrData
, PS_PWR_DATA
, 1);
865 for(env
=0; env
<nEnvelopes
+1;env
++) {
866 envBorder
[env
] = fMultI(GetInvInt(nEnvelopes
),frameSize
*env
);
869 for(env
=0; env
<nEnvelopes
;env
++) {
871 /* clear energy array */
872 for (band
=0; band
<psBands
; band
++) {
873 pwrData
->pwrL
[env
][band
] = pwrData
->pwrR
[env
][band
] = pwrData
->pwrCr
[env
][band
] = pwrData
->pwrCi
[env
][band
] = FIXP_DBL(1);
876 /**** calculate energies and correlation ****/
878 /* start with hybrid data */
879 for (group
=0; group
< nIidGroups
; group
++) {
880 /* Translate group to bin */
881 bin
= hPsEncode
->subband2parameterIndex
[group
];
883 /* Translate from 20 bins to 10 bins */
884 if (hPsEncode
->psEncMode
== PS_BANDS_COARSE
) {
888 /* determine group border */
889 int bScale
= hPsEncode
->psBandNrgScale
[bin
];
891 FIXP_DBL pwrL_env_bin
= pwrData
->pwrL
[env
][bin
];
892 FIXP_DBL pwrR_env_bin
= pwrData
->pwrR
[env
][bin
];
893 FIXP_DBL pwrCr_env_bin
= pwrData
->pwrCr
[env
][bin
];
894 FIXP_DBL pwrCi_env_bin
= pwrData
->pwrCi
[env
][bin
];
896 int scale
= (int)dynBandScale
[bin
];
897 for (col
=envBorder
[env
]; col
<envBorder
[env
+1]; col
++) {
898 for (subband
= hPsEncode
->iidGroupBorders
[group
]; subband
< hPsEncode
->iidGroupBorders
[group
+1]; subband
++) {
899 FIXP_QMF l_real
= (hybridData
[col
][0][0][subband
]) << scale
;
900 FIXP_QMF l_imag
= (hybridData
[col
][0][1][subband
]) << scale
;
901 FIXP_QMF r_real
= (hybridData
[col
][1][0][subband
]) << scale
;
902 FIXP_QMF r_imag
= (hybridData
[col
][1][1][subband
]) << scale
;
904 pwrL_env_bin
+= (fPow2Div2(l_real
) + fPow2Div2(l_imag
)) >> bScale
;
905 pwrR_env_bin
+= (fPow2Div2(r_real
) + fPow2Div2(r_imag
)) >> bScale
;
906 pwrCr_env_bin
+= (fMultDiv2(l_real
, r_real
) + fMultDiv2(l_imag
, r_imag
)) >> bScale
;
907 pwrCi_env_bin
+= (fMultDiv2(r_real
, l_imag
) - fMultDiv2(l_real
, r_imag
)) >> bScale
;
910 /* assure, nrg's of left and right channel are not negative; necessary on 16 bit multiply units */
911 pwrData
->pwrL
[env
][bin
] = fixMax((FIXP_DBL
)0,pwrL_env_bin
);
912 pwrData
->pwrR
[env
][bin
] = fixMax((FIXP_DBL
)0,pwrR_env_bin
);
914 pwrData
->pwrCr
[env
][bin
] = pwrCr_env_bin
;
915 pwrData
->pwrCi
[env
][bin
] = pwrCi_env_bin
;
919 /* calc logarithmic energy */
920 LdDataVector(pwrData
->pwrL
[env
], pwrData
->ldPwrL
[env
], psBands
);
921 LdDataVector(pwrData
->pwrR
[env
], pwrData
->ldPwrR
[env
], psBands
);
925 /* calculate iid and icc */
926 calculateIID(pwrData
->ldPwrL
, pwrData
->ldPwrR
, iid
, nEnvelopes
, psBands
);
927 calculateICC(pwrData
->ldPwrL
, pwrData
->ldPwrR
, pwrData
->pwrCr
, pwrData
->pwrCi
, icc
, nEnvelopes
, psBands
);
929 /*** Envelope Reduction ***/
930 while (envelopeReducible(iid
,icc
,psBands
,nEnvelopes
)) {
932 /* sum energies of two neighboring envelopes */
934 for (e
=0; e
<nEnvelopes
; e
++) {
935 FDKsbrEnc_addFIXP_DBL(pwrData
->pwrL
[2*e
], pwrData
->pwrL
[2*e
+1], pwrData
->pwrL
[e
], psBands
);
936 FDKsbrEnc_addFIXP_DBL(pwrData
->pwrR
[2*e
], pwrData
->pwrR
[2*e
+1], pwrData
->pwrR
[e
], psBands
);
937 FDKsbrEnc_addFIXP_DBL(pwrData
->pwrCr
[2*e
],pwrData
->pwrCr
[2*e
+1],pwrData
->pwrCr
[e
],psBands
);
938 FDKsbrEnc_addFIXP_DBL(pwrData
->pwrCi
[2*e
],pwrData
->pwrCi
[2*e
+1],pwrData
->pwrCi
[e
],psBands
);
940 /* calc logarithmic energy */
941 LdDataVector(pwrData
->pwrL
[e
], pwrData
->ldPwrL
[e
], psBands
);
942 LdDataVector(pwrData
->pwrR
[e
], pwrData
->ldPwrR
[e
], psBands
);
944 /* reduce number of envelopes and adjust borders */
945 envBorder
[e
] = envBorder
[2*e
];
947 envBorder
[nEnvelopes
] = envBorder
[2*nEnvelopes
];
949 /* re-calculate iid and icc */
950 calculateIID(pwrData
->ldPwrL
, pwrData
->ldPwrR
, iid
, nEnvelopes
, psBands
);
951 calculateICC(pwrData
->ldPwrL
, pwrData
->ldPwrR
, pwrData
->pwrCr
, pwrData
->pwrCi
, icc
, nEnvelopes
, psBands
);
957 hPsData
->headerCnt
= MAX_PS_NOHEADER_CNT
;
958 hPsData
->iidTimeCnt
= MAX_TIME_DIFF_FRAMES
;
959 hPsData
->iccTimeCnt
= MAX_TIME_DIFF_FRAMES
;
960 hPsData
->noEnvCnt
= MAX_NOENV_CNT
;
963 /*** Parameter processing, quantisation etc ***/
964 processIidData(hPsData
, iid
, psBands
, nEnvelopes
, hPsEncode
->iidQuantErrorThreshold
);
965 processIccData(hPsData
, icc
, psBands
, nEnvelopes
);
968 /*** Initialize output struct ***/
970 /* PS Header on/off ? */
971 if( (hPsData
->headerCnt
<MAX_PS_NOHEADER_CNT
)
972 && ( (hPsData
->iidQuantMode
== hPsData
->iidQuantModeLast
) && (hPsData
->iccQuantMode
== hPsData
->iccQuantModeLast
) )
973 && ( (hPsData
->iidEnable
== hPsData
->iidEnableLast
) && (hPsData
->iccEnable
== hPsData
->iccEnableLast
) ) ) {
974 hPsOut
->enablePSHeader
= 0;
977 hPsOut
->enablePSHeader
= 1;
978 hPsData
->headerCnt
= 0;
981 /* nEnvelopes = 0 ? */
982 if ( (hPsData
->noEnvCnt
< MAX_NOENV_CNT
)
983 && (similarIid(hPsData
, psBands
, nEnvelopes
))
984 && (similarIcc(hPsData
, psBands
, nEnvelopes
)) ) {
985 hPsOut
->nEnvelopes
= nEnvelopes
= 0;
988 hPsData
->noEnvCnt
= 0;
994 hPsOut
->enableIID
= hPsData
->iidEnable
;
995 hPsOut
->iidMode
= getIIDMode(psBands
, hPsData
->iidQuantMode
);
997 hPsOut
->enableICC
= hPsData
->iccEnable
;
998 hPsOut
->iccMode
= getICCMode(psBands
, hPsData
->iccQuantMode
);
1000 hPsOut
->enableIpdOpd
= 0;
1001 hPsOut
->frameClass
= 0;
1002 hPsOut
->nEnvelopes
= nEnvelopes
;
1004 for(env
=0; env
<nEnvelopes
; env
++) {
1005 hPsOut
->frameBorder
[env
] = envBorder
[env
+1];
1008 for(env
=0; env
<hPsOut
->nEnvelopes
; env
++) {
1009 hPsOut
->deltaIID
[env
] = (PS_DELTA
)hPsData
->iidDiffMode
[env
];
1011 for(band
=0; band
<psBands
; band
++) {
1012 hPsOut
->iid
[env
][band
] = hPsData
->iidIdx
[env
][band
];
1016 for(env
=0; env
<hPsOut
->nEnvelopes
; env
++) {
1017 hPsOut
->deltaICC
[env
] = (PS_DELTA
)hPsData
->iccDiffMode
[env
];
1018 for(band
=0; band
<psBands
; band
++) {
1019 hPsOut
->icc
[env
][band
] = hPsData
->iccIdx
[env
][band
];
1023 /* IPD OPD not supported right now */
1024 FDKmemclear(hPsOut
->ipd
, PS_MAX_ENVELOPES
*PS_MAX_BANDS
*sizeof(PS_DELTA
));
1025 for(env
=0; env
<PS_MAX_ENVELOPES
; env
++) {
1026 hPsOut
->deltaIPD
[env
] = PS_DELTA_FREQ
;
1027 hPsOut
->deltaOPD
[env
] = PS_DELTA_FREQ
;
1030 FDKmemclear(hPsOut
->ipdLast
, PS_MAX_BANDS
*sizeof(INT
));
1031 FDKmemclear(hPsOut
->opdLast
, PS_MAX_BANDS
*sizeof(INT
));
1033 for(band
=0; band
<PS_MAX_BANDS
; band
++) {
1034 hPsOut
->iidLast
[band
] = hPsData
->iidIdxLast
[band
];
1035 hPsOut
->iccLast
[band
] = hPsData
->iccIdxLast
[band
];
1038 /* save iids and iccs for differential time coding in the next frame */
1039 hPsData
->nEnvelopesLast
= nEnvelopes
;
1040 hPsData
->iidEnableLast
= hPsData
->iidEnable
;
1041 hPsData
->iccEnableLast
= hPsData
->iccEnable
;
1042 hPsData
->iidQuantModeLast
= hPsData
->iidQuantMode
;
1043 hPsData
->iccQuantModeLast
= hPsData
->iccQuantMode
;
1044 for (i
=0; i
<psBands
; i
++) {
1045 hPsData
->iidIdxLast
[i
] = hPsData
->iidIdx
[nEnvelopes
-1][i
];
1046 hPsData
->iccIdxLast
[i
] = hPsData
->iccIdx
[nEnvelopes
-1][i
];
1048 } /* Envelope > 0 */
1050 C_ALLOC_SCRATCH_END(pwrData
, PS_PWR_DATA
, 1)