1
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5 � Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6 All rights reserved.
7
8 1. INTRODUCTION
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28
29 2. COPYRIGHT LICENSE
30
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52
53 3. NO PATENT LICENSE
54
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61
62 4. DISCLAIMER
63
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72
73 5. CONTACT INFORMATION
74
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
83
84 /********************** Fraunhofer IIS FDK AAC Encoder lib ******************
85
86 Author(s): M. Neusinger
87 Description: Compressor for AAC Metadata Generator
88
89 ******************************************************************************/
90
91
92 #include "metadata_compressor.h"
93 #include "channel_map.h"
94
95
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))
99
100 /*----------------- defines ----------------------*/
101
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. */
105
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))
111
112 /**
113 * Enum for channel assignment.
114 */
115 enum {
116 L = 0,
117 R = 1,
118 C = 2,
119 LFE = 3,
120 LS = 4,
121 RS = 5,
122 S = 6,
123 LS2 = 7,
124 RS2 = 8
125 };
126
127 /*--------------- structure definitions --------------------*/
128
129 /**
130 * Structure holds weighting filter filter states.
131 */
132 struct WEIGHTING_STATES {
133 FIXP_DBL x1;
134 FIXP_DBL x2;
135 FIXP_DBL y1;
136 FIXP_DBL y2;
137 };
138
139 /**
140 * Dynamic Range Control compressor structure.
141 */
142 struct DRC_COMP {
143
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. */
149
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. */
153
154 FIXP_DBL maxBoost[2]; /*!< Maximum boost. */
155 FIXP_DBL maxCut[2]; /*!< Maximum cut. */
156 FIXP_DBL maxEarlyCut[2]; /*!< Maximum early cut. */
157
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. */
163
164 FIXP_DBL attackThr[2]; /*!< Slow/fast attack threshold. */
165 FIXP_DBL decayThr[2]; /*!< Slow/fast release threshold. */
166
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. */
171
172 UCHAR useWeighting; /*!< Use weighting filter. */
173
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). */
177
178 FIXP_DBL smoothLevel[2]; /*!< level smoothing states */
179 FIXP_DBL smoothGain[2]; /*!< gain smoothing states */
180 UINT holdCnt[2]; /*!< hold counter */
181
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)*/
185
186 WEIGHTING_STATES filter[MAX_DRC_CHANNELS]; /*!< array holds weighting filter states */
187
188 };
189
190 /*---------------- constants -----------------------*/
191
192 /**
193 * Profile tables.
194 */
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)
202 };
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)
210 };
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)
218 };
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)
226 };
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)
234 };
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) )
242 };
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) )
250 };
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) )
258 };
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)
266 };
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)
274 };
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)
282 };
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)
290 };
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)
298 };
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)
306 };
307
308 static const INT tabHoldOff[] = { 10, 10, 10, 10, 10, 0 };
309
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)
317 };
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)
325 };
326
327 /**
328 * Weighting filter coefficients (biquad bandpass).
329 */
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 */
332
333
334 /*------------- function definitions ----------------*/
335
336 /**
337 * \brief Calculate scaling factor for denoted processing block.
338 *
339 * \param blockLength Length of processing block.
340 *
341 * \return shiftFactor
342 */
getShiftFactor(const UINT length)343 static UINT getShiftFactor(
344 const UINT length
345 )
346 {
347 UINT ldN;
348 for(ldN=1;(((UINT)1)<<ldN) < length;ldN++);
349
350 return ldN;
351 }
352
353 /**
354 * \brief Sum up fixpoint values with best possible accuracy.
355 *
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.
360 *
361 * \return void
362 */
fixpAdd(const FIXP_DBL value1,const int q1,FIXP_DBL * const pValue2,int * const pQ2)363 static void fixpAdd(
364 const FIXP_DBL value1,
365 const int q1,
366 FIXP_DBL *const pValue2,
367 int *const pQ2
368 )
369 {
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);
373
374 if ( (value1!=FL2FXCONST_DBL(0.f)) && (*pValue2!=FL2FXCONST_DBL(0.f)) ) {
375 resultScale++;
376 }
377
378 *pValue2 = scaleValue(value1, q1-resultScale) + scaleValue(*pValue2, (*pQ2)-resultScale);
379 *pQ2 = (*pValue2!=(FIXP_DBL)0) ? resultScale : DFRACT_BITS-1;
380 }
381
382 /**
383 * \brief Function for converting time constant to filter coefficient.
384 *
385 * \param t Time constant.
386 * \param sampleRate Sampling rate in Hz.
387 * \param blockLength Length of processing block in samples per channel.
388 *
389 * \return result = 1.0 - exp(-1.0/((t) * (f)))
390 */
tc2Coeff(const FIXP_DBL t,const INT sampleRate,const INT blockLength)391 static FIXP_DBL tc2Coeff(
392 const FIXP_DBL t,
393 const INT sampleRate,
394 const INT blockLength
395 )
396 {
397 FIXP_DBL sampleRateFract;
398 FIXP_DBL blockLengthFract;
399 FIXP_DBL f, product;
400 FIXP_DBL exponent, result;
401 INT e_res;
402
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 */
408
409 /* product = t*f */
410 product = fMultNorm(t, f, &e_res);
411 product = scaleValue(product, e_res+METADATA_INT_BITS); /* convert to METADATA_FRACT */
412
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 */
416
417 /* exponent * ld(e) */
418 exponent = fMult(exponent,FIXP_ILOG2_DIV2)<<1; /* e^(x) = 2^(x*ld(e)) */
419
420 /* exp(-1.0/((t) * (f))) */
421 result = f2Pow(-exponent, DFRACT_BITS-1-METADATA_FRACT_BITS, &e_res);
422
423 /* result = 1.0 - exp(-1.0/((t) * (f))) */
424 result = FL2FXCONST_DBL(1.0f) - scaleValue(result, e_res);
425
426 return result;
427 }
428
FDK_DRC_Generator_Open(HDRC_COMP * phDrcComp)429 INT FDK_DRC_Generator_Open(
430 HDRC_COMP *phDrcComp
431 )
432 {
433 INT err = 0;
434 HDRC_COMP hDcComp = NULL;
435
436 if (phDrcComp == NULL) {
437 err = -1;
438 goto bail;
439 }
440
441 /* allocate memory */
442 hDcComp = (HDRC_COMP)FDKcalloc(1, sizeof(DRC_COMP));
443
444 if (hDcComp == NULL) {
445 err = -1;
446 goto bail;
447 }
448
449 FDKmemclear(hDcComp, sizeof(DRC_COMP));
450
451 /* Return drc compressor instance */
452 *phDrcComp = hDcComp;
453 return err;
454 bail:
455 FDK_DRC_Generator_Close(&hDcComp);
456 return err;
457 }
458
FDK_DRC_Generator_Close(HDRC_COMP * phDrcComp)459 INT FDK_DRC_Generator_Close(
460 HDRC_COMP *phDrcComp
461 )
462 {
463 if (phDrcComp == NULL) {
464 return -1;
465 }
466 if (*phDrcComp != NULL) {
467 FDKfree(*phDrcComp);
468 *phDrcComp = NULL;
469 }
470 return 0;
471 }
472
473
FDK_DRC_Generator_Initialize(HDRC_COMP drcComp,const DRC_PROFILE profileLine,const DRC_PROFILE profileRF,const INT blockLength,const UINT sampleRate,const CHANNEL_MODE channelMode,const CHANNEL_ORDER channelOrder,const UCHAR useWeighting)474 INT FDK_DRC_Generator_Initialize(
475 HDRC_COMP drcComp,
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
483 )
484 {
485 int i;
486 CHANNEL_MAPPING channelMapping;
487
488 drcComp->limDecay = FL2FXCONST_DBL( ((0.006f / 256) * blockLength) / METADATA_INT_SCALE );
489
490 /* Save parameters. */
491 drcComp->blockLength = blockLength;
492 drcComp->sampleRate = sampleRate;
493 drcComp->chanConfig = channelMode;
494 drcComp->useWeighting = useWeighting;
495
496 if (FDK_DRC_Generator_setDrcProfile(drcComp, profileLine, profileRF)!=0) { /* expects initialized blockLength and sampleRate */
497 return (-1);
498 }
499
500 /* Set number of channels and channel offsets. */
501 if (FDKaacEnc_InitChannelMapping(channelMode, channelOrder, &channelMapping)!=AAC_ENC_OK) {
502 return (-2);
503 }
504
505 for (i = 0; i < 9; i++) drcComp->channelIdx[i] = -1;
506
507 switch (channelMode) {
508 case MODE_1: /* mono */
509 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
510 break;
511 case MODE_2: /* stereo */
512 drcComp->channelIdx[L] = channelMapping.elInfo[0].ChannelIndex[0];
513 drcComp->channelIdx[R] = channelMapping.elInfo[0].ChannelIndex[1];
514 break;
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];
519 break;
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];
525 break;
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];
532 break;
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];
540 break;
541 case MODE_1_2_2_2_1: /* 7.1 ch */
542 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
543 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
544 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
545 drcComp->channelIdx[LFE] = channelMapping.elInfo[4].ChannelIndex[0];
546 drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0];
547 drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1];
548 drcComp->channelIdx[LS2] = channelMapping.elInfo[3].ChannelIndex[0];
549 drcComp->channelIdx[RS2] = channelMapping.elInfo[3].ChannelIndex[1];
550 break;
551 case MODE_1_1:
552 case MODE_1_1_1_1:
553 case MODE_1_1_1_1_1_1:
554 case MODE_1_1_1_1_1_1_1_1:
555 case MODE_1_1_1_1_1_1_1_1_1_1_1_1:
556 case MODE_2_2:
557 case MODE_2_2_2:
558 case MODE_2_2_2_2:
559 case MODE_2_2_2_2_2_2:
560 default:
561 return (-1);
562 }
563
564 drcComp->fullChannels = channelMapping.nChannelsEff;
565 drcComp->channels = channelMapping.nChannels;
566
567 /* Init states. */
568 drcComp->smoothLevel[0] = drcComp->smoothLevel[1] = (FIXP_DBL)(-135<<METADATA_FRACT_BITS);
569
570 FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain));
571 FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt));
572 FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain));
573 FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak));
574 FDKmemclear(drcComp->filter, sizeof(drcComp->filter));
575
576 return (0);
577 }
578
579
FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp,const DRC_PROFILE profileLine,const DRC_PROFILE profileRF)580 INT FDK_DRC_Generator_setDrcProfile(
581 HDRC_COMP drcComp,
582 const DRC_PROFILE profileLine,
583 const DRC_PROFILE profileRF
584 )
585 {
586 int profileIdx, i;
587
588 drcComp->profile[0] = profileLine;
589 drcComp->profile[1] = profileRF;
590
591 for (i = 0; i < 2; i++) {
592 /* get profile index */
593 switch (drcComp->profile[i]) {
594 case DRC_NONE:
595 case DRC_FILMSTANDARD: profileIdx = 0; break;
596 case DRC_FILMLIGHT: profileIdx = 1; break;
597 case DRC_MUSICSTANDARD: profileIdx = 2; break;
598 case DRC_MUSICLIGHT: profileIdx = 3; break;
599 case DRC_SPEECH: profileIdx = 4; break;
600 case DRC_DELAY_TEST: profileIdx = 5; break;
601 default: return (-1);
602 }
603
604 /* get parameters for selected profile */
605 if (profileIdx >= 0) {
606 drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx];
607 drcComp->boostThr[i] = tabBoostThr[profileIdx];
608 drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx];
609 drcComp->cutThr[i] = tabCutThr[profileIdx];
610 drcComp->maxCutThr[i] = tabMaxCutThr[profileIdx];
611
612 drcComp->boostFac[i] = tabBoostRatio[profileIdx];
613 drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx];
614 drcComp->cutFac[i] = tabCutRatio[profileIdx];
615
616 drcComp->maxBoost[i] = tabMaxBoost[profileIdx];
617 drcComp->maxCut[i] = tabMaxCut[profileIdx];
618 drcComp->maxEarlyCut[i] = - fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); /* no scaling after mult needed, earlyCutFac is in FIXP_DBL */
619
620 drcComp->fastAttack[i] = tc2Coeff(tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
621 drcComp->fastDecay[i] = tc2Coeff(tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
622 drcComp->slowAttack[i] = tc2Coeff(tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
623 drcComp->slowDecay[i] = tc2Coeff(tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
624 drcComp->holdOff[i] = tabHoldOff[profileIdx] * 256 / drcComp->blockLength;
625
626 drcComp->attackThr[i] = tabAttackThr[profileIdx];
627 drcComp->decayThr[i] = tabDecayThr[profileIdx];
628 }
629
630 drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
631 }
632 return (0);
633 }
634
635
FDK_DRC_Generator_Calc(HDRC_COMP drcComp,const INT_PCM * const inSamples,const INT dialnorm,const INT drc_TargetRefLevel,const INT comp_TargetRefLevel,FIXP_DBL clev,FIXP_DBL slev,INT * const pDynrng,INT * const pCompr)636 INT FDK_DRC_Generator_Calc(
637 HDRC_COMP drcComp,
638 const INT_PCM * const inSamples,
639 const INT dialnorm,
640 const INT drc_TargetRefLevel,
641 const INT comp_TargetRefLevel,
642 FIXP_DBL clev,
643 FIXP_DBL slev,
644 INT * const pDynrng,
645 INT * const pCompr
646 )
647 {
648 int i, c;
649 FIXP_DBL peak[2];
650
651
652 /**************************************************************************
653 * compressor
654 **************************************************************************/
655 if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) {
656 /* Calc loudness level */
657 FIXP_DBL level_b = FL2FXCONST_DBL(0.f);
658 int level_e = DFRACT_BITS-1;
659
660 /* Increase energy time resolution with shorter processing blocks. 32 is an empiric value. */
661 const int granuleLength = fixMin(32, drcComp->blockLength);
662
663 if (drcComp->useWeighting) {
664 FIXP_DBL x1, x2, y, y1, y2;
665 /* sum of filter coefficients about 2.5 -> squared value is 6.25
666 WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce granuleShift by 1.
667 */
668 const int granuleShift = getShiftFactor(granuleLength)-1;
669
670 for (c = 0; c < (int)drcComp->channels; c++) {
671 const INT_PCM* pSamples = &inSamples[c];
672
673 if (c == drcComp->channelIdx[LFE]) {
674 continue; /* skip LFE */
675 }
676
677 /* get filter states */
678 x1 = drcComp->filter[c].x1;
679 x2 = drcComp->filter[c].x2;
680 y1 = drcComp->filter[c].y1;
681 y2 = drcComp->filter[c].y2;
682
683 i = 0;
684
685 do {
686
687 int offset = i;
688 FIXP_DBL accu = FL2FXCONST_DBL(0.f);
689
690 for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) {
691 /* apply weighting filter */
692 FIXP_DBL x = FX_PCM2FX_DBL((FIXP_PCM)pSamples[i*drcComp->channels]) >> WEIGHTING_FILTER_SHIFT;
693
694 /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */
695 y = fMult(b0,x-x2) - fMult(a1,y1) - fMult(a2,y2);
696
697 x2 = x1;
698 x1 = x;
699 y2 = y1;
700 y1 = y;
701
702 accu += fPow2Div2(y)>>(granuleShift-1); /* partial energy */
703 } /* i */
704
705 fixpAdd(accu, granuleShift+2*WEIGHTING_FILTER_SHIFT, &level_b, &level_e); /* sup up partial energies */
706
707 } while ( i < drcComp->blockLength );
708
709
710 /* save filter states */
711 drcComp->filter[c].x1 = x1;
712 drcComp->filter[c].x2 = x2;
713 drcComp->filter[c].y1 = y1;
714 drcComp->filter[c].y2 = y2;
715 } /* c */
716 } /* weighting */
717 else {
718 const int granuleShift = getShiftFactor(granuleLength);
719
720 for (c = 0; c < (int)drcComp->channels; c++) {
721 const INT_PCM* pSamples = &inSamples[c];
722
723 if ((int)c == drcComp->channelIdx[LFE]) {
724 continue; /* skip LFE */
725 }
726
727 i = 0;
728
729 do {
730 int offset = i;
731 FIXP_DBL accu = FL2FXCONST_DBL(0.f);
732
733 for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) {
734 /* partial energy */
735 accu += fPow2Div2((FIXP_PCM)pSamples[i*drcComp->channels])>>(granuleShift-1);
736 } /* i */
737
738 fixpAdd(accu, granuleShift, &level_b, &level_e); /* sup up partial energies */
739
740 } while ( i < drcComp->blockLength );
741 }
742 } /* weighting */
743
744 /*
745 * Convert to dBFS, apply dialnorm
746 */
747 /* level scaling */
748
749 /* descaled level in ld64 representation */
750 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)));
751
752 /* if (level < 1e-10) level = 1e-10f; */
753 ldLevel = FDKmax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f));
754
755 /* level = 10 * log(level)/log(10) + 3;
756 * = 10*log(2)/log(10) * ld(level) + 3;
757 * = 10 * 0.30102999566398119521373889472449 * ld(level) + 3
758 * = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3)
759 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64
760 *
761 * additional scaling with METADATA_FRACT_BITS:
762 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64 * 2^(METADATA_FRACT_BITS)
763 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT)
764 * = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * ( 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 )
765 * */
766 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) );
767
768 /* level -= dialnorm + 31 */ /* this is fixed to Dolby-ReferenceLevel as compressor profiles are defined relative to this */
769 level -= ((FIXP_DBL)(dialnorm<<(METADATA_FRACT_BITS-16)) + (FIXP_DBL)(31<<METADATA_FRACT_BITS));
770
771 for (i = 0; i < 2; i++) {
772 if (drcComp->profile[i] == DRC_NONE) {
773 /* no compression */
774 drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
775 }
776 else {
777 FIXP_DBL gain, alpha, lvl2smthlvl;
778
779 /* calc static gain */
780 if (level <= drcComp->maxBoostThr[i]) {
781 /* max boost */
782 gain = drcComp->maxBoost[i];
783 }
784 else if (level < drcComp->boostThr[i]) {
785 /* boost range */
786 gain = fMult((level - drcComp->boostThr[i]),drcComp->boostFac[i]);
787 }
788 else if (level <= drcComp->earlyCutThr[i]) {
789 /* null band */
790 gain = FL2FXCONST_DBL(0.f);
791 }
792 else if (level <= drcComp->cutThr[i]) {
793 /* early cut range */
794 gain = fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]);
795 }
796 else if (level < drcComp->maxCutThr[i]) {
797 /* cut range */
798 gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) - drcComp->maxEarlyCut[i];
799 }
800 else {
801 /* max cut */
802 gain = -drcComp->maxCut[i];
803 }
804
805 /* choose time constant */
806 lvl2smthlvl = level - drcComp->smoothLevel[i];
807 if (gain < drcComp->smoothGain[i]) {
808 /* attack */
809 if (lvl2smthlvl > drcComp->attackThr[i]) {
810 /* fast attack */
811 alpha = drcComp->fastAttack[i];
812 }
813 else {
814 /* slow attack */
815 alpha = drcComp->slowAttack[i];
816 }
817 }
818 else {
819 /* release */
820 if (lvl2smthlvl < -drcComp->decayThr[i]) {
821 /* fast release */
822 alpha = drcComp->fastDecay[i];
823 }
824 else {
825 /* slow release */
826 alpha = drcComp->slowDecay[i];
827 }
828 }
829
830 /* smooth gain & level */
831 if ((gain < drcComp->smoothGain[i]) || (drcComp->holdCnt[i] == 0)) { /* hold gain unless we have an attack or hold period is over */
832 FIXP_DBL accu;
833
834 /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] + alpha * level; */
835 accu = fMult((FL2FXCONST_DBL(1.f)-alpha), drcComp->smoothLevel[i]);
836 accu += fMult(alpha,level);
837 drcComp->smoothLevel[i] = accu;
838
839 /* drcComp->smoothGain[i] = (1-alpha) * drcComp->smoothGain[i] + alpha * gain; */
840 accu = fMult((FL2FXCONST_DBL(1.f)-alpha), drcComp->smoothGain[i]);
841 accu += fMult(alpha,gain);
842 drcComp->smoothGain[i] = accu;
843 }
844
845 /* hold counter */
846 if (drcComp->holdCnt[i]) {
847 drcComp->holdCnt[i]--;
848 }
849 if (gain < drcComp->smoothGain[i]) {
850 drcComp->holdCnt[i] = drcComp->holdOff[i];
851 }
852 } /* profile != DRC_NONE */
853 } /* for i=1..2 */
854 } else {
855 /* no compression */
856 drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f);
857 drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f);
858 }
859
860 /**************************************************************************
861 * limiter
862 **************************************************************************/
863
864 /* find peak level */
865 peak[0] = peak[1] = FL2FXCONST_DBL(0.f);
866 for (i = 0; i < drcComp->blockLength; i++) {
867 FIXP_DBL tmp;
868 const INT_PCM* pSamples = &inSamples[i*drcComp->channels];
869 INT_PCM maxSample = 0;
870
871 /* single channels */
872 for (c = 0; c < (int)drcComp->channels; c++) {
873 maxSample = FDKmax(maxSample, fAbs(pSamples[c]));
874 }
875 peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample)>>DOWNMIX_SHIFT);
876
877 /* Lt/Rt downmix */
878 if (drcComp->fullChannels > 2) {
879 /* Lt */
880 tmp = FL2FXCONST_DBL(0.f);
881
882 if (drcComp->channelIdx[LS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */
883 if (drcComp->channelIdx[LS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */
884 if (drcComp->channelIdx[RS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */
885 if (drcComp->channelIdx[RS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */
886 if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
887 if (drcComp->channelIdx[S] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1); /* S */
888 if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */
889 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */
890
891 peak[0] = fixMax(peak[0], fixp_abs(tmp));
892
893 /* Rt */
894 tmp = FL2FXCONST_DBL(0.f);
895 if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */
896 if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */
897 if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */
898 if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */
899 if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
900 if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1); /* S */
901 if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */
902 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT); /* R */
903
904 peak[0] = fixMax(peak[0], fixp_abs(tmp));
905 }
906
907 /* Lo/Ro downmix */
908 if (drcComp->fullChannels > 2) {
909 /* Lo */
910 tmp = FL2FXCONST_DBL(0.f);
911 if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */
912 if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */
913 if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
914 if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */
915 if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */
916 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */
917
918 peak[0] = fixMax(peak[0], fixp_abs(tmp));
919
920 /* Ro */
921 tmp = FL2FXCONST_DBL(0.f);
922 if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */
923 if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */
924 if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 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[R]])>>DOWNMIX_SHIFT); /* R */
928
929 peak[0] = fixMax(peak[0], fixp_abs(tmp));
930 }
931
932 peak[1] = fixMax(peak[0], peak[1]);
933
934 /* Mono Downmix - for comp_val only */
935 if (drcComp->fullChannels > 1) {
936 tmp = FL2FXCONST_DBL(0.f);
937 if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */
938 if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */
939 if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */
940 if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */
941 if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
942 /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/ /* 7.1ch */
943 if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */
944 if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */
945 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */
946 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT); /* R */
947
948 peak[1] = fixMax(peak[1], fixp_abs(tmp));
949 }
950 }
951
952 for (i=0; i<2; i++) {
953 FIXP_DBL tmp = drcComp->prevPeak[i];
954 drcComp->prevPeak[i] = peak[i];
955 peak[i] = fixMax(peak[i], tmp);
956
957 /*
958 * Convert to dBFS, apply dialnorm
959 */
960 /* descaled peak in ld64 representation */
961 FIXP_DBL ld_peak = CalcLdData(peak[i]) + (FIXP_DBL)((LONG)DOWNMIX_SHIFT<<(DFRACT_BITS-1-LD_DATA_SHIFT));
962
963 /* if (peak < 1e-6) level = 1e-6f; */
964 ld_peak = FDKmax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f));
965
966 /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
967 * peak[i] = 20 * log(2)/log(10) * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
968 * peak[i] = 10 * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
969 *
970 * additional scaling with METADATA_FRACT_BITS:
971 * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64 + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS)
972 * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * 2*0.30102999566398119521373889472449 * ld64(peak[i])
973 * + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i]
974 */
975 peak[i] = fMult((FIXP_DBL)(10<<(METADATA_FRACT_BITS+LD_DATA_SHIFT)), fMult( FL2FX_DBL(2*0.30102999566398119521373889472449f), ld_peak));
976 peak[i] += (FL2FX_DBL(0.2f)>>METADATA_INT_BITS); /* add a little bit headroom */
977 peak[i] += drcComp->smoothGain[i];
978 }
979
980 /* peak -= dialnorm + 31; */ /* this is Dolby style only */
981 peak[0] -= (FIXP_DBL)((dialnorm-drc_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */
982
983 /* peak += 11; */ /* this is Dolby style only */ /* RF mode output is 11dB higher */
984 /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/
985 peak[1] -= (FIXP_DBL)((dialnorm-comp_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */
986
987 /* limiter gain */
988 drcComp->limGain[0] += drcComp->limDecay; /* linear limiter release */
989 drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]);
990
991 drcComp->limGain[1] += 2*drcComp->limDecay; /* linear limiter release */
992 drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]);
993
994 /*************************************************************************/
995
996 /* apply limiting, return DRC gains*/
997 {
998 FIXP_DBL tmp;
999
1000 tmp = drcComp->smoothGain[0];
1001 if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) {
1002 tmp += drcComp->limGain[0];
1003 }
1004 *pDynrng = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16));
1005
1006 tmp = drcComp->smoothGain[1];
1007 if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) {
1008 tmp += drcComp->limGain[1];
1009 }
1010 *pCompr = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16));
1011 }
1012
1013 return 0;
1014 }
1015
1016
FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp)1017 DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp)
1018 {
1019 return drcComp->profile[0];
1020 }
1021
FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp)1022 DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp)
1023 {
1024 return drcComp->profile[1];
1025 }
1026
1027
1028