1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6
7 1. INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33
34 2. COPYRIGHT LICENSE
35
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60
61 3. NO PATENT LICENSE
62
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70
71 4. DISCLAIMER
72
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83
84 5. CONTACT INFORMATION
85
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94
95 /**************************** AAC encoder library ******************************
96
97 Author(s): M. Neusinger
98
99 Description: Compressor for AAC Metadata Generator
100
101 *******************************************************************************/
102
103 #include "metadata_compressor.h"
104 #include "channel_map.h"
105
106 #define LOG2 0.69314718056f /* natural logarithm of 2 */
107 #define ILOG2 1.442695041f /* 1/LOG2 */
108 #define FIXP_ILOG2_DIV2 (FL2FXCONST_DBL(ILOG2 / 2))
109
110 /*----------------- defines ----------------------*/
111
112 #define MAX_DRC_CHANNELS (8) /*!< Max number of audio input channels. */
113 #define DOWNMIX_SHIFT (3) /*!< Max 8 channel. */
114 #define WEIGHTING_FILTER_SHIFT (2) /*!< Scaling used in weighting filter. */
115
116 #define METADATA_INT_BITS 10
117 #define METADATA_LINT_BITS 20
118 #define METADATA_INT_SCALE (INT64(1) << (METADATA_INT_BITS))
119 #define METADATA_FRACT_BITS (DFRACT_BITS - 1 - METADATA_INT_BITS)
120 #define METADATA_FRACT_SCALE (INT64(1) << (METADATA_FRACT_BITS))
121
122 /**
123 * Enum for channel assignment.
124 */
125 enum { L = 0, R = 1, C = 2, LFE = 3, LS = 4, RS = 5, S = 6, LS2 = 7, RS2 = 8 };
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 FIXP_DBL maxBoostThr[2]; /*!< Max boost threshold. */
144 FIXP_DBL boostThr[2]; /*!< Boost threshold. */
145 FIXP_DBL earlyCutThr[2]; /*!< Early cut threshold. */
146 FIXP_DBL cutThr[2]; /*!< Cut threshold. */
147 FIXP_DBL maxCutThr[2]; /*!< Max cut threshold. */
148
149 FIXP_DBL boostFac[2]; /*!< Precalculated factor for boost compression. */
150 FIXP_DBL
151 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,
177 Ls, Rs, S, Ls2, Rs2). */
178
179 FIXP_DBL smoothLevel[2]; /*!< level smoothing states */
180 FIXP_DBL smoothGain[2]; /*!< gain smoothing states */
181 UINT holdCnt[2]; /*!< hold counter */
182
183 FIXP_DBL limGain[2]; /*!< limiter gain */
184 FIXP_DBL limDecay; /*!< limiter decay (linear) */
185 FIXP_DBL prevPeak[2]; /*!< max peak of previous block (stereo/mono)*/
186
187 WEIGHTING_STATES
188 filter[MAX_DRC_CHANNELS]; /*!< array holds weighting filter states */
189 };
190
191 /*---------------- constants -----------------------*/
192
193 /**
194 * Profile tables.
195 */
196 static const FIXP_DBL tabMaxBoostThr[] = {
197 (FIXP_DBL)(-(43 << METADATA_FRACT_BITS)),
198 (FIXP_DBL)(-(53 << METADATA_FRACT_BITS)),
199 (FIXP_DBL)(-(55 << METADATA_FRACT_BITS)),
200 (FIXP_DBL)(-(65 << METADATA_FRACT_BITS)),
201 (FIXP_DBL)(-(50 << METADATA_FRACT_BITS)),
202 (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))};
210 static const FIXP_DBL tabEarlyCutThr[] = {
211 (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)),
212 (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)),
213 (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)),
214 (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)),
215 (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)),
216 (FIXP_DBL)(-(20 << METADATA_FRACT_BITS))};
217 static const FIXP_DBL tabCutThr[] = {(FIXP_DBL)(-(16 << METADATA_FRACT_BITS)),
218 (FIXP_DBL)(-(11 << METADATA_FRACT_BITS)),
219 (FIXP_DBL)(-(16 << METADATA_FRACT_BITS)),
220 (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)),
221 (FIXP_DBL)(-(16 << METADATA_FRACT_BITS)),
222 (FIXP_DBL)(-(10 << METADATA_FRACT_BITS))};
223 static const FIXP_DBL tabMaxCutThr[] = {
224 (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(9 << METADATA_FRACT_BITS),
225 (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(9 << METADATA_FRACT_BITS),
226 (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(4 << METADATA_FRACT_BITS)};
227 static const FIXP_DBL tabBoostRatio[] = {
228 FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
229 FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
230 FL2FXCONST_DBL(((1.f / 5.f) - 1.f)), FL2FXCONST_DBL(((1.f / 5.f) - 1.f))};
231 static const FIXP_DBL tabEarlyCutRatio[] = {
232 FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
233 FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 1.f) - 1.f)),
234 FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f))};
235 static const FIXP_DBL tabCutRatio[] = {
236 FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 20.f) - 1.f)),
237 FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
238 FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 20.f) - 1.f))};
239 static const FIXP_DBL tabMaxBoost[] = {(FIXP_DBL)(6 << METADATA_FRACT_BITS),
240 (FIXP_DBL)(6 << METADATA_FRACT_BITS),
241 (FIXP_DBL)(12 << METADATA_FRACT_BITS),
242 (FIXP_DBL)(12 << METADATA_FRACT_BITS),
243 (FIXP_DBL)(15 << METADATA_FRACT_BITS),
244 (FIXP_DBL)(15 << METADATA_FRACT_BITS)};
245 static const FIXP_DBL tabMaxCut[] = {(FIXP_DBL)(24 << METADATA_FRACT_BITS),
246 (FIXP_DBL)(24 << METADATA_FRACT_BITS),
247 (FIXP_DBL)(24 << METADATA_FRACT_BITS),
248 (FIXP_DBL)(15 << METADATA_FRACT_BITS),
249 (FIXP_DBL)(24 << METADATA_FRACT_BITS),
250 (FIXP_DBL)(24 << METADATA_FRACT_BITS)};
251 static const FIXP_DBL tabFastAttack[] = {
252 FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
253 FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
254 FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
255 FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
256 FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
257 FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
258 static const FIXP_DBL tabFastDecay[] = {
259 FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
260 FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
261 FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
262 FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
263 FL2FXCONST_DBL((200.f / 1000.f) / METADATA_INT_SCALE),
264 FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
265 static const FIXP_DBL tabSlowAttack[] = {
266 FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
267 FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
268 FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
269 FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
270 FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
271 FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
272 static const FIXP_DBL tabSlowDecay[] = {
273 FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE),
274 FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE),
275 FL2FXCONST_DBL((10000.f / 1000.f) / METADATA_INT_SCALE),
276 FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE),
277 FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
278 FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
279
280 static const INT tabHoldOff[] = {10, 10, 10, 10, 10, 0};
281
282 static const FIXP_DBL tabAttackThr[] = {(FIXP_DBL)(15 << METADATA_FRACT_BITS),
283 (FIXP_DBL)(15 << METADATA_FRACT_BITS),
284 (FIXP_DBL)(15 << METADATA_FRACT_BITS),
285 (FIXP_DBL)(15 << METADATA_FRACT_BITS),
286 (FIXP_DBL)(10 << METADATA_FRACT_BITS),
287 (FIXP_DBL)(0 << METADATA_FRACT_BITS)};
288 static const FIXP_DBL tabDecayThr[] = {(FIXP_DBL)(20 << METADATA_FRACT_BITS),
289 (FIXP_DBL)(20 << METADATA_FRACT_BITS),
290 (FIXP_DBL)(20 << METADATA_FRACT_BITS),
291 (FIXP_DBL)(20 << METADATA_FRACT_BITS),
292 (FIXP_DBL)(10 << METADATA_FRACT_BITS),
293 (FIXP_DBL)(0 << METADATA_FRACT_BITS)};
294
295 /**
296 * Weighting filter coefficients (biquad bandpass).
297 */
298 static const FIXP_DBL b0 = FL2FXCONST_DBL(0.53050662f); /* b1 = 0, b2 = -b0 */
299 static const FIXP_DBL a1 = FL2FXCONST_DBL(-0.95237983f),
300 a2 = FL2FXCONST_DBL(-0.02248836f); /* a0 = 1 */
301
302 /*------------- function definitions ----------------*/
303
304 /**
305 * \brief Calculate scaling factor for denoted processing block.
306 *
307 * \param blockLength Length of processing block.
308 *
309 * \return shiftFactor
310 */
getShiftFactor(const UINT length)311 static UINT getShiftFactor(const UINT length) {
312 UINT ldN;
313 for (ldN = 1; (((UINT)1) << ldN) < length; ldN++)
314 ;
315
316 return ldN;
317 }
318
319 /**
320 * \brief Sum up fixpoint values with best possible accuracy.
321 *
322 * \param value1 First input value.
323 * \param q1 Scaling factor of first input value.
324 * \param pValue2 Pointer to second input value, will be modified on
325 * return.
326 * \param pQ2 Pointer to second scaling factor, will be modified on
327 * return.
328 *
329 * \return void
330 */
fixpAdd(const FIXP_DBL value1,const int q1,FIXP_DBL * const pValue2,int * const pQ2)331 static void fixpAdd(const FIXP_DBL value1, const int q1,
332 FIXP_DBL* const pValue2, int* const pQ2) {
333 const int headroom1 = fNormz(fixp_abs(value1)) - 1;
334 const int headroom2 = fNormz(fixp_abs(*pValue2)) - 1;
335 int resultScale = fixMax(q1 - headroom1, (*pQ2) - headroom2);
336
337 if ((value1 != FL2FXCONST_DBL(0.f)) && (*pValue2 != FL2FXCONST_DBL(0.f))) {
338 resultScale++;
339 }
340
341 *pValue2 = scaleValue(value1, q1 - resultScale) +
342 scaleValue(*pValue2, (*pQ2) - resultScale);
343 *pQ2 = (*pValue2 != (FIXP_DBL)0) ? resultScale : DFRACT_BITS - 1;
344 }
345
346 /**
347 * \brief Function for converting time constant to filter coefficient.
348 *
349 * \param t Time constant.
350 * \param sampleRate Sampling rate in Hz.
351 * \param blockLength Length of processing block in samples per channel.
352 *
353 * \return result = 1.0 - exp(-1.0/((t) * (f)))
354 */
tc2Coeff(const FIXP_DBL t,const INT sampleRate,const INT blockLength)355 static FIXP_DBL tc2Coeff(const FIXP_DBL t, const INT sampleRate,
356 const INT blockLength) {
357 FIXP_DBL sampleRateFract;
358 FIXP_DBL blockLengthFract;
359 FIXP_DBL f, product;
360 FIXP_DBL exponent, result;
361 INT e_res;
362
363 /* f = sampleRate/blockLength */
364 sampleRateFract =
365 (FIXP_DBL)(sampleRate << (DFRACT_BITS - 1 - METADATA_LINT_BITS));
366 blockLengthFract =
367 (FIXP_DBL)(blockLength << (DFRACT_BITS - 1 - METADATA_LINT_BITS));
368 f = fDivNorm(sampleRateFract, blockLengthFract, &e_res);
369 f = scaleValue(f, e_res - METADATA_INT_BITS); /* convert to METADATA_FRACT */
370
371 /* product = t*f */
372 product = fMultNorm(t, f, &e_res);
373 product = scaleValue(
374 product, e_res + METADATA_INT_BITS); /* convert to METADATA_FRACT */
375
376 /* exponent = (-1.0/((t) * (f))) */
377 exponent = fDivNorm(METADATA_FRACT_SCALE, product, &e_res);
378 exponent = scaleValue(
379 exponent, e_res - METADATA_INT_BITS); /* convert to METADATA_FRACT */
380
381 /* exponent * ld(e) */
382 exponent = fMult(exponent, FIXP_ILOG2_DIV2) << 1; /* e^(x) = 2^(x*ld(e)) */
383
384 /* exp(-1.0/((t) * (f))) */
385 result = f2Pow(-exponent, DFRACT_BITS - 1 - METADATA_FRACT_BITS, &e_res);
386
387 /* result = 1.0 - exp(-1.0/((t) * (f))) */
388 result = (FIXP_DBL)MAXVAL_DBL - scaleValue(result, e_res);
389
390 return result;
391 }
392
findPeakLevels(HDRC_COMP drcComp,const INT_PCM * const inSamples,const FIXP_DBL clev,const FIXP_DBL slev,const FIXP_DBL ext_leva,const FIXP_DBL ext_levb,const FIXP_DBL lfe_lev,const FIXP_DBL dmxGain5,const FIXP_DBL dmxGain2,FIXP_DBL peak[2])393 static void findPeakLevels(HDRC_COMP drcComp, const INT_PCM* const inSamples,
394 const FIXP_DBL clev, const FIXP_DBL slev,
395 const FIXP_DBL ext_leva, const FIXP_DBL ext_levb,
396 const FIXP_DBL lfe_lev, const FIXP_DBL dmxGain5,
397 const FIXP_DBL dmxGain2, FIXP_DBL peak[2]) {
398 int i, c;
399 FIXP_DBL tmp = FL2FXCONST_DBL(0.f);
400 INT_PCM maxSample = 0;
401
402 /* find peak level */
403 peak[0] = peak[1] = FL2FXCONST_DBL(0.f);
404 for (i = 0; i < drcComp->blockLength; i++) {
405 const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
406
407 /* single channels */
408 for (c = 0; c < (int)drcComp->channels; c++) {
409 maxSample = fMax(maxSample, (INT_PCM)fAbs(pSamples[c]));
410 }
411 }
412 peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample) >> DOWNMIX_SHIFT);
413
414 /* 7.1/6.1 to 5.1 downmixes */
415 if (drcComp->fullChannels > 5) {
416 for (i = 0; i < drcComp->blockLength; i++) {
417 const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
418
419 /* channel 1 (L, Ls,...) */
420 tmp = FL2FXCONST_DBL(0.f);
421 switch (drcComp->chanConfig) {
422 case MODE_6_1:
423 tmp +=
424 fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
425 (DOWNMIX_SHIFT - 1); /* Ls */
426 tmp +=
427 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
428 (DOWNMIX_SHIFT - 1); /* Cs */
429 break;
430 case MODE_7_1_BACK:
431 case MODE_7_1_REAR_SURROUND:
432 tmp +=
433 fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
434 (DOWNMIX_SHIFT - 1); /* Ls */
435 tmp +=
436 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
437 (DOWNMIX_SHIFT - 1); /* Lrs / Lss */
438 break;
439 case MODE_1_2_2_2_1:
440 case MODE_7_1_FRONT_CENTER:
441 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
442 DOWNMIX_SHIFT); /* L */
443 tmp +=
444 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
445 (DOWNMIX_SHIFT - 1); /* Lc */
446 break;
447 case MODE_7_1_TOP_FRONT:
448 tmp +=
449 fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
450 (DOWNMIX_SHIFT - 1); /* L */
451 tmp +=
452 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
453 (DOWNMIX_SHIFT - 1); /* Lvh */
454 break;
455 default:
456 break;
457 }
458 peak[0] = fixMax(peak[0], fixp_abs(tmp));
459
460 /* channel 2 (R, Rs,...) */
461 tmp = FL2FXCONST_DBL(0.f);
462 switch (drcComp->chanConfig) {
463 case MODE_6_1:
464 tmp +=
465 fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
466 (DOWNMIX_SHIFT - 1); /* Rs */
467 tmp +=
468 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
469 (DOWNMIX_SHIFT - 1); /* Cs */
470 break;
471 case MODE_7_1_BACK:
472 case MODE_7_1_REAR_SURROUND:
473 tmp +=
474 fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
475 (DOWNMIX_SHIFT - 1); /* Rs */
476 tmp +=
477 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
478 (DOWNMIX_SHIFT - 1); /* Rrs / Rss */
479 break;
480 case MODE_1_2_2_2_1:
481 case MODE_7_1_FRONT_CENTER:
482 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
483 DOWNMIX_SHIFT); /* R */
484 tmp +=
485 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
486 (DOWNMIX_SHIFT - 1); /* Rc */
487 break;
488 case MODE_7_1_TOP_FRONT:
489 tmp +=
490 fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
491 (DOWNMIX_SHIFT - 1); /* R */
492 tmp +=
493 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
494 (DOWNMIX_SHIFT - 1); /* Rvh */
495 break;
496 default:
497 break;
498 }
499 peak[0] = fixMax(peak[0], fixp_abs(tmp));
500
501 /* channel 3 (C) */
502 tmp = FL2FXCONST_DBL(0.f);
503 switch (drcComp->chanConfig) {
504 case MODE_1_2_2_2_1:
505 case MODE_7_1_FRONT_CENTER:
506 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
507 DOWNMIX_SHIFT); /* C */
508 tmp +=
509 fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
510 (DOWNMIX_SHIFT - 1); /* Lc */
511 tmp +=
512 fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
513 (DOWNMIX_SHIFT - 1); /* Rc */
514 break;
515 default:
516 break;
517 }
518 peak[0] = fixMax(peak[0], fixp_abs(tmp));
519
520 } /* for (blocklength) */
521
522 /* take downmix gain into accout */
523 peak[0] = fMult(dmxGain5, peak[0])
524 << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
525 }
526
527 /* 7.1 / 5.1 to stereo downmixes */
528 if (drcComp->fullChannels > 2) {
529 /* Lt/Rt downmix */
530 for (i = 0; i < drcComp->blockLength; i++) {
531 const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
532
533 /* Lt */
534 tmp = FL2FXCONST_DBL(0.f);
535 if (drcComp->channelIdx[LS] >= 0)
536 tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
537 (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
538 (DOWNMIX_SHIFT - 1); /* Ls */
539 if (drcComp->channelIdx[LS2] >= 0)
540 tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
541 (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
542 (DOWNMIX_SHIFT - 1); /* Ls2 */
543 if (drcComp->channelIdx[RS] >= 0)
544 tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
545 (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
546 (DOWNMIX_SHIFT - 1); /* Rs */
547 if (drcComp->channelIdx[RS2] >= 0)
548 tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
549 (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
550 (DOWNMIX_SHIFT - 1); /* Rs2 */
551 if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0))
552 tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
553 if (drcComp->channelIdx[S] >= 0)
554 tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
555 (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >>
556 (DOWNMIX_SHIFT - 1); /* S */
557 if (drcComp->channelIdx[C] >= 0)
558 tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
559 (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
560 (DOWNMIX_SHIFT - 1); /* C */
561 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >>
562 DOWNMIX_SHIFT); /* L */
563
564 /* apply scaling of downmix gains */
565 /* only for positive values only, as legacy decoders might not know this
566 * parameter */
567 if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
568 if (drcComp->fullChannels > 5) {
569 tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
570 }
571 tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
572 }
573 peak[0] = fixMax(peak[0], fixp_abs(tmp));
574
575 /* Rt */
576 tmp = FL2FXCONST_DBL(0.f);
577 if (drcComp->channelIdx[LS] >= 0)
578 tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
579 (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
580 (DOWNMIX_SHIFT - 1); /* Ls */
581 if (drcComp->channelIdx[LS2] >= 0)
582 tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
583 (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
584 (DOWNMIX_SHIFT - 1); /* Ls2 */
585 if (drcComp->channelIdx[RS] >= 0)
586 tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
587 (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
588 (DOWNMIX_SHIFT - 1); /* Rs */
589 if (drcComp->channelIdx[RS2] >= 0)
590 tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
591 (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
592 (DOWNMIX_SHIFT - 1); /* Rs2 */
593 if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0))
594 tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
595 if (drcComp->channelIdx[S] >= 0)
596 tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
597 (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >>
598 (DOWNMIX_SHIFT - 1); /* S */
599 if (drcComp->channelIdx[C] >= 0)
600 tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
601 (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
602 (DOWNMIX_SHIFT - 1); /* C */
603 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >>
604 DOWNMIX_SHIFT); /* R */
605
606 /* apply scaling of downmix gains */
607 /* only for positive values only, as legacy decoders might not know this
608 * parameter */
609 if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
610 if (drcComp->fullChannels > 5) {
611 tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
612 }
613 tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
614 }
615 peak[0] = fixMax(peak[0], fixp_abs(tmp));
616 }
617
618 /* Lo/Ro downmix */
619 for (i = 0; i < drcComp->blockLength; i++) {
620 const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
621
622 /* Lo */
623 tmp = FL2FXCONST_DBL(0.f);
624 switch (drcComp->chanConfig) {
625 case MODE_6_1:
626 tmp += fMultDiv2(fMult(slev, ext_leva),
627 (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
628 (DOWNMIX_SHIFT - 1); /* Ls */
629 tmp += fMultDiv2(fMult(slev, ext_levb),
630 (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
631 (DOWNMIX_SHIFT - 1); /* Cs */
632 tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
633 (DOWNMIX_SHIFT - 1); /* C */
634 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
635 DOWNMIX_SHIFT); /* L */
636 tmp +=
637 fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
638 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
639 break;
640 case MODE_7_1_BACK:
641 case MODE_7_1_REAR_SURROUND:
642 tmp += fMultDiv2(fMult(slev, ext_leva),
643 (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
644 (DOWNMIX_SHIFT - 1); /* Ls */
645 tmp += fMultDiv2(fMult(slev, ext_levb),
646 (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
647 (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/
648 tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
649 (DOWNMIX_SHIFT - 1); /* C */
650 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
651 DOWNMIX_SHIFT); /* L */
652 tmp +=
653 fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
654 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
655 break;
656 case MODE_1_2_2_2_1:
657 case MODE_7_1_FRONT_CENTER:
658 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
659 DOWNMIX_SHIFT); /* L */
660 tmp +=
661 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
662 (DOWNMIX_SHIFT - 1); /* Lc */
663 tmp += fMultDiv2(fMult(ext_leva, clev),
664 (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
665 (DOWNMIX_SHIFT - 1); /* Lc - second path*/
666 tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
667 (DOWNMIX_SHIFT - 1); /* C */
668 tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
669 (DOWNMIX_SHIFT - 1); /* Ls */
670 tmp +=
671 fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
672 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
673 break;
674 case MODE_7_1_TOP_FRONT:
675 tmp +=
676 fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
677 (DOWNMIX_SHIFT - 1); /* L */
678 tmp +=
679 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
680 (DOWNMIX_SHIFT - 1); /* Lvh */
681 tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
682 (DOWNMIX_SHIFT - 1); /* C */
683 tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
684 (DOWNMIX_SHIFT - 1); /* Ls */
685 tmp +=
686 fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
687 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
688 break;
689 default:
690 if (drcComp->channelIdx[LS] >= 0)
691 tmp +=
692 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
693 (DOWNMIX_SHIFT - 1); /* Ls */
694 if (drcComp->channelIdx[LS2] >= 0)
695 tmp +=
696 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
697 (DOWNMIX_SHIFT - 1); /* Ls2 */
698 if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0))
699 tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
700 if (drcComp->channelIdx[S] >= 0)
701 tmp +=
702 fMultDiv2(slev,
703 fMult(FL2FXCONST_DBL(0.7f),
704 (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >>
705 (DOWNMIX_SHIFT - 1); /* S */
706 if (drcComp->channelIdx[C] >= 0)
707 tmp +=
708 fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
709 (DOWNMIX_SHIFT - 1); /* C */
710 if (drcComp->channelIdx[3] >= 0)
711 tmp += fMultDiv2(lfe_lev,
712 (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
713 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
714 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >>
715 DOWNMIX_SHIFT); /* L */
716 break;
717 }
718
719 /* apply scaling of downmix gains */
720 /* only for positive values only, as legacy decoders might not know this
721 * parameter */
722 if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
723 if (drcComp->fullChannels > 5) {
724 tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
725 }
726 tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
727 }
728 peak[0] = fixMax(peak[0], fixp_abs(tmp));
729
730 /* Ro */
731 tmp = FL2FXCONST_DBL(0.f);
732 switch (drcComp->chanConfig) {
733 case MODE_6_1:
734 tmp += fMultDiv2(fMult(slev, ext_leva),
735 (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
736 (DOWNMIX_SHIFT - 1); /* Rs */
737 tmp += fMultDiv2(fMult(slev, ext_levb),
738 (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
739 (DOWNMIX_SHIFT - 1); /* Cs */
740 tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
741 (DOWNMIX_SHIFT - 1); /* C */
742 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
743 DOWNMIX_SHIFT); /* R */
744 tmp +=
745 fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
746 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
747 break;
748 case MODE_7_1_BACK:
749 case MODE_7_1_REAR_SURROUND:
750 tmp += fMultDiv2(fMult(slev, ext_leva),
751 (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
752 (DOWNMIX_SHIFT - 1); /* Rs */
753 tmp += fMultDiv2(fMult(slev, ext_levb),
754 (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
755 (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/
756 tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
757 (DOWNMIX_SHIFT - 1); /* C */
758 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
759 DOWNMIX_SHIFT); /* R */
760 tmp +=
761 fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
762 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
763 break;
764 case MODE_1_2_2_2_1:
765 case MODE_7_1_FRONT_CENTER:
766 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
767 DOWNMIX_SHIFT); /* R */
768 tmp +=
769 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
770 (DOWNMIX_SHIFT - 1); /* Rc */
771 tmp += fMultDiv2(fMult(ext_leva, clev),
772 (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
773 (DOWNMIX_SHIFT - 1); /* Rc - second path*/
774 tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
775 (DOWNMIX_SHIFT - 1); /* C */
776 tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
777 (DOWNMIX_SHIFT - 1); /* Rs */
778 tmp +=
779 fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
780 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
781 break;
782 case MODE_7_1_TOP_FRONT:
783 tmp +=
784 fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
785 (DOWNMIX_SHIFT - 1); /* R */
786 tmp +=
787 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
788 (DOWNMIX_SHIFT - 1); /* Rvh */
789 tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
790 (DOWNMIX_SHIFT - 1); /* C */
791 tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
792 (DOWNMIX_SHIFT - 1); /* Rs */
793 tmp +=
794 fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
795 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
796 break;
797 default:
798 if (drcComp->channelIdx[RS] >= 0)
799 tmp +=
800 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
801 (DOWNMIX_SHIFT - 1); /* Rs */
802 if (drcComp->channelIdx[RS2] >= 0)
803 tmp +=
804 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
805 (DOWNMIX_SHIFT - 1); /* Rs2 */
806 if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0))
807 tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
808 if (drcComp->channelIdx[S] >= 0)
809 tmp +=
810 fMultDiv2(slev,
811 fMult(FL2FXCONST_DBL(0.7f),
812 (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >>
813 (DOWNMIX_SHIFT - 1); /* S */
814 if (drcComp->channelIdx[C] >= 0)
815 tmp +=
816 fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
817 (DOWNMIX_SHIFT - 1); /* C */
818 if (drcComp->channelIdx[3] >= 0)
819 tmp += fMultDiv2(lfe_lev,
820 (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
821 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
822 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >>
823 DOWNMIX_SHIFT); /* R */
824 }
825
826 /* apply scaling of downmix gains */
827 /* only for positive values only, as legacy decoders might not know this
828 * parameter */
829 if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
830 if (drcComp->fullChannels > 5) {
831 tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
832 }
833 tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
834 }
835 peak[0] = fixMax(peak[0], fixp_abs(tmp));
836 }
837 }
838
839 peak[1] = fixMax(peak[0], peak[1]);
840
841 /* Mono Downmix - for comp_val only */
842 if (drcComp->fullChannels > 1) {
843 for (i = 0; i < drcComp->blockLength; i++) {
844 const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
845
846 tmp = FL2FXCONST_DBL(0.f);
847 switch (drcComp->chanConfig) {
848 case MODE_6_1:
849 tmp += fMultDiv2(fMult(slev, ext_leva),
850 (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
851 (DOWNMIX_SHIFT - 1); /* Ls */
852 tmp += fMultDiv2(fMult(slev, ext_leva),
853 (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
854 (DOWNMIX_SHIFT - 1); /* Rs */
855 tmp += fMult(fMult(slev, ext_levb),
856 (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
857 (DOWNMIX_SHIFT - 1); /* Cs */
858 tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
859 (DOWNMIX_SHIFT - 1); /* C */
860 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
861 DOWNMIX_SHIFT); /* L */
862 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
863 DOWNMIX_SHIFT); /* R */
864 tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
865 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
866 break;
867 case MODE_7_1_BACK:
868 case MODE_7_1_REAR_SURROUND:
869 tmp += fMultDiv2(fMult(slev, ext_leva),
870 (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
871 (DOWNMIX_SHIFT - 1); /* Ls */
872 tmp += fMultDiv2(fMult(slev, ext_leva),
873 (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
874 (DOWNMIX_SHIFT - 1); /* Rs */
875 tmp += fMultDiv2(fMult(slev, ext_levb),
876 (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
877 (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/
878 tmp += fMultDiv2(fMult(slev, ext_levb),
879 (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
880 (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/
881 tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
882 (DOWNMIX_SHIFT - 1); /* C */
883 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
884 DOWNMIX_SHIFT); /* L */
885 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
886 DOWNMIX_SHIFT); /* R */
887 tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
888 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
889 break;
890 case MODE_1_2_2_2_1:
891 case MODE_7_1_FRONT_CENTER:
892 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
893 DOWNMIX_SHIFT); /* L */
894 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
895 DOWNMIX_SHIFT); /* R */
896 tmp +=
897 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
898 (DOWNMIX_SHIFT - 1); /* Lc */
899 tmp +=
900 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
901 (DOWNMIX_SHIFT - 1); /* Rc */
902 tmp += fMultDiv2(fMult(ext_leva, clev),
903 (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
904 (DOWNMIX_SHIFT - 1); /* Lc - second path*/
905 tmp += fMultDiv2(fMult(ext_leva, clev),
906 (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
907 (DOWNMIX_SHIFT - 1); /* Rc - second path*/
908 tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
909 (DOWNMIX_SHIFT - 1); /* C */
910 tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
911 (DOWNMIX_SHIFT - 1); /* Ls */
912 tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
913 (DOWNMIX_SHIFT - 1); /* Rs */
914 tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
915 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
916 break;
917 case MODE_7_1_TOP_FRONT:
918 tmp +=
919 fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
920 (DOWNMIX_SHIFT - 1); /* L */
921 tmp +=
922 fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
923 (DOWNMIX_SHIFT - 1); /* R */
924 tmp +=
925 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
926 (DOWNMIX_SHIFT - 1); /* Lvh */
927 tmp +=
928 fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
929 (DOWNMIX_SHIFT - 1); /* Rvh */
930 tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
931 (DOWNMIX_SHIFT - 1); /* C */
932 tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
933 (DOWNMIX_SHIFT - 1); /* Ls */
934 tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
935 (DOWNMIX_SHIFT - 1); /* Rs */
936 tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
937 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
938 break;
939 default:
940 if (drcComp->channelIdx[LS] >= 0)
941 tmp +=
942 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
943 (DOWNMIX_SHIFT - 1); /* Ls */
944 if (drcComp->channelIdx[LS2] >= 0)
945 tmp +=
946 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
947 (DOWNMIX_SHIFT - 1); /* Ls2 */
948 if (drcComp->channelIdx[RS] >= 0)
949 tmp +=
950 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
951 (DOWNMIX_SHIFT - 1); /* Rs */
952 if (drcComp->channelIdx[RS2] >= 0)
953 tmp +=
954 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
955 (DOWNMIX_SHIFT - 1); /* Rs2 */
956 if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0))
957 tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
958 /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/ /* 7.1ch */
959 if (drcComp->channelIdx[S] >= 0)
960 tmp +=
961 fMultDiv2(slev,
962 fMult(FL2FXCONST_DBL(0.7f),
963 (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >>
964 (DOWNMIX_SHIFT - 1); /* S */
965 if (drcComp->channelIdx[C] >= 0)
966 tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
967 (DOWNMIX_SHIFT - 1); /* C (2*clev) */
968 if (drcComp->channelIdx[3] >= 0)
969 tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
970 (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
971 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >>
972 DOWNMIX_SHIFT); /* L */
973 tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >>
974 DOWNMIX_SHIFT); /* R */
975 }
976
977 /* apply scaling of downmix gains */
978 /* only for positive values only, as legacy decoders might not know this
979 * parameter */
980 if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
981 if (drcComp->fullChannels > 5) {
982 tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
983 }
984 tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
985 }
986 peak[1] = fixMax(peak[1], fixp_abs(tmp));
987 }
988 }
989 }
990
FDK_DRC_Generator_Open(HDRC_COMP * phDrcComp)991 INT FDK_DRC_Generator_Open(HDRC_COMP* phDrcComp) {
992 INT err = 0;
993 HDRC_COMP hDcComp = NULL;
994
995 if (phDrcComp == NULL) {
996 err = -1;
997 goto bail;
998 }
999
1000 /* allocate memory */
1001 hDcComp = (HDRC_COMP)FDKcalloc(1, sizeof(DRC_COMP));
1002
1003 if (hDcComp == NULL) {
1004 err = -1;
1005 goto bail;
1006 }
1007
1008 FDKmemclear(hDcComp, sizeof(DRC_COMP));
1009
1010 /* Return drc compressor instance */
1011 *phDrcComp = hDcComp;
1012 return err;
1013 bail:
1014 FDK_DRC_Generator_Close(&hDcComp);
1015 return err;
1016 }
1017
FDK_DRC_Generator_Close(HDRC_COMP * phDrcComp)1018 INT FDK_DRC_Generator_Close(HDRC_COMP* phDrcComp) {
1019 if (phDrcComp == NULL) {
1020 return -1;
1021 }
1022 if (*phDrcComp != NULL) {
1023 FDKfree(*phDrcComp);
1024 *phDrcComp = NULL;
1025 }
1026 return 0;
1027 }
1028
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)1029 INT FDK_DRC_Generator_Initialize(HDRC_COMP drcComp,
1030 const DRC_PROFILE profileLine,
1031 const DRC_PROFILE profileRF,
1032 const INT blockLength, const UINT sampleRate,
1033 const CHANNEL_MODE channelMode,
1034 const CHANNEL_ORDER channelOrder,
1035 const UCHAR useWeighting) {
1036 int i;
1037 CHANNEL_MAPPING channelMapping;
1038
1039 drcComp->limDecay =
1040 FL2FXCONST_DBL(((0.006f / 256) * blockLength) / METADATA_INT_SCALE);
1041
1042 /* Save parameters. */
1043 drcComp->blockLength = blockLength;
1044 drcComp->sampleRate = sampleRate;
1045 drcComp->chanConfig = channelMode;
1046 drcComp->useWeighting = useWeighting;
1047
1048 if (FDK_DRC_Generator_setDrcProfile(drcComp, profileLine, profileRF) !=
1049 0) { /* expects initialized blockLength and sampleRate */
1050 return (-1);
1051 }
1052
1053 /* Set number of channels and channel offsets. */
1054 if (FDKaacEnc_InitChannelMapping(channelMode, channelOrder,
1055 &channelMapping) != AAC_ENC_OK) {
1056 return (-2);
1057 }
1058
1059 for (i = 0; i < 9; i++) drcComp->channelIdx[i] = -1;
1060
1061 switch (channelMode) {
1062 case MODE_1: /* mono */
1063 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
1064 break;
1065 case MODE_2: /* stereo */
1066 drcComp->channelIdx[L] = channelMapping.elInfo[0].ChannelIndex[0];
1067 drcComp->channelIdx[R] = channelMapping.elInfo[0].ChannelIndex[1];
1068 break;
1069 case MODE_1_2: /* 3ch */
1070 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
1071 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
1072 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
1073 break;
1074 case MODE_1_2_1: /* 4ch */
1075 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
1076 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
1077 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
1078 drcComp->channelIdx[S] = channelMapping.elInfo[2].ChannelIndex[0];
1079 break;
1080 case MODE_1_2_2: /* 5ch */
1081 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
1082 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
1083 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
1084 drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0];
1085 drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1];
1086 break;
1087 case MODE_1_2_2_1: /* 5.1 ch */
1088 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
1089 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
1090 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
1091 drcComp->channelIdx[LFE] = channelMapping.elInfo[3].ChannelIndex[0];
1092 drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0];
1093 drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1];
1094 break;
1095 case MODE_1_2_2_2_1: /* 7.1 ch */
1096 case MODE_7_1_FRONT_CENTER:
1097 drcComp->channelIdx[L] = channelMapping.elInfo[2].ChannelIndex[0]; /* l */
1098 drcComp->channelIdx[R] = channelMapping.elInfo[2].ChannelIndex[1]; /* r */
1099 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
1100 drcComp->channelIdx[LFE] =
1101 channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
1102 drcComp->channelIdx[LS] =
1103 channelMapping.elInfo[3].ChannelIndex[0]; /* ls */
1104 drcComp->channelIdx[RS] =
1105 channelMapping.elInfo[3].ChannelIndex[1]; /* rs */
1106 drcComp->channelIdx[LS2] =
1107 channelMapping.elInfo[1].ChannelIndex[0]; /* lc */
1108 drcComp->channelIdx[RS2] =
1109 channelMapping.elInfo[1].ChannelIndex[1]; /* rc */
1110 break;
1111 case MODE_7_1_BACK:
1112 case MODE_7_1_REAR_SURROUND:
1113 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */
1114 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */
1115 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
1116 drcComp->channelIdx[LFE] =
1117 channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
1118 drcComp->channelIdx[LS] =
1119 channelMapping.elInfo[3].ChannelIndex[0]; /* lrear */
1120 drcComp->channelIdx[RS] =
1121 channelMapping.elInfo[3].ChannelIndex[1]; /* rrear */
1122 drcComp->channelIdx[LS2] =
1123 channelMapping.elInfo[2].ChannelIndex[0]; /* ls */
1124 drcComp->channelIdx[RS2] =
1125 channelMapping.elInfo[2].ChannelIndex[1]; /* rs */
1126 break;
1127 case MODE_6_1:
1128 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */
1129 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */
1130 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
1131 drcComp->channelIdx[LFE] =
1132 channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
1133 drcComp->channelIdx[LS] =
1134 channelMapping.elInfo[2].ChannelIndex[0]; /* ls */
1135 drcComp->channelIdx[RS] =
1136 channelMapping.elInfo[2].ChannelIndex[1]; /* rs */
1137 drcComp->channelIdx[S] = channelMapping.elInfo[3].ChannelIndex[0]; /* s */
1138 break;
1139 case MODE_7_1_TOP_FRONT:
1140 drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */
1141 drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */
1142 drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
1143 drcComp->channelIdx[LFE] =
1144 channelMapping.elInfo[3].ChannelIndex[0]; /* lfe */
1145 drcComp->channelIdx[LS] =
1146 channelMapping.elInfo[2].ChannelIndex[0]; /* ls */
1147 drcComp->channelIdx[RS] =
1148 channelMapping.elInfo[2].ChannelIndex[1]; /* rs */
1149 drcComp->channelIdx[LS2] =
1150 channelMapping.elInfo[4].ChannelIndex[0]; /* lvh2 */
1151 drcComp->channelIdx[RS2] =
1152 channelMapping.elInfo[4].ChannelIndex[1]; /* rvh2 */
1153 break;
1154 default:
1155 return (-1);
1156 }
1157
1158 drcComp->fullChannels = channelMapping.nChannelsEff;
1159 drcComp->channels = channelMapping.nChannels;
1160
1161 /* Init states. */
1162 drcComp->smoothLevel[0] = drcComp->smoothLevel[1] =
1163 (FIXP_DBL)(-(135 << METADATA_FRACT_BITS));
1164
1165 FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain));
1166 FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt));
1167 FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain));
1168 FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak));
1169 FDKmemclear(drcComp->filter, sizeof(drcComp->filter));
1170
1171 return (0);
1172 }
1173
FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp,const DRC_PROFILE profileLine,const DRC_PROFILE profileRF)1174 INT FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp,
1175 const DRC_PROFILE profileLine,
1176 const DRC_PROFILE profileRF) {
1177 int profileIdx, i;
1178
1179 drcComp->profile[0] = profileLine;
1180 drcComp->profile[1] = profileRF;
1181
1182 for (i = 0; i < 2; i++) {
1183 /* get profile index */
1184 switch (drcComp->profile[i]) {
1185 case DRC_NONE:
1186 case DRC_NOT_PRESENT:
1187 case DRC_FILMSTANDARD:
1188 profileIdx = 0;
1189 break;
1190 case DRC_FILMLIGHT:
1191 profileIdx = 1;
1192 break;
1193 case DRC_MUSICSTANDARD:
1194 profileIdx = 2;
1195 break;
1196 case DRC_MUSICLIGHT:
1197 profileIdx = 3;
1198 break;
1199 case DRC_SPEECH:
1200 profileIdx = 4;
1201 break;
1202 case DRC_DELAY_TEST:
1203 profileIdx = 5;
1204 break;
1205 default:
1206 return (-1);
1207 }
1208
1209 /* get parameters for selected profile */
1210 if (profileIdx >= 0) {
1211 drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx];
1212 drcComp->boostThr[i] = tabBoostThr[profileIdx];
1213 drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx];
1214 drcComp->cutThr[i] = tabCutThr[profileIdx];
1215 drcComp->maxCutThr[i] = tabMaxCutThr[profileIdx];
1216
1217 drcComp->boostFac[i] = tabBoostRatio[profileIdx];
1218 drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx];
1219 drcComp->cutFac[i] = tabCutRatio[profileIdx];
1220
1221 drcComp->maxBoost[i] = tabMaxBoost[profileIdx];
1222 drcComp->maxCut[i] = tabMaxCut[profileIdx];
1223 drcComp->maxEarlyCut[i] =
1224 -fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]),
1225 drcComp->earlyCutFac[i]); /* no scaling after mult needed,
1226 earlyCutFac is in FIXP_DBL */
1227
1228 drcComp->fastAttack[i] = tc2Coeff(
1229 tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
1230 drcComp->fastDecay[i] = tc2Coeff(
1231 tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
1232 drcComp->slowAttack[i] = tc2Coeff(
1233 tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
1234 drcComp->slowDecay[i] = tc2Coeff(
1235 tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
1236 drcComp->holdOff[i] = tabHoldOff[profileIdx] * 256 / drcComp->blockLength;
1237
1238 drcComp->attackThr[i] = tabAttackThr[profileIdx];
1239 drcComp->decayThr[i] = tabDecayThr[profileIdx];
1240 }
1241
1242 drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
1243 }
1244 return (0);
1245 }
1246
FDK_DRC_Generator_Calc(HDRC_COMP drcComp,const INT_PCM * const inSamples,const UINT inSamplesBufSize,const INT dialnorm,const INT drc_TargetRefLevel,const INT comp_TargetRefLevel,const FIXP_DBL clev,const FIXP_DBL slev,const FIXP_DBL ext_leva,const FIXP_DBL ext_levb,const FIXP_DBL lfe_lev,const INT dmxGain5,const INT dmxGain2,INT * const pDynrng,INT * const pCompr)1247 INT FDK_DRC_Generator_Calc(HDRC_COMP drcComp, const INT_PCM* const inSamples,
1248 const UINT inSamplesBufSize, const INT dialnorm,
1249 const INT drc_TargetRefLevel,
1250 const INT comp_TargetRefLevel, const FIXP_DBL clev,
1251 const FIXP_DBL slev, const FIXP_DBL ext_leva,
1252 const FIXP_DBL ext_levb, const FIXP_DBL lfe_lev,
1253 const INT dmxGain5, const INT dmxGain2,
1254 INT* const pDynrng, INT* const pCompr) {
1255 int i, c;
1256 FIXP_DBL peak[2];
1257
1258 /**************************************************************************
1259 * compressor
1260 **************************************************************************/
1261 if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) {
1262 /* Calc loudness level */
1263 FIXP_DBL level_b = FL2FXCONST_DBL(0.f);
1264 int level_e = DFRACT_BITS - 1;
1265
1266 /* Increase energy time resolution with shorter processing blocks. 16 is an
1267 * empiric value. */
1268 const int granuleLength = fixMin(16, drcComp->blockLength);
1269
1270 if (drcComp->useWeighting) {
1271 FIXP_DBL x1, x2, y, y1, y2;
1272 /* sum of filter coefficients about 2.5 -> squared value is 6.25
1273 WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce
1274 granuleShift by 1.
1275 */
1276 const int granuleShift = getShiftFactor(granuleLength) - 1;
1277
1278 for (c = 0; c < (int)drcComp->channels; c++) {
1279 const INT_PCM* pSamples = inSamples + c * inSamplesBufSize;
1280
1281 if (c == drcComp->channelIdx[LFE]) {
1282 continue; /* skip LFE */
1283 }
1284
1285 /* get filter states */
1286 x1 = drcComp->filter[c].x1;
1287 x2 = drcComp->filter[c].x2;
1288 y1 = drcComp->filter[c].y1;
1289 y2 = drcComp->filter[c].y2;
1290
1291 i = 0;
1292
1293 do {
1294 int offset = i;
1295 FIXP_DBL accu = FL2FXCONST_DBL(0.f);
1296
1297 for (i = offset;
1298 i < fixMin(offset + granuleLength, drcComp->blockLength); i++) {
1299 /* apply weighting filter */
1300 FIXP_DBL x =
1301 FX_PCM2FX_DBL((FIXP_PCM)pSamples[i]) >> WEIGHTING_FILTER_SHIFT;
1302
1303 /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */
1304 y = fMult(b0, x - x2) - fMult(a1, y1) - fMult(a2, y2);
1305
1306 x2 = x1;
1307 x1 = x;
1308 y2 = y1;
1309 y1 = y;
1310
1311 accu += fPow2Div2(y) >> (granuleShift - 1); /* partial energy */
1312 } /* i */
1313
1314 fixpAdd(accu, granuleShift + 2 * WEIGHTING_FILTER_SHIFT, &level_b,
1315 &level_e); /* sup up partial energies */
1316
1317 } while (i < drcComp->blockLength);
1318
1319 /* save filter states */
1320 drcComp->filter[c].x1 = x1;
1321 drcComp->filter[c].x2 = x2;
1322 drcComp->filter[c].y1 = y1;
1323 drcComp->filter[c].y2 = y2;
1324 } /* c */
1325 } /* weighting */
1326 else {
1327 const int granuleShift = getShiftFactor(granuleLength);
1328
1329 for (c = 0; c < (int)drcComp->channels; c++) {
1330 const INT_PCM* pSamples = inSamples + c * inSamplesBufSize;
1331
1332 if ((int)c == drcComp->channelIdx[LFE]) {
1333 continue; /* skip LFE */
1334 }
1335
1336 i = 0;
1337
1338 do {
1339 int offset = i;
1340 FIXP_DBL accu = FL2FXCONST_DBL(0.f);
1341
1342 for (i = offset;
1343 i < fixMin(offset + granuleLength, drcComp->blockLength); i++) {
1344 /* partial energy */
1345 accu += fPow2Div2((FIXP_PCM)pSamples[i]) >> (granuleShift - 1);
1346 } /* i */
1347
1348 fixpAdd(accu, granuleShift, &level_b,
1349 &level_e); /* sup up partial energies */
1350
1351 } while (i < drcComp->blockLength);
1352 }
1353 } /* weighting */
1354
1355 /*
1356 * Convert to dBFS, apply dialnorm
1357 */
1358 /* level scaling */
1359
1360 /* descaled level in ld64 representation */
1361 FIXP_DBL ldLevel =
1362 CalcLdData(level_b) +
1363 (FIXP_DBL)((level_e - 12) << (DFRACT_BITS - 1 - LD_DATA_SHIFT)) -
1364 CalcLdData((FIXP_DBL)(drcComp->blockLength << (DFRACT_BITS - 1 - 12)));
1365
1366 /* if (level < 1e-10) level = 1e-10f; */
1367 ldLevel =
1368 fMax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f));
1369
1370 /* level = 10 * log(level)/log(10) + 3;
1371 * = 10*log(2)/log(10) * ld(level) + 3;
1372 * = 10 * 0.30102999566398119521373889472449 * ld(level) + 3
1373 * = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3)
1374 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64)
1375 * * 64
1376 *
1377 * additional scaling with METADATA_FRACT_BITS:
1378 * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64)
1379 * * 64 * 2^(METADATA_FRACT_BITS) = 10 * (0.30102999566398119521373889472449
1380 * * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) =
1381 * 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * (
1382 * 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 )
1383 * */
1384 FIXP_DBL level = fMult(
1385 (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)),
1386 fMult(FL2FXCONST_DBL(0.30102999566398119521373889472449f), ldLevel) +
1387 (FIXP_DBL)(FL2FXCONST_DBL(0.3f) >> LD_DATA_SHIFT));
1388
1389 /* level -= dialnorm + 31 */ /* this is fixed to Dolby-ReferenceLevel as
1390 compressor profiles are defined relative to
1391 this */
1392 level -= ((FIXP_DBL)(dialnorm << (METADATA_FRACT_BITS - 16)) +
1393 (FIXP_DBL)(31 << METADATA_FRACT_BITS));
1394
1395 for (i = 0; i < 2; i++) {
1396 if (drcComp->profile[i] == DRC_NONE) {
1397 /* no compression */
1398 drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
1399 } else {
1400 FIXP_DBL gain, alpha, lvl2smthlvl;
1401
1402 /* calc static gain */
1403 if (level <= drcComp->maxBoostThr[i]) {
1404 /* max boost */
1405 gain = drcComp->maxBoost[i];
1406 } else if (level < drcComp->boostThr[i]) {
1407 /* boost range */
1408 gain = fMult((level - drcComp->boostThr[i]), drcComp->boostFac[i]);
1409 } else if (level <= drcComp->earlyCutThr[i]) {
1410 /* null band */
1411 gain = FL2FXCONST_DBL(0.f);
1412 } else if (level <= drcComp->cutThr[i]) {
1413 /* early cut range */
1414 gain =
1415 fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]);
1416 } else if (level < drcComp->maxCutThr[i]) {
1417 /* cut range */
1418 gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) -
1419 drcComp->maxEarlyCut[i];
1420 } else {
1421 /* max cut */
1422 gain = -drcComp->maxCut[i];
1423 }
1424
1425 /* choose time constant */
1426 lvl2smthlvl = level - drcComp->smoothLevel[i];
1427 if (gain < drcComp->smoothGain[i]) {
1428 /* attack */
1429 if (lvl2smthlvl > drcComp->attackThr[i]) {
1430 /* fast attack */
1431 alpha = drcComp->fastAttack[i];
1432 } else {
1433 /* slow attack */
1434 alpha = drcComp->slowAttack[i];
1435 }
1436 } else {
1437 /* release */
1438 if (lvl2smthlvl < -drcComp->decayThr[i]) {
1439 /* fast release */
1440 alpha = drcComp->fastDecay[i];
1441 } else {
1442 /* slow release */
1443 alpha = drcComp->slowDecay[i];
1444 }
1445 }
1446
1447 /* smooth gain & level */
1448 if ((gain < drcComp->smoothGain[i]) ||
1449 (drcComp->holdCnt[i] ==
1450 0)) { /* hold gain unless we have an attack or hold
1451 period is over */
1452 FIXP_DBL accu;
1453
1454 /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] +
1455 * alpha * level; */
1456 accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothLevel[i]);
1457 accu += fMult(alpha, level);
1458 drcComp->smoothLevel[i] = accu;
1459
1460 /* drcComp->smoothGain[i] = (1-alpha) * drcComp->smoothGain[i] +
1461 * alpha * gain; */
1462 accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothGain[i]);
1463 accu += fMult(alpha, gain);
1464 drcComp->smoothGain[i] = accu;
1465 }
1466
1467 /* hold counter */
1468 if (drcComp->holdCnt[i]) {
1469 drcComp->holdCnt[i]--;
1470 }
1471 if (gain < drcComp->smoothGain[i]) {
1472 drcComp->holdCnt[i] = drcComp->holdOff[i];
1473 }
1474 } /* profile != DRC_NONE */
1475 } /* for i=1..2 */
1476 } else {
1477 /* no compression */
1478 drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f);
1479 drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f);
1480 }
1481
1482 /**************************************************************************
1483 * limiter
1484 **************************************************************************/
1485
1486 findPeakLevels(drcComp, inSamples, clev, slev, ext_leva, ext_levb, lfe_lev,
1487 (FIXP_DBL)((LONG)(dmxGain5) << (METADATA_FRACT_BITS - 16)),
1488 (FIXP_DBL)((LONG)(dmxGain2) << (METADATA_FRACT_BITS - 16)),
1489 peak);
1490
1491 for (i = 0; i < 2; i++) {
1492 FIXP_DBL tmp = drcComp->prevPeak[i];
1493 drcComp->prevPeak[i] = peak[i];
1494 peak[i] = fixMax(peak[i], tmp);
1495
1496 /*
1497 * Convert to dBFS, apply dialnorm
1498 */
1499 /* descaled peak in ld64 representation */
1500 FIXP_DBL ld_peak =
1501 CalcLdData(peak[i]) +
1502 (FIXP_DBL)((LONG)DOWNMIX_SHIFT << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
1503
1504 /* if (peak < 1e-6) level = 1e-6f; */
1505 ld_peak =
1506 fMax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f));
1507
1508 /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f +
1509 * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) peak[i] = 20 *
1510 * log(2)/log(10) * ld(peak[i]) + 0.2f +
1511 * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) peak[i] = 10 *
1512 * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f +
1513 * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
1514 *
1515 * additional scaling with METADATA_FRACT_BITS:
1516 * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64
1517 * + 0.2f +
1518 * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS)
1519 * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) *
1520 * 2*0.30102999566398119521373889472449 * ld64(peak[i])
1521 * + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i]
1522 */
1523 peak[i] = fMult(
1524 (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)),
1525 fMult(FL2FX_DBL(2 * 0.30102999566398119521373889472449f), ld_peak));
1526 peak[i] +=
1527 (FL2FX_DBL(0.5f) >> METADATA_INT_BITS); /* add a little bit headroom */
1528 peak[i] += drcComp->smoothGain[i];
1529 }
1530
1531 /* peak -= dialnorm + 31; */ /* this is Dolby style only */
1532 peak[0] -= (FIXP_DBL)((dialnorm - drc_TargetRefLevel)
1533 << (METADATA_FRACT_BITS -
1534 16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */
1535
1536 /* peak += 11; */
1537 /* this is Dolby style only */ /* RF mode output is 11dB higher */
1538 /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/
1539 peak[1] -=
1540 (FIXP_DBL)((dialnorm - comp_TargetRefLevel)
1541 << (METADATA_FRACT_BITS -
1542 16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */
1543
1544 /* limiter gain */
1545 drcComp->limGain[0] += drcComp->limDecay; /* linear limiter release */
1546 drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]);
1547
1548 drcComp->limGain[1] += 2 * drcComp->limDecay; /* linear limiter release */
1549 drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]);
1550
1551 /*************************************************************************/
1552
1553 /* apply limiting, return DRC gains*/
1554 {
1555 FIXP_DBL tmp;
1556
1557 tmp = drcComp->smoothGain[0];
1558 if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) {
1559 tmp += drcComp->limGain[0];
1560 }
1561 *pDynrng = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16));
1562
1563 tmp = drcComp->smoothGain[1];
1564 if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) {
1565 tmp += drcComp->limGain[1];
1566 }
1567 *pCompr = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16));
1568 }
1569
1570 return 0;
1571 }
1572
FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp)1573 DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp) {
1574 return drcComp->profile[0];
1575 }
1576
FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp)1577 DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp) {
1578 return drcComp->profile[1];
1579 }
1580