Imported Debian version 0.1.3.1
[deb_fdk-aac.git] / libAACenc / src / metadata_compressor.cpp
1
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5 © Copyright 1995 - 2013 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 */
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 */
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 */
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 = (FIXP_DBL)MAXVAL_DBL - scaleValue(result, e_res);
425
426 return result;
427 }
428
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
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
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 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 */
551 break;
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 */
561 break;
562 case MODE_1_1:
563 case MODE_1_1_1_1:
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:
567 case MODE_2_2:
568 case MODE_2_2_2:
569 case MODE_2_2_2_2:
570 case MODE_2_2_2_2_2_2:
571 default:
572 return (-1);
573 }
574
575 drcComp->fullChannels = channelMapping.nChannelsEff;
576 drcComp->channels = channelMapping.nChannels;
577
578 /* Init states. */
579 drcComp->smoothLevel[0] = drcComp->smoothLevel[1] = (FIXP_DBL)(-135<<METADATA_FRACT_BITS);
580
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));
586
587 return (0);
588 }
589
590
591 INT FDK_DRC_Generator_setDrcProfile(
592 HDRC_COMP drcComp,
593 const DRC_PROFILE profileLine,
594 const DRC_PROFILE profileRF
595 )
596 {
597 int profileIdx, i;
598
599 drcComp->profile[0] = profileLine;
600 drcComp->profile[1] = profileRF;
601
602 for (i = 0; i < 2; i++) {
603 /* get profile index */
604 switch (drcComp->profile[i]) {
605 case DRC_NONE:
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);
613 }
614
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];
622
623 drcComp->boostFac[i] = tabBoostRatio[profileIdx];
624 drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx];
625 drcComp->cutFac[i] = tabCutRatio[profileIdx];
626
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 */
630
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;
636
637 drcComp->attackThr[i] = tabAttackThr[profileIdx];
638 drcComp->decayThr[i] = tabDecayThr[profileIdx];
639 }
640
641 drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
642 }
643 return (0);
644 }
645
646
647 INT FDK_DRC_Generator_Calc(
648 HDRC_COMP drcComp,
649 const INT_PCM * const inSamples,
650 const INT dialnorm,
651 const INT drc_TargetRefLevel,
652 const INT comp_TargetRefLevel,
653 FIXP_DBL clev,
654 FIXP_DBL slev,
655 INT * const pDynrng,
656 INT * const pCompr
657 )
658 {
659 int i, c;
660 FIXP_DBL peak[2];
661
662
663 /**************************************************************************
664 * compressor
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;
670
671 /* Increase energy time resolution with shorter processing blocks. 32 is an empiric value. */
672 const int granuleLength = fixMin(32, drcComp->blockLength);
673
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.
678 */
679 const int granuleShift = getShiftFactor(granuleLength)-1;
680
681 for (c = 0; c < (int)drcComp->channels; c++) {
682 const INT_PCM* pSamples = &inSamples[c];
683
684 if (c == drcComp->channelIdx[LFE]) {
685 continue; /* skip LFE */
686 }
687
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;
693
694 i = 0;
695
696 do {
697
698 int offset = i;
699 FIXP_DBL accu = FL2FXCONST_DBL(0.f);
700
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;
704
705 /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */
706 y = fMult(b0,x-x2) - fMult(a1,y1) - fMult(a2,y2);
707
708 x2 = x1;
709 x1 = x;
710 y2 = y1;
711 y1 = y;
712
713 accu += fPow2Div2(y)>>(granuleShift-1); /* partial energy */
714 } /* i */
715
716 fixpAdd(accu, granuleShift+2*WEIGHTING_FILTER_SHIFT, &level_b, &level_e); /* sup up partial energies */
717
718 } while ( i < drcComp->blockLength );
719
720
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;
726 } /* c */
727 } /* weighting */
728 else {
729 const int granuleShift = getShiftFactor(granuleLength);
730
731 for (c = 0; c < (int)drcComp->channels; c++) {
732 const INT_PCM* pSamples = &inSamples[c];
733
734 if ((int)c == drcComp->channelIdx[LFE]) {
735 continue; /* skip LFE */
736 }
737
738 i = 0;
739
740 do {
741 int offset = i;
742 FIXP_DBL accu = FL2FXCONST_DBL(0.f);
743
744 for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) {
745 /* partial energy */
746 accu += fPow2Div2((FIXP_PCM)pSamples[i*drcComp->channels])>>(granuleShift-1);
747 } /* i */
748
749 fixpAdd(accu, granuleShift, &level_b, &level_e); /* sup up partial energies */
750
751 } while ( i < drcComp->blockLength );
752 }
753 } /* weighting */
754
755 /*
756 * Convert to dBFS, apply dialnorm
757 */
758 /* level scaling */
759
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)));
762
763 /* if (level < 1e-10) level = 1e-10f; */
764 ldLevel = FDKmax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f));
765
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
771 *
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 )
776 * */
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) );
778
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));
781
782 for (i = 0; i < 2; i++) {
783 if (drcComp->profile[i] == DRC_NONE) {
784 /* no compression */
785 drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
786 }
787 else {
788 FIXP_DBL gain, alpha, lvl2smthlvl;
789
790 /* calc static gain */
791 if (level <= drcComp->maxBoostThr[i]) {
792 /* max boost */
793 gain = drcComp->maxBoost[i];
794 }
795 else if (level < drcComp->boostThr[i]) {
796 /* boost range */
797 gain = fMult((level - drcComp->boostThr[i]),drcComp->boostFac[i]);
798 }
799 else if (level <= drcComp->earlyCutThr[i]) {
800 /* null band */
801 gain = FL2FXCONST_DBL(0.f);
802 }
803 else if (level <= drcComp->cutThr[i]) {
804 /* early cut range */
805 gain = fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]);
806 }
807 else if (level < drcComp->maxCutThr[i]) {
808 /* cut range */
809 gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) - drcComp->maxEarlyCut[i];
810 }
811 else {
812 /* max cut */
813 gain = -drcComp->maxCut[i];
814 }
815
816 /* choose time constant */
817 lvl2smthlvl = level - drcComp->smoothLevel[i];
818 if (gain < drcComp->smoothGain[i]) {
819 /* attack */
820 if (lvl2smthlvl > drcComp->attackThr[i]) {
821 /* fast attack */
822 alpha = drcComp->fastAttack[i];
823 }
824 else {
825 /* slow attack */
826 alpha = drcComp->slowAttack[i];
827 }
828 }
829 else {
830 /* release */
831 if (lvl2smthlvl < -drcComp->decayThr[i]) {
832 /* fast release */
833 alpha = drcComp->fastDecay[i];
834 }
835 else {
836 /* slow release */
837 alpha = drcComp->slowDecay[i];
838 }
839 }
840
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 */
843 FIXP_DBL accu;
844
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;
849
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;
854 }
855
856 /* hold counter */
857 if (drcComp->holdCnt[i]) {
858 drcComp->holdCnt[i]--;
859 }
860 if (gain < drcComp->smoothGain[i]) {
861 drcComp->holdCnt[i] = drcComp->holdOff[i];
862 }
863 } /* profile != DRC_NONE */
864 } /* for i=1..2 */
865 } else {
866 /* no compression */
867 drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f);
868 drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f);
869 }
870
871 /**************************************************************************
872 * limiter
873 **************************************************************************/
874
875 /* find peak level */
876 peak[0] = peak[1] = FL2FXCONST_DBL(0.f);
877 for (i = 0; i < drcComp->blockLength; i++) {
878 FIXP_DBL tmp;
879 const INT_PCM* pSamples = &inSamples[i*drcComp->channels];
880 INT_PCM maxSample = 0;
881
882 /* single channels */
883 for (c = 0; c < (int)drcComp->channels; c++) {
884 maxSample = FDKmax(maxSample, fAbs(pSamples[c]));
885 }
886 peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample)>>DOWNMIX_SHIFT);
887
888 /* Lt/Rt downmix */
889 if (drcComp->fullChannels > 2) {
890 /* Lt */
891 tmp = FL2FXCONST_DBL(0.f);
892
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 */
901
902 peak[0] = fixMax(peak[0], fixp_abs(tmp));
903
904 /* Rt */
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 */
914
915 peak[0] = fixMax(peak[0], fixp_abs(tmp));
916 }
917
918 /* Lo/Ro downmix */
919 if (drcComp->fullChannels > 2) {
920 /* Lo */
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 */
928
929 peak[0] = fixMax(peak[0], fixp_abs(tmp));
930
931 /* Ro */
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 */
939
940 peak[0] = fixMax(peak[0], fixp_abs(tmp));
941 }
942
943 peak[1] = fixMax(peak[0], peak[1]);
944
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 */
958
959 peak[1] = fixMax(peak[1], fixp_abs(tmp));
960 }
961 }
962
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);
967
968 /*
969 * Convert to dBFS, apply dialnorm
970 */
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));
973
974 /* if (peak < 1e-6) level = 1e-6f; */
975 ld_peak = FDKmax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f));
976
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)
980 *
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]
985 */
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];
989 }
990
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 */
993
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 */
997
998 /* limiter gain */
999 drcComp->limGain[0] += drcComp->limDecay; /* linear limiter release */
1000 drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]);
1001
1002 drcComp->limGain[1] += 2*drcComp->limDecay; /* linear limiter release */
1003 drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]);
1004
1005 /*************************************************************************/
1006
1007 /* apply limiting, return DRC gains*/
1008 {
1009 FIXP_DBL tmp;
1010
1011 tmp = drcComp->smoothGain[0];
1012 if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) {
1013 tmp += drcComp->limGain[0];
1014 }
1015 *pDynrng = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16));
1016
1017 tmp = drcComp->smoothGain[1];
1018 if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) {
1019 tmp += drcComp->limGain[1];
1020 }
1021 *pCompr = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16));
1022 }
1023
1024 return 0;
1025 }
1026
1027
1028 DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp)
1029 {
1030 return drcComp->profile[0];
1031 }
1032
1033 DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp)
1034 {
1035 return drcComp->profile[1];
1036 }
1037
1038