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 /********************** Fraunhofer IIS FDK AAC Encoder lib ******************
86 Author(s): M. Neusinger
87 Description: Compressor for AAC Metadata Generator
89 ******************************************************************************/
92 #include "metadata_compressor.h"
93 #include "channel_map.h"
96 #define LOG2 0.69314718056f /* natural logarithm of 2 */
97 #define ILOG2 1.442695041f /* 1/LOG2 */
98 #define FIXP_ILOG2_DIV2 (FL2FXCONST_DBL(ILOG2/2))
100 /*----------------- defines ----------------------*/
102 #define MAX_DRC_CHANNELS (8) /*!< Max number of audio input channels. */
103 #define DOWNMIX_SHIFT (3) /*!< Max 8 channel. */
104 #define WEIGHTING_FILTER_SHIFT (2) /*!< Scaling used in weighting filter. */
106 #define METADATA_INT_BITS 10
107 #define METADATA_LINT_BITS 20
108 #define METADATA_INT_SCALE (INT64(1)<<(METADATA_INT_BITS))
109 #define METADATA_FRACT_BITS (DFRACT_BITS-1-METADATA_INT_BITS)
110 #define METADATA_FRACT_SCALE (INT64(1)<<(METADATA_FRACT_BITS))
113 * Enum for channel assignment.
127 /*--------------- structure definitions --------------------*/
130 * Structure holds weighting filter filter states.
132 struct WEIGHTING_STATES
{
140 * Dynamic Range Control compressor structure.
144 FIXP_DBL maxBoostThr
[2]; /*!< Max boost threshold. */
145 FIXP_DBL boostThr
[2]; /*!< Boost threshold. */
146 FIXP_DBL earlyCutThr
[2]; /*!< Early cut threshold. */
147 FIXP_DBL cutThr
[2]; /*!< Cut threshold. */
148 FIXP_DBL maxCutThr
[2]; /*!< Max cut threshold. */
150 FIXP_DBL boostFac
[2]; /*!< Precalculated factor for boost compression. */
151 FIXP_DBL earlyCutFac
[2]; /*!< Precalculated factor for early cut compression. */
152 FIXP_DBL cutFac
[2]; /*!< Precalculated factor for cut compression. */
154 FIXP_DBL maxBoost
[2]; /*!< Maximum boost. */
155 FIXP_DBL maxCut
[2]; /*!< Maximum cut. */
156 FIXP_DBL maxEarlyCut
[2]; /*!< Maximum early cut. */
158 FIXP_DBL fastAttack
[2]; /*!< Fast attack coefficient. */
159 FIXP_DBL fastDecay
[2]; /*!< Fast release coefficient. */
160 FIXP_DBL slowAttack
[2]; /*!< Slow attack coefficient. */
161 FIXP_DBL slowDecay
[2]; /*!< Slow release coefficient. */
162 UINT holdOff
[2]; /*!< Hold time in blocks. */
164 FIXP_DBL attackThr
[2]; /*!< Slow/fast attack threshold. */
165 FIXP_DBL decayThr
[2]; /*!< Slow/fast release threshold. */
167 DRC_PROFILE profile
[2]; /*!< DRC profile. */
168 INT blockLength
; /*!< Block length in samples. */
169 UINT sampleRate
; /*!< Sample rate. */
170 CHANNEL_MODE chanConfig
; /*!< Channel configuration. */
172 UCHAR useWeighting
; /*!< Use weighting filter. */
174 UINT channels
; /*!< Number of channels. */
175 UINT fullChannels
; /*!< Number of full range channels. */
176 INT channelIdx
[9]; /*!< Offsets of interleaved channel samples (L, R, C, LFE, Ls, Rs, S, Ls2, Rs2). */
178 FIXP_DBL smoothLevel
[2]; /*!< level smoothing states */
179 FIXP_DBL smoothGain
[2]; /*!< gain smoothing states */
180 UINT holdCnt
[2]; /*!< hold counter */
182 FIXP_DBL limGain
[2]; /*!< limiter gain */
183 FIXP_DBL limDecay
; /*!< limiter decay (linear) */
184 FIXP_DBL prevPeak
[2]; /*!< max peak of previous block (stereo/mono)*/
186 WEIGHTING_STATES filter
[MAX_DRC_CHANNELS
]; /*!< array holds weighting filter states */
190 /*---------------- constants -----------------------*/
195 static const FIXP_DBL tabMaxBoostThr
[] = {
196 (FIXP_DBL
)(-43<<METADATA_FRACT_BITS
),
197 (FIXP_DBL
)(-53<<METADATA_FRACT_BITS
),
198 (FIXP_DBL
)(-55<<METADATA_FRACT_BITS
),
199 (FIXP_DBL
)(-65<<METADATA_FRACT_BITS
),
200 (FIXP_DBL
)(-50<<METADATA_FRACT_BITS
),
201 (FIXP_DBL
)(-40<<METADATA_FRACT_BITS
)
203 static const FIXP_DBL tabBoostThr
[] = {
204 (FIXP_DBL
)(-31<<METADATA_FRACT_BITS
),
205 (FIXP_DBL
)(-41<<METADATA_FRACT_BITS
),
206 (FIXP_DBL
)(-31<<METADATA_FRACT_BITS
),
207 (FIXP_DBL
)(-41<<METADATA_FRACT_BITS
),
208 (FIXP_DBL
)(-31<<METADATA_FRACT_BITS
),
209 (FIXP_DBL
)(-31<<METADATA_FRACT_BITS
)
211 static const FIXP_DBL tabEarlyCutThr
[] = {
212 (FIXP_DBL
)(-26<<METADATA_FRACT_BITS
),
213 (FIXP_DBL
)(-21<<METADATA_FRACT_BITS
),
214 (FIXP_DBL
)(-26<<METADATA_FRACT_BITS
),
215 (FIXP_DBL
)(-21<<METADATA_FRACT_BITS
),
216 (FIXP_DBL
)(-26<<METADATA_FRACT_BITS
),
217 (FIXP_DBL
)(-20<<METADATA_FRACT_BITS
)
219 static const FIXP_DBL tabCutThr
[] = {
220 (FIXP_DBL
)(-16<<METADATA_FRACT_BITS
),
221 (FIXP_DBL
)(-11<<METADATA_FRACT_BITS
),
222 (FIXP_DBL
)(-16<<METADATA_FRACT_BITS
),
223 (FIXP_DBL
)(-21<<METADATA_FRACT_BITS
),
224 (FIXP_DBL
)(-16<<METADATA_FRACT_BITS
),
225 (FIXP_DBL
)(-10<<METADATA_FRACT_BITS
)
227 static const FIXP_DBL tabMaxCutThr
[] = {
228 (FIXP_DBL
)(4<<METADATA_FRACT_BITS
),
229 (FIXP_DBL
)(9<<METADATA_FRACT_BITS
),
230 (FIXP_DBL
)(4<<METADATA_FRACT_BITS
),
231 (FIXP_DBL
)(9<<METADATA_FRACT_BITS
),
232 (FIXP_DBL
)(4<<METADATA_FRACT_BITS
),
233 (FIXP_DBL
)(4<<METADATA_FRACT_BITS
)
235 static const FIXP_DBL tabBoostRatio
[] = {
236 FL2FXCONST_DBL( ((1.f
/2.f
) - 1.f
) ),
237 FL2FXCONST_DBL( ((1.f
/2.f
) - 1.f
) ),
238 FL2FXCONST_DBL( ((1.f
/2.f
) - 1.f
) ),
239 FL2FXCONST_DBL( ((1.f
/2.f
) - 1.f
) ),
240 FL2FXCONST_DBL( ((1.f
/5.f
) - 1.f
) ),
241 FL2FXCONST_DBL( ((1.f
/5.f
) - 1.f
) )
243 static const FIXP_DBL tabEarlyCutRatio
[] = {
244 FL2FXCONST_DBL( ((1.f
/2.f
) - 1.f
) ),
245 FL2FXCONST_DBL( ((1.f
/2.f
) - 1.f
) ),
246 FL2FXCONST_DBL( ((1.f
/2.f
) - 1.f
) ),
247 FL2FXCONST_DBL( ((1.f
/1.f
) - 1.f
) ),
248 FL2FXCONST_DBL( ((1.f
/2.f
) - 1.f
) ),
249 FL2FXCONST_DBL( ((1.f
/2.f
) - 1.f
) )
251 static const FIXP_DBL tabCutRatio
[] = {
252 FL2FXCONST_DBL( ((1.f
/20.f
) - 1.f
) ),
253 FL2FXCONST_DBL( ((1.f
/20.f
) - 1.f
) ),
254 FL2FXCONST_DBL( ((1.f
/20.f
) - 1.f
) ),
255 FL2FXCONST_DBL( ((1.f
/ 2.f
) - 1.f
) ),
256 FL2FXCONST_DBL( ((1.f
/20.f
) - 1.f
) ),
257 FL2FXCONST_DBL( ((1.f
/20.f
) - 1.f
) )
259 static const FIXP_DBL tabMaxBoost
[] = {
260 (FIXP_DBL
)( 6<<METADATA_FRACT_BITS
),
261 (FIXP_DBL
)( 6<<METADATA_FRACT_BITS
),
262 (FIXP_DBL
)(12<<METADATA_FRACT_BITS
),
263 (FIXP_DBL
)(12<<METADATA_FRACT_BITS
),
264 (FIXP_DBL
)(15<<METADATA_FRACT_BITS
),
265 (FIXP_DBL
)(15<<METADATA_FRACT_BITS
)
267 static const FIXP_DBL tabMaxCut
[] = {
268 (FIXP_DBL
)(24<<METADATA_FRACT_BITS
),
269 (FIXP_DBL
)(24<<METADATA_FRACT_BITS
),
270 (FIXP_DBL
)(24<<METADATA_FRACT_BITS
),
271 (FIXP_DBL
)(15<<METADATA_FRACT_BITS
),
272 (FIXP_DBL
)(24<<METADATA_FRACT_BITS
),
273 (FIXP_DBL
)(24<<METADATA_FRACT_BITS
)
275 static const FIXP_DBL tabFastAttack
[] = {
276 FL2FXCONST_DBL((10.f
/1000.f
)/METADATA_INT_SCALE
),
277 FL2FXCONST_DBL((10.f
/1000.f
)/METADATA_INT_SCALE
),
278 FL2FXCONST_DBL((10.f
/1000.f
)/METADATA_INT_SCALE
),
279 FL2FXCONST_DBL((10.f
/1000.f
)/METADATA_INT_SCALE
),
280 FL2FXCONST_DBL((10.f
/1000.f
)/METADATA_INT_SCALE
),
281 FL2FXCONST_DBL( (0.f
/1000.f
)/METADATA_INT_SCALE
)
283 static const FIXP_DBL tabFastDecay
[] = {
284 FL2FXCONST_DBL((1000.f
/1000.f
)/METADATA_INT_SCALE
),
285 FL2FXCONST_DBL((1000.f
/1000.f
)/METADATA_INT_SCALE
),
286 FL2FXCONST_DBL((1000.f
/1000.f
)/METADATA_INT_SCALE
),
287 FL2FXCONST_DBL((1000.f
/1000.f
)/METADATA_INT_SCALE
),
288 FL2FXCONST_DBL( (200.f
/1000.f
)/METADATA_INT_SCALE
),
289 FL2FXCONST_DBL( (0.f
/1000.f
)/METADATA_INT_SCALE
)
291 static const FIXP_DBL tabSlowAttack
[] = {
292 FL2FXCONST_DBL((100.f
/1000.f
)/METADATA_INT_SCALE
),
293 FL2FXCONST_DBL((100.f
/1000.f
)/METADATA_INT_SCALE
),
294 FL2FXCONST_DBL((100.f
/1000.f
)/METADATA_INT_SCALE
),
295 FL2FXCONST_DBL((100.f
/1000.f
)/METADATA_INT_SCALE
),
296 FL2FXCONST_DBL((100.f
/1000.f
)/METADATA_INT_SCALE
),
297 FL2FXCONST_DBL( (0.f
/1000.f
)/METADATA_INT_SCALE
)
299 static const FIXP_DBL tabSlowDecay
[] = {
300 FL2FXCONST_DBL( (3000.f
/1000.f
)/METADATA_INT_SCALE
),
301 FL2FXCONST_DBL( (3000.f
/1000.f
)/METADATA_INT_SCALE
),
302 FL2FXCONST_DBL((10000.f
/1000.f
)/METADATA_INT_SCALE
),
303 FL2FXCONST_DBL( (3000.f
/1000.f
)/METADATA_INT_SCALE
),
304 FL2FXCONST_DBL( (1000.f
/1000.f
)/METADATA_INT_SCALE
),
305 FL2FXCONST_DBL( (0.f
/1000.f
)/METADATA_INT_SCALE
)
308 static const INT tabHoldOff
[] = { 10, 10, 10, 10, 10, 0 };
310 static const FIXP_DBL tabAttackThr
[] = {
311 (FIXP_DBL
)(15<<METADATA_FRACT_BITS
),
312 (FIXP_DBL
)(15<<METADATA_FRACT_BITS
),
313 (FIXP_DBL
)(15<<METADATA_FRACT_BITS
),
314 (FIXP_DBL
)(15<<METADATA_FRACT_BITS
),
315 (FIXP_DBL
)(10<<METADATA_FRACT_BITS
),
316 (FIXP_DBL
)(0<<METADATA_FRACT_BITS
)
318 static const FIXP_DBL tabDecayThr
[] = {
319 (FIXP_DBL
)(20<<METADATA_FRACT_BITS
),
320 (FIXP_DBL
)(20<<METADATA_FRACT_BITS
),
321 (FIXP_DBL
)(20<<METADATA_FRACT_BITS
),
322 (FIXP_DBL
)(20<<METADATA_FRACT_BITS
),
323 (FIXP_DBL
)(10<<METADATA_FRACT_BITS
),
324 (FIXP_DBL
)( 0<<METADATA_FRACT_BITS
)
328 * Weighting filter coefficients (biquad bandpass).
330 static const FIXP_DBL b0
= FL2FXCONST_DBL(0.53050662f
); /* b1 = 0, b2 = -b0 */
331 static const FIXP_DBL a1
= FL2FXCONST_DBL(-0.95237983f
), a2
= FL2FXCONST_DBL(-0.02248836f
); /* a0 = 1 */
334 /*------------- function definitions ----------------*/
337 * \brief Calculate scaling factor for denoted processing block.
339 * \param blockLength Length of processing block.
341 * \return shiftFactor
343 static UINT
getShiftFactor(
348 for(ldN
=1;(((UINT
)1)<<ldN
) < length
;ldN
++);
354 * \brief Sum up fixpoint values with best possible accuracy.
356 * \param value1 First input value.
357 * \param q1 Scaling factor of first input value.
358 * \param pValue2 Pointer to second input value, will be modified on return.
359 * \param pQ2 Pointer to second scaling factor, will be modified on return.
364 const FIXP_DBL value1
,
366 FIXP_DBL
*const pValue2
,
370 const int headroom1
= fNormz(fixp_abs(value1
))-1;
371 const int headroom2
= fNormz(fixp_abs(*pValue2
))-1;
372 int resultScale
= fixMax(q1
-headroom1
, (*pQ2
)-headroom2
);
374 if ( (value1
!=FL2FXCONST_DBL(0.f
)) && (*pValue2
!=FL2FXCONST_DBL(0.f
)) ) {
378 *pValue2
= scaleValue(value1
, q1
-resultScale
) + scaleValue(*pValue2
, (*pQ2
)-resultScale
);
379 *pQ2
= (*pValue2
!=(FIXP_DBL
)0) ? resultScale
: DFRACT_BITS
-1;
383 * \brief Function for converting time constant to filter coefficient.
385 * \param t Time constant.
386 * \param sampleRate Sampling rate in Hz.
387 * \param blockLength Length of processing block in samples per channel.
389 * \return result = 1.0 - exp(-1.0/((t) * (f)))
391 static FIXP_DBL
tc2Coeff(
393 const INT sampleRate
,
394 const INT blockLength
397 FIXP_DBL sampleRateFract
;
398 FIXP_DBL blockLengthFract
;
400 FIXP_DBL exponent
, result
;
403 /* f = sampleRate/blockLength */
404 sampleRateFract
= (FIXP_DBL
)(sampleRate
<<(DFRACT_BITS
-1-METADATA_LINT_BITS
));
405 blockLengthFract
= (FIXP_DBL
)(blockLength
<<(DFRACT_BITS
-1-METADATA_LINT_BITS
));
406 f
= fDivNorm(sampleRateFract
, blockLengthFract
, &e_res
);
407 f
= scaleValue(f
, e_res
-METADATA_INT_BITS
); /* convert to METADATA_FRACT */
410 product
= fMultNorm(t
, f
, &e_res
);
411 product
= scaleValue(product
, e_res
+METADATA_INT_BITS
); /* convert to METADATA_FRACT */
413 /* exponent = (-1.0/((t) * (f))) */
414 exponent
= fDivNorm(METADATA_FRACT_SCALE
, product
, &e_res
);
415 exponent
= scaleValue(exponent
, e_res
-METADATA_INT_BITS
); /* convert to METADATA_FRACT */
417 /* exponent * ld(e) */
418 exponent
= fMult(exponent
,FIXP_ILOG2_DIV2
)<<1; /* e^(x) = 2^(x*ld(e)) */
420 /* exp(-1.0/((t) * (f))) */
421 result
= f2Pow(-exponent
, DFRACT_BITS
-1-METADATA_FRACT_BITS
, &e_res
);
423 /* result = 1.0 - exp(-1.0/((t) * (f))) */
424 result
= (FIXP_DBL
)MAXVAL_DBL
- scaleValue(result
, e_res
);
429 INT
FDK_DRC_Generator_Open(
434 HDRC_COMP hDcComp
= NULL
;
436 if (phDrcComp
== NULL
) {
441 /* allocate memory */
442 hDcComp
= (HDRC_COMP
)FDKcalloc(1, sizeof(DRC_COMP
));
444 if (hDcComp
== NULL
) {
449 FDKmemclear(hDcComp
, sizeof(DRC_COMP
));
451 /* Return drc compressor instance */
452 *phDrcComp
= hDcComp
;
455 FDK_DRC_Generator_Close(&hDcComp
);
459 INT
FDK_DRC_Generator_Close(
463 if (phDrcComp
== NULL
) {
466 if (*phDrcComp
!= NULL
) {
474 INT
FDK_DRC_Generator_Initialize(
476 const DRC_PROFILE profileLine
,
477 const DRC_PROFILE profileRF
,
478 const INT blockLength
,
479 const UINT sampleRate
,
480 const CHANNEL_MODE channelMode
,
481 const CHANNEL_ORDER channelOrder
,
482 const UCHAR useWeighting
486 CHANNEL_MAPPING channelMapping
;
488 drcComp
->limDecay
= FL2FXCONST_DBL( ((0.006f
/ 256) * blockLength
) / METADATA_INT_SCALE
);
490 /* Save parameters. */
491 drcComp
->blockLength
= blockLength
;
492 drcComp
->sampleRate
= sampleRate
;
493 drcComp
->chanConfig
= channelMode
;
494 drcComp
->useWeighting
= useWeighting
;
496 if (FDK_DRC_Generator_setDrcProfile(drcComp
, profileLine
, profileRF
)!=0) { /* expects initialized blockLength and sampleRate */
500 /* Set number of channels and channel offsets. */
501 if (FDKaacEnc_InitChannelMapping(channelMode
, channelOrder
, &channelMapping
)!=AAC_ENC_OK
) {
505 for (i
= 0; i
< 9; i
++) drcComp
->channelIdx
[i
] = -1;
507 switch (channelMode
) {
508 case MODE_1
: /* mono */
509 drcComp
->channelIdx
[C
] = channelMapping
.elInfo
[0].ChannelIndex
[0];
511 case MODE_2
: /* stereo */
512 drcComp
->channelIdx
[L
] = channelMapping
.elInfo
[0].ChannelIndex
[0];
513 drcComp
->channelIdx
[R
] = channelMapping
.elInfo
[0].ChannelIndex
[1];
515 case MODE_1_2
: /* 3ch */
516 drcComp
->channelIdx
[L
] = channelMapping
.elInfo
[1].ChannelIndex
[0];
517 drcComp
->channelIdx
[R
] = channelMapping
.elInfo
[1].ChannelIndex
[1];
518 drcComp
->channelIdx
[C
] = channelMapping
.elInfo
[0].ChannelIndex
[0];
520 case MODE_1_2_1
: /* 4ch */
521 drcComp
->channelIdx
[L
] = channelMapping
.elInfo
[1].ChannelIndex
[0];
522 drcComp
->channelIdx
[R
] = channelMapping
.elInfo
[1].ChannelIndex
[1];
523 drcComp
->channelIdx
[C
] = channelMapping
.elInfo
[0].ChannelIndex
[0];
524 drcComp
->channelIdx
[S
] = channelMapping
.elInfo
[2].ChannelIndex
[0];
526 case MODE_1_2_2
: /* 5ch */
527 drcComp
->channelIdx
[L
] = channelMapping
.elInfo
[1].ChannelIndex
[0];
528 drcComp
->channelIdx
[R
] = channelMapping
.elInfo
[1].ChannelIndex
[1];
529 drcComp
->channelIdx
[C
] = channelMapping
.elInfo
[0].ChannelIndex
[0];
530 drcComp
->channelIdx
[LS
] = channelMapping
.elInfo
[2].ChannelIndex
[0];
531 drcComp
->channelIdx
[RS
] = channelMapping
.elInfo
[2].ChannelIndex
[1];
533 case MODE_1_2_2_1
: /* 5.1 ch */
534 drcComp
->channelIdx
[L
] = channelMapping
.elInfo
[1].ChannelIndex
[0];
535 drcComp
->channelIdx
[R
] = channelMapping
.elInfo
[1].ChannelIndex
[1];
536 drcComp
->channelIdx
[C
] = channelMapping
.elInfo
[0].ChannelIndex
[0];
537 drcComp
->channelIdx
[LFE
] = channelMapping
.elInfo
[3].ChannelIndex
[0];
538 drcComp
->channelIdx
[LS
] = channelMapping
.elInfo
[2].ChannelIndex
[0];
539 drcComp
->channelIdx
[RS
] = channelMapping
.elInfo
[2].ChannelIndex
[1];
541 case MODE_1_2_2_2_1
: /* 7.1 ch */
542 case MODE_7_1_FRONT_CENTER
:
543 drcComp
->channelIdx
[L
] = channelMapping
.elInfo
[2].ChannelIndex
[0]; /* l */
544 drcComp
->channelIdx
[R
] = channelMapping
.elInfo
[2].ChannelIndex
[1]; /* r */
545 drcComp
->channelIdx
[C
] = channelMapping
.elInfo
[0].ChannelIndex
[0]; /* c */
546 drcComp
->channelIdx
[LFE
] = channelMapping
.elInfo
[4].ChannelIndex
[0]; /* lfe */
547 drcComp
->channelIdx
[LS
] = channelMapping
.elInfo
[3].ChannelIndex
[0]; /* ls */
548 drcComp
->channelIdx
[RS
] = channelMapping
.elInfo
[3].ChannelIndex
[1]; /* rs */
549 drcComp
->channelIdx
[LS2
] = channelMapping
.elInfo
[1].ChannelIndex
[0]; /* lc */
550 drcComp
->channelIdx
[RS2
] = channelMapping
.elInfo
[1].ChannelIndex
[1]; /* rc */
552 case MODE_7_1_REAR_SURROUND
:
553 drcComp
->channelIdx
[L
] = channelMapping
.elInfo
[1].ChannelIndex
[0]; /* l */
554 drcComp
->channelIdx
[R
] = channelMapping
.elInfo
[1].ChannelIndex
[1]; /* r */
555 drcComp
->channelIdx
[C
] = channelMapping
.elInfo
[0].ChannelIndex
[0]; /* c */
556 drcComp
->channelIdx
[LFE
] = channelMapping
.elInfo
[4].ChannelIndex
[0]; /* lfe */
557 drcComp
->channelIdx
[LS
] = channelMapping
.elInfo
[3].ChannelIndex
[0]; /* lrear */
558 drcComp
->channelIdx
[RS
] = channelMapping
.elInfo
[3].ChannelIndex
[1]; /* rrear */
559 drcComp
->channelIdx
[LS2
] = channelMapping
.elInfo
[2].ChannelIndex
[0]; /* ls */
560 drcComp
->channelIdx
[RS2
] = channelMapping
.elInfo
[2].ChannelIndex
[1]; /* rs */
564 case MODE_1_1_1_1_1_1
:
565 case MODE_1_1_1_1_1_1_1_1
:
566 case MODE_1_1_1_1_1_1_1_1_1_1_1_1
:
570 case MODE_2_2_2_2_2_2
:
575 drcComp
->fullChannels
= channelMapping
.nChannelsEff
;
576 drcComp
->channels
= channelMapping
.nChannels
;
579 drcComp
->smoothLevel
[0] = drcComp
->smoothLevel
[1] = (FIXP_DBL
)(-135<<METADATA_FRACT_BITS
);
581 FDKmemclear(drcComp
->smoothGain
, sizeof(drcComp
->smoothGain
));
582 FDKmemclear(drcComp
->holdCnt
, sizeof(drcComp
->holdCnt
));
583 FDKmemclear(drcComp
->limGain
, sizeof(drcComp
->limGain
));
584 FDKmemclear(drcComp
->prevPeak
, sizeof(drcComp
->prevPeak
));
585 FDKmemclear(drcComp
->filter
, sizeof(drcComp
->filter
));
591 INT
FDK_DRC_Generator_setDrcProfile(
593 const DRC_PROFILE profileLine
,
594 const DRC_PROFILE profileRF
599 drcComp
->profile
[0] = profileLine
;
600 drcComp
->profile
[1] = profileRF
;
602 for (i
= 0; i
< 2; i
++) {
603 /* get profile index */
604 switch (drcComp
->profile
[i
]) {
606 case DRC_FILMSTANDARD
: profileIdx
= 0; break;
607 case DRC_FILMLIGHT
: profileIdx
= 1; break;
608 case DRC_MUSICSTANDARD
: profileIdx
= 2; break;
609 case DRC_MUSICLIGHT
: profileIdx
= 3; break;
610 case DRC_SPEECH
: profileIdx
= 4; break;
611 case DRC_DELAY_TEST
: profileIdx
= 5; break;
612 default: return (-1);
615 /* get parameters for selected profile */
616 if (profileIdx
>= 0) {
617 drcComp
->maxBoostThr
[i
] = tabMaxBoostThr
[profileIdx
];
618 drcComp
->boostThr
[i
] = tabBoostThr
[profileIdx
];
619 drcComp
->earlyCutThr
[i
] = tabEarlyCutThr
[profileIdx
];
620 drcComp
->cutThr
[i
] = tabCutThr
[profileIdx
];
621 drcComp
->maxCutThr
[i
] = tabMaxCutThr
[profileIdx
];
623 drcComp
->boostFac
[i
] = tabBoostRatio
[profileIdx
];
624 drcComp
->earlyCutFac
[i
] = tabEarlyCutRatio
[profileIdx
];
625 drcComp
->cutFac
[i
] = tabCutRatio
[profileIdx
];
627 drcComp
->maxBoost
[i
] = tabMaxBoost
[profileIdx
];
628 drcComp
->maxCut
[i
] = tabMaxCut
[profileIdx
];
629 drcComp
->maxEarlyCut
[i
] = - fMult((drcComp
->cutThr
[i
] - drcComp
->earlyCutThr
[i
]), drcComp
->earlyCutFac
[i
]); /* no scaling after mult needed, earlyCutFac is in FIXP_DBL */
631 drcComp
->fastAttack
[i
] = tc2Coeff(tabFastAttack
[profileIdx
], drcComp
->sampleRate
, drcComp
->blockLength
);
632 drcComp
->fastDecay
[i
] = tc2Coeff(tabFastDecay
[profileIdx
], drcComp
->sampleRate
, drcComp
->blockLength
);
633 drcComp
->slowAttack
[i
] = tc2Coeff(tabSlowAttack
[profileIdx
], drcComp
->sampleRate
, drcComp
->blockLength
);
634 drcComp
->slowDecay
[i
] = tc2Coeff(tabSlowDecay
[profileIdx
], drcComp
->sampleRate
, drcComp
->blockLength
);
635 drcComp
->holdOff
[i
] = tabHoldOff
[profileIdx
] * 256 / drcComp
->blockLength
;
637 drcComp
->attackThr
[i
] = tabAttackThr
[profileIdx
];
638 drcComp
->decayThr
[i
] = tabDecayThr
[profileIdx
];
641 drcComp
->smoothGain
[i
] = FL2FXCONST_DBL(0.f
);
647 INT
FDK_DRC_Generator_Calc(
649 const INT_PCM
* const inSamples
,
651 const INT drc_TargetRefLevel
,
652 const INT comp_TargetRefLevel
,
663 /**************************************************************************
665 **************************************************************************/
666 if ((drcComp
->profile
[0] != DRC_NONE
) || (drcComp
->profile
[1] != DRC_NONE
)) {
667 /* Calc loudness level */
668 FIXP_DBL level_b
= FL2FXCONST_DBL(0.f
);
669 int level_e
= DFRACT_BITS
-1;
671 /* Increase energy time resolution with shorter processing blocks. 32 is an empiric value. */
672 const int granuleLength
= fixMin(32, drcComp
->blockLength
);
674 if (drcComp
->useWeighting
) {
675 FIXP_DBL x1
, x2
, y
, y1
, y2
;
676 /* sum of filter coefficients about 2.5 -> squared value is 6.25
677 WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce granuleShift by 1.
679 const int granuleShift
= getShiftFactor(granuleLength
)-1;
681 for (c
= 0; c
< (int)drcComp
->channels
; c
++) {
682 const INT_PCM
* pSamples
= &inSamples
[c
];
684 if (c
== drcComp
->channelIdx
[LFE
]) {
685 continue; /* skip LFE */
688 /* get filter states */
689 x1
= drcComp
->filter
[c
].x1
;
690 x2
= drcComp
->filter
[c
].x2
;
691 y1
= drcComp
->filter
[c
].y1
;
692 y2
= drcComp
->filter
[c
].y2
;
699 FIXP_DBL accu
= FL2FXCONST_DBL(0.f
);
701 for (i
=offset
; i
< fixMin(offset
+granuleLength
,drcComp
->blockLength
); i
++) {
702 /* apply weighting filter */
703 FIXP_DBL x
= FX_PCM2FX_DBL((FIXP_PCM
)pSamples
[i
*drcComp
->channels
]) >> WEIGHTING_FILTER_SHIFT
;
705 /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */
706 y
= fMult(b0
,x
-x2
) - fMult(a1
,y1
) - fMult(a2
,y2
);
713 accu
+= fPow2Div2(y
)>>(granuleShift
-1); /* partial energy */
716 fixpAdd(accu
, granuleShift
+2*WEIGHTING_FILTER_SHIFT
, &level_b
, &level_e
); /* sup up partial energies */
718 } while ( i
< drcComp
->blockLength
);
721 /* save filter states */
722 drcComp
->filter
[c
].x1
= x1
;
723 drcComp
->filter
[c
].x2
= x2
;
724 drcComp
->filter
[c
].y1
= y1
;
725 drcComp
->filter
[c
].y2
= y2
;
729 const int granuleShift
= getShiftFactor(granuleLength
);
731 for (c
= 0; c
< (int)drcComp
->channels
; c
++) {
732 const INT_PCM
* pSamples
= &inSamples
[c
];
734 if ((int)c
== drcComp
->channelIdx
[LFE
]) {
735 continue; /* skip LFE */
742 FIXP_DBL accu
= FL2FXCONST_DBL(0.f
);
744 for (i
=offset
; i
< fixMin(offset
+granuleLength
,drcComp
->blockLength
); i
++) {
746 accu
+= fPow2Div2((FIXP_PCM
)pSamples
[i
*drcComp
->channels
])>>(granuleShift
-1);
749 fixpAdd(accu
, granuleShift
, &level_b
, &level_e
); /* sup up partial energies */
751 } while ( i
< drcComp
->blockLength
);
756 * Convert to dBFS, apply dialnorm
760 /* descaled level in ld64 representation */
761 FIXP_DBL ldLevel
= CalcLdData(level_b
) + (FIXP_DBL
)((level_e
-12)<<(DFRACT_BITS
-1-LD_DATA_SHIFT
)) - CalcLdData((FIXP_DBL
)(drcComp
->blockLength
<<(DFRACT_BITS
-1-12)));
763 /* if (level < 1e-10) level = 1e-10f; */
764 ldLevel
= FDKmax(ldLevel
, FL2FXCONST_DBL(-0.51905126482615036685473741085772f
));
766 /* level = 10 * log(level)/log(10) + 3;
767 * = 10*log(2)/log(10) * ld(level) + 3;
768 * = 10 * 0.30102999566398119521373889472449 * ld(level) + 3
769 * = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3)
770 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64
772 * additional scaling with METADATA_FRACT_BITS:
773 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64 * 2^(METADATA_FRACT_BITS)
774 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT)
775 * = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * ( 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 )
777 FIXP_DBL level
= fMult((FIXP_DBL
)(10<<(METADATA_FRACT_BITS
+LD_DATA_SHIFT
)), fMult( FL2FXCONST_DBL(0.30102999566398119521373889472449f
), ldLevel
) + (FIXP_DBL
)(FL2FXCONST_DBL(0.3f
)>>LD_DATA_SHIFT
) );
779 /* level -= dialnorm + 31 */ /* this is fixed to Dolby-ReferenceLevel as compressor profiles are defined relative to this */
780 level
-= ((FIXP_DBL
)(dialnorm
<<(METADATA_FRACT_BITS
-16)) + (FIXP_DBL
)(31<<METADATA_FRACT_BITS
));
782 for (i
= 0; i
< 2; i
++) {
783 if (drcComp
->profile
[i
] == DRC_NONE
) {
785 drcComp
->smoothGain
[i
] = FL2FXCONST_DBL(0.f
);
788 FIXP_DBL gain
, alpha
, lvl2smthlvl
;
790 /* calc static gain */
791 if (level
<= drcComp
->maxBoostThr
[i
]) {
793 gain
= drcComp
->maxBoost
[i
];
795 else if (level
< drcComp
->boostThr
[i
]) {
797 gain
= fMult((level
- drcComp
->boostThr
[i
]),drcComp
->boostFac
[i
]);
799 else if (level
<= drcComp
->earlyCutThr
[i
]) {
801 gain
= FL2FXCONST_DBL(0.f
);
803 else if (level
<= drcComp
->cutThr
[i
]) {
804 /* early cut range */
805 gain
= fMult((level
- drcComp
->earlyCutThr
[i
]), drcComp
->earlyCutFac
[i
]);
807 else if (level
< drcComp
->maxCutThr
[i
]) {
809 gain
= fMult((level
- drcComp
->cutThr
[i
]), drcComp
->cutFac
[i
]) - drcComp
->maxEarlyCut
[i
];
813 gain
= -drcComp
->maxCut
[i
];
816 /* choose time constant */
817 lvl2smthlvl
= level
- drcComp
->smoothLevel
[i
];
818 if (gain
< drcComp
->smoothGain
[i
]) {
820 if (lvl2smthlvl
> drcComp
->attackThr
[i
]) {
822 alpha
= drcComp
->fastAttack
[i
];
826 alpha
= drcComp
->slowAttack
[i
];
831 if (lvl2smthlvl
< -drcComp
->decayThr
[i
]) {
833 alpha
= drcComp
->fastDecay
[i
];
837 alpha
= drcComp
->slowDecay
[i
];
841 /* smooth gain & level */
842 if ((gain
< drcComp
->smoothGain
[i
]) || (drcComp
->holdCnt
[i
] == 0)) { /* hold gain unless we have an attack or hold period is over */
845 /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] + alpha * level; */
846 accu
= fMult(((FIXP_DBL
)MAXVAL_DBL
-alpha
), drcComp
->smoothLevel
[i
]);
847 accu
+= fMult(alpha
,level
);
848 drcComp
->smoothLevel
[i
] = accu
;
850 /* drcComp->smoothGain[i] = (1-alpha) * drcComp->smoothGain[i] + alpha * gain; */
851 accu
= fMult(((FIXP_DBL
)MAXVAL_DBL
-alpha
), drcComp
->smoothGain
[i
]);
852 accu
+= fMult(alpha
,gain
);
853 drcComp
->smoothGain
[i
] = accu
;
857 if (drcComp
->holdCnt
[i
]) {
858 drcComp
->holdCnt
[i
]--;
860 if (gain
< drcComp
->smoothGain
[i
]) {
861 drcComp
->holdCnt
[i
] = drcComp
->holdOff
[i
];
863 } /* profile != DRC_NONE */
867 drcComp
->smoothGain
[0] = FL2FXCONST_DBL(0.f
);
868 drcComp
->smoothGain
[1] = FL2FXCONST_DBL(0.f
);
871 /**************************************************************************
873 **************************************************************************/
875 /* find peak level */
876 peak
[0] = peak
[1] = FL2FXCONST_DBL(0.f
);
877 for (i
= 0; i
< drcComp
->blockLength
; i
++) {
879 const INT_PCM
* pSamples
= &inSamples
[i
*drcComp
->channels
];
880 INT_PCM maxSample
= 0;
882 /* single channels */
883 for (c
= 0; c
< (int)drcComp
->channels
; c
++) {
884 maxSample
= FDKmax(maxSample
, fAbs(pSamples
[c
]));
886 peak
[0] = fixMax(peak
[0], FX_PCM2FX_DBL(maxSample
)>>DOWNMIX_SHIFT
);
889 if (drcComp
->fullChannels
> 2) {
891 tmp
= FL2FXCONST_DBL(0.f
);
893 if (drcComp
->channelIdx
[LS
] >= 0) tmp
-= fMultDiv2(FL2FXCONST_DBL(0.707f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[LS
]])>>(DOWNMIX_SHIFT
-1); /* Ls */
894 if (drcComp
->channelIdx
[LS2
] >= 0) tmp
-= fMultDiv2(FL2FXCONST_DBL(0.707f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[LS2
]])>>(DOWNMIX_SHIFT
-1); /* Ls2 */
895 if (drcComp
->channelIdx
[RS
] >= 0) tmp
-= fMultDiv2(FL2FXCONST_DBL(0.707f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[RS
]])>>(DOWNMIX_SHIFT
-1); /* Rs */
896 if (drcComp
->channelIdx
[RS2
] >= 0) tmp
-= fMultDiv2(FL2FXCONST_DBL(0.707f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[RS2
]])>>(DOWNMIX_SHIFT
-1); /* Rs2 */
897 if ((drcComp
->channelIdx
[LS
] >= 0) && (drcComp
->channelIdx
[LS2
] >= 0)) tmp
= fMult(FL2FXCONST_DBL(0.707f
), tmp
); /* 7.1ch */
898 if (drcComp
->channelIdx
[S
] >= 0) tmp
-= fMultDiv2(FL2FXCONST_DBL(0.707f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[S
]])>>(DOWNMIX_SHIFT
-1); /* S */
899 if (drcComp
->channelIdx
[C
] >= 0) tmp
+= fMultDiv2(FL2FXCONST_DBL(0.707f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[C
]])>>(DOWNMIX_SHIFT
-1); /* C */
900 tmp
+= (FX_PCM2FX_DBL((FIXP_PCM
)pSamples
[drcComp
->channelIdx
[L
]])>>DOWNMIX_SHIFT
); /* L */
902 peak
[0] = fixMax(peak
[0], fixp_abs(tmp
));
905 tmp
= FL2FXCONST_DBL(0.f
);
906 if (drcComp
->channelIdx
[LS
] >= 0) tmp
+= fMultDiv2(FL2FXCONST_DBL(0.707f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[LS
]])>>(DOWNMIX_SHIFT
-1); /* Ls */
907 if (drcComp
->channelIdx
[LS2
] >= 0) tmp
+= fMultDiv2(FL2FXCONST_DBL(0.707f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[LS2
]])>>(DOWNMIX_SHIFT
-1); /* Ls2 */
908 if (drcComp
->channelIdx
[RS
] >= 0) tmp
+= fMultDiv2(FL2FXCONST_DBL(0.707f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[RS
]])>>(DOWNMIX_SHIFT
-1); /* Rs */
909 if (drcComp
->channelIdx
[RS2
] >= 0) tmp
+= fMultDiv2(FL2FXCONST_DBL(0.707f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[RS2
]])>>(DOWNMIX_SHIFT
-1); /* Rs2 */
910 if ((drcComp
->channelIdx
[RS
] >= 0) && (drcComp
->channelIdx
[RS2
] >= 0)) tmp
= fMult(FL2FXCONST_DBL(0.707f
), tmp
); /* 7.1ch */
911 if (drcComp
->channelIdx
[S
] >= 0) tmp
+= fMultDiv2(FL2FXCONST_DBL(0.707f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[S
]])>>(DOWNMIX_SHIFT
-1); /* S */
912 if (drcComp
->channelIdx
[C
] >= 0) tmp
+= fMultDiv2(FL2FXCONST_DBL(0.707f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[C
]])>>(DOWNMIX_SHIFT
-1); /* C */
913 tmp
+= (FX_PCM2FX_DBL((FIXP_PCM
)pSamples
[drcComp
->channelIdx
[R
]])>>DOWNMIX_SHIFT
); /* R */
915 peak
[0] = fixMax(peak
[0], fixp_abs(tmp
));
919 if (drcComp
->fullChannels
> 2) {
921 tmp
= FL2FXCONST_DBL(0.f
);
922 if (drcComp
->channelIdx
[LS
] >= 0) tmp
+= fMultDiv2(slev
, (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[LS
]])>>(DOWNMIX_SHIFT
-1); /* Ls */
923 if (drcComp
->channelIdx
[LS2
] >= 0) tmp
+= fMultDiv2(slev
, (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[LS2
]])>>(DOWNMIX_SHIFT
-1); /* Ls2 */
924 if ((drcComp
->channelIdx
[LS
] >= 0) && (drcComp
->channelIdx
[LS2
] >= 0)) tmp
= fMult(FL2FXCONST_DBL(0.707f
), tmp
); /* 7.1ch */
925 if (drcComp
->channelIdx
[S
] >= 0) tmp
+= fMultDiv2(slev
, fMult(FL2FXCONST_DBL(0.7f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[S
]]))>>(DOWNMIX_SHIFT
-1); /* S */
926 if (drcComp
->channelIdx
[C
] >= 0) tmp
+= fMultDiv2(clev
, (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[C
]])>>(DOWNMIX_SHIFT
-1); /* C */
927 tmp
+= (FX_PCM2FX_DBL((FIXP_PCM
)pSamples
[drcComp
->channelIdx
[L
]])>>DOWNMIX_SHIFT
); /* L */
929 peak
[0] = fixMax(peak
[0], fixp_abs(tmp
));
932 tmp
= FL2FXCONST_DBL(0.f
);
933 if (drcComp
->channelIdx
[RS
] >= 0) tmp
+= fMultDiv2(slev
, (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[RS
]])>>(DOWNMIX_SHIFT
-1); /* Rs */
934 if (drcComp
->channelIdx
[RS2
] >= 0) tmp
+= fMultDiv2(slev
, (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[RS2
]])>>(DOWNMIX_SHIFT
-1); /* Rs2 */
935 if ((drcComp
->channelIdx
[RS
] >= 0) && (drcComp
->channelIdx
[RS2
] >= 0)) tmp
= fMult(FL2FXCONST_DBL(0.707f
), tmp
); /* 7.1ch */
936 if (drcComp
->channelIdx
[S
] >= 0) tmp
+= fMultDiv2(slev
, fMult(FL2FXCONST_DBL(0.7f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[S
]]))>>(DOWNMIX_SHIFT
-1); /* S */
937 if (drcComp
->channelIdx
[C
] >= 0) tmp
+= fMultDiv2(clev
, (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[C
]])>>(DOWNMIX_SHIFT
-1); /* C */
938 tmp
+= (FX_PCM2FX_DBL((FIXP_PCM
)pSamples
[drcComp
->channelIdx
[R
]])>>DOWNMIX_SHIFT
); /* R */
940 peak
[0] = fixMax(peak
[0], fixp_abs(tmp
));
943 peak
[1] = fixMax(peak
[0], peak
[1]);
945 /* Mono Downmix - for comp_val only */
946 if (drcComp
->fullChannels
> 1) {
947 tmp
= FL2FXCONST_DBL(0.f
);
948 if (drcComp
->channelIdx
[LS
] >= 0) tmp
+= fMultDiv2(slev
, (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[LS
]])>>(DOWNMIX_SHIFT
-1); /* Ls */
949 if (drcComp
->channelIdx
[LS2
] >= 0) tmp
+= fMultDiv2(slev
, (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[LS2
]])>>(DOWNMIX_SHIFT
-1); /* Ls2 */
950 if (drcComp
->channelIdx
[RS
] >= 0) tmp
+= fMultDiv2(slev
, (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[RS
]])>>(DOWNMIX_SHIFT
-1); /* Rs */
951 if (drcComp
->channelIdx
[RS2
] >= 0) tmp
+= fMultDiv2(slev
, (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[RS2
]])>>(DOWNMIX_SHIFT
-1); /* Rs2 */
952 if ((drcComp
->channelIdx
[LS
] >= 0) && (drcComp
->channelIdx
[LS2
] >= 0)) tmp
= fMult(FL2FXCONST_DBL(0.707f
), tmp
); /* 7.1ch */
953 /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/ /* 7.1ch */
954 if (drcComp
->channelIdx
[S
] >= 0) tmp
+= fMultDiv2(slev
, fMult(FL2FXCONST_DBL(0.7f
), (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[S
]]))>>(DOWNMIX_SHIFT
-1); /* S */
955 if (drcComp
->channelIdx
[C
] >= 0) tmp
+= fMult(clev
, (FIXP_PCM
)pSamples
[drcComp
->channelIdx
[C
]])>>(DOWNMIX_SHIFT
-1); /* C (2*clev) */
956 tmp
+= (FX_PCM2FX_DBL((FIXP_PCM
)pSamples
[drcComp
->channelIdx
[L
]])>>DOWNMIX_SHIFT
); /* L */
957 tmp
+= (FX_PCM2FX_DBL((FIXP_PCM
)pSamples
[drcComp
->channelIdx
[R
]])>>DOWNMIX_SHIFT
); /* R */
959 peak
[1] = fixMax(peak
[1], fixp_abs(tmp
));
963 for (i
=0; i
<2; i
++) {
964 FIXP_DBL tmp
= drcComp
->prevPeak
[i
];
965 drcComp
->prevPeak
[i
] = peak
[i
];
966 peak
[i
] = fixMax(peak
[i
], tmp
);
969 * Convert to dBFS, apply dialnorm
971 /* descaled peak in ld64 representation */
972 FIXP_DBL ld_peak
= CalcLdData(peak
[i
]) + (FIXP_DBL
)((LONG
)DOWNMIX_SHIFT
<<(DFRACT_BITS
-1-LD_DATA_SHIFT
));
974 /* if (peak < 1e-6) level = 1e-6f; */
975 ld_peak
= FDKmax(ld_peak
, FL2FXCONST_DBL(-0.31143075889569022011284244651463f
));
977 /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
978 * peak[i] = 20 * log(2)/log(10) * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
979 * peak[i] = 10 * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
981 * additional scaling with METADATA_FRACT_BITS:
982 * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64 + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS)
983 * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * 2*0.30102999566398119521373889472449 * ld64(peak[i])
984 * + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i]
986 peak
[i
] = fMult((FIXP_DBL
)(10<<(METADATA_FRACT_BITS
+LD_DATA_SHIFT
)), fMult( FL2FX_DBL(2*0.30102999566398119521373889472449f
), ld_peak
));
987 peak
[i
] += (FL2FX_DBL(0.5f
)>>METADATA_INT_BITS
); /* add a little bit headroom */
988 peak
[i
] += drcComp
->smoothGain
[i
];
991 /* peak -= dialnorm + 31; */ /* this is Dolby style only */
992 peak
[0] -= (FIXP_DBL
)((dialnorm
-drc_TargetRefLevel
)<<(METADATA_FRACT_BITS
-16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */
994 /* peak += 11; */ /* this is Dolby style only */ /* RF mode output is 11dB higher */
995 /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/
996 peak
[1] -= (FIXP_DBL
)((dialnorm
-comp_TargetRefLevel
)<<(METADATA_FRACT_BITS
-16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */
999 drcComp
->limGain
[0] += drcComp
->limDecay
; /* linear limiter release */
1000 drcComp
->limGain
[0] = fixMin(drcComp
->limGain
[0], -peak
[0]);
1002 drcComp
->limGain
[1] += 2*drcComp
->limDecay
; /* linear limiter release */
1003 drcComp
->limGain
[1] = fixMin(drcComp
->limGain
[1], -peak
[1]);
1005 /*************************************************************************/
1007 /* apply limiting, return DRC gains*/
1011 tmp
= drcComp
->smoothGain
[0];
1012 if (drcComp
->limGain
[0] < FL2FXCONST_DBL(0.f
)) {
1013 tmp
+= drcComp
->limGain
[0];
1015 *pDynrng
= (LONG
) scaleValue(tmp
, -(METADATA_FRACT_BITS
-16));
1017 tmp
= drcComp
->smoothGain
[1];
1018 if (drcComp
->limGain
[1] < FL2FXCONST_DBL(0.f
)) {
1019 tmp
+= drcComp
->limGain
[1];
1021 *pCompr
= (LONG
) scaleValue(tmp
, -(METADATA_FRACT_BITS
-16));
1028 DRC_PROFILE
FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp
)
1030 return drcComp
->profile
[0];
1033 DRC_PROFILE
FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp
)
1035 return drcComp
->profile
[1];