/src/aac/libAACenc/src/metadata_compressor.cpp
Line | Count | Source (jump to first uncovered line) |
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 | 0 | #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 | 0 | #define DOWNMIX_SHIFT (3) /*!< Max 8 channel. */ |
114 | 0 | #define WEIGHTING_FILTER_SHIFT (2) /*!< Scaling used in weighting filter. */ |
115 | | |
116 | 0 | #define METADATA_INT_BITS 10 |
117 | 0 | #define METADATA_LINT_BITS 20 |
118 | | #define METADATA_INT_SCALE (INT64(1) << (METADATA_INT_BITS)) |
119 | 0 | #define METADATA_FRACT_BITS (DFRACT_BITS - 1 - METADATA_INT_BITS) |
120 | 0 | #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 | | */ |
311 | 0 | static UINT getShiftFactor(const UINT length) { |
312 | 0 | UINT ldN; |
313 | 0 | for (ldN = 1; (((UINT)1) << ldN) < length; ldN++) |
314 | 0 | ; |
315 | |
|
316 | 0 | return ldN; |
317 | 0 | } |
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 | | */ |
331 | | static void fixpAdd(const FIXP_DBL value1, const int q1, |
332 | 0 | FIXP_DBL* const pValue2, int* const pQ2) { |
333 | 0 | const int headroom1 = fNormz(fixp_abs(value1)) - 1; |
334 | 0 | const int headroom2 = fNormz(fixp_abs(*pValue2)) - 1; |
335 | 0 | int resultScale = fixMax(q1 - headroom1, (*pQ2) - headroom2); |
336 | |
|
337 | 0 | if ((value1 != FL2FXCONST_DBL(0.f)) && (*pValue2 != FL2FXCONST_DBL(0.f))) { |
338 | 0 | resultScale++; |
339 | 0 | } |
340 | |
|
341 | 0 | *pValue2 = scaleValue(value1, q1 - resultScale) + |
342 | 0 | scaleValue(*pValue2, (*pQ2) - resultScale); |
343 | 0 | *pQ2 = (*pValue2 != (FIXP_DBL)0) ? resultScale : DFRACT_BITS - 1; |
344 | 0 | } |
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 | | */ |
355 | | static FIXP_DBL tc2Coeff(const FIXP_DBL t, const INT sampleRate, |
356 | 0 | const INT blockLength) { |
357 | 0 | FIXP_DBL sampleRateFract; |
358 | 0 | FIXP_DBL blockLengthFract; |
359 | 0 | FIXP_DBL f, product; |
360 | 0 | FIXP_DBL exponent, result; |
361 | 0 | INT e_res; |
362 | | |
363 | | /* f = sampleRate/blockLength */ |
364 | 0 | sampleRateFract = |
365 | 0 | (FIXP_DBL)(sampleRate << (DFRACT_BITS - 1 - METADATA_LINT_BITS)); |
366 | 0 | blockLengthFract = |
367 | 0 | (FIXP_DBL)(blockLength << (DFRACT_BITS - 1 - METADATA_LINT_BITS)); |
368 | 0 | f = fDivNorm(sampleRateFract, blockLengthFract, &e_res); |
369 | 0 | f = scaleValue(f, e_res - METADATA_INT_BITS); /* convert to METADATA_FRACT */ |
370 | | |
371 | | /* product = t*f */ |
372 | 0 | product = fMultNorm(t, f, &e_res); |
373 | 0 | product = scaleValue( |
374 | 0 | product, e_res + METADATA_INT_BITS); /* convert to METADATA_FRACT */ |
375 | | |
376 | | /* exponent = (-1.0/((t) * (f))) */ |
377 | 0 | exponent = fDivNorm(METADATA_FRACT_SCALE, product, &e_res); |
378 | 0 | exponent = scaleValue( |
379 | 0 | exponent, e_res - METADATA_INT_BITS); /* convert to METADATA_FRACT */ |
380 | | |
381 | | /* exponent * ld(e) */ |
382 | 0 | exponent = fMult(exponent, FIXP_ILOG2_DIV2) << 1; /* e^(x) = 2^(x*ld(e)) */ |
383 | | |
384 | | /* exp(-1.0/((t) * (f))) */ |
385 | 0 | result = f2Pow(-exponent, DFRACT_BITS - 1 - METADATA_FRACT_BITS, &e_res); |
386 | | |
387 | | /* result = 1.0 - exp(-1.0/((t) * (f))) */ |
388 | 0 | result = (FIXP_DBL)MAXVAL_DBL - scaleValue(result, e_res); |
389 | |
|
390 | 0 | return result; |
391 | 0 | } |
392 | | |
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 | 0 | const FIXP_DBL dmxGain2, FIXP_DBL peak[2]) { |
398 | 0 | int i, c; |
399 | 0 | FIXP_DBL tmp = FL2FXCONST_DBL(0.f); |
400 | 0 | INT_PCM maxSample = 0; |
401 | | |
402 | | /* find peak level */ |
403 | 0 | peak[0] = peak[1] = FL2FXCONST_DBL(0.f); |
404 | 0 | for (i = 0; i < drcComp->blockLength; i++) { |
405 | 0 | const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; |
406 | | |
407 | | /* single channels */ |
408 | 0 | for (c = 0; c < (int)drcComp->channels; c++) { |
409 | 0 | maxSample = fMax(maxSample, (INT_PCM)fAbs(pSamples[c])); |
410 | 0 | } |
411 | 0 | } |
412 | 0 | peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample) >> DOWNMIX_SHIFT); |
413 | | |
414 | | /* 7.1/6.1 to 5.1 downmixes */ |
415 | 0 | if (drcComp->fullChannels > 5) { |
416 | 0 | for (i = 0; i < drcComp->blockLength; i++) { |
417 | 0 | const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; |
418 | | |
419 | | /* channel 1 (L, Ls,...) */ |
420 | 0 | tmp = FL2FXCONST_DBL(0.f); |
421 | 0 | switch (drcComp->chanConfig) { |
422 | 0 | case MODE_6_1: |
423 | 0 | tmp += |
424 | 0 | fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> |
425 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
426 | 0 | tmp += |
427 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> |
428 | 0 | (DOWNMIX_SHIFT - 1); /* Cs */ |
429 | 0 | break; |
430 | 0 | case MODE_7_1_BACK: |
431 | 0 | case MODE_7_1_REAR_SURROUND: |
432 | 0 | tmp += |
433 | 0 | fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> |
434 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
435 | 0 | tmp += |
436 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> |
437 | 0 | (DOWNMIX_SHIFT - 1); /* Lrs / Lss */ |
438 | 0 | break; |
439 | 0 | case MODE_1_2_2_2_1: |
440 | 0 | case MODE_7_1_FRONT_CENTER: |
441 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> |
442 | 0 | DOWNMIX_SHIFT); /* L */ |
443 | 0 | tmp += |
444 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> |
445 | 0 | (DOWNMIX_SHIFT - 1); /* Lc */ |
446 | 0 | break; |
447 | 0 | case MODE_7_1_TOP_FRONT: |
448 | 0 | tmp += |
449 | 0 | fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> |
450 | 0 | (DOWNMIX_SHIFT - 1); /* L */ |
451 | 0 | tmp += |
452 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> |
453 | 0 | (DOWNMIX_SHIFT - 1); /* Lvh */ |
454 | 0 | break; |
455 | 0 | default: |
456 | 0 | break; |
457 | 0 | } |
458 | 0 | peak[0] = fixMax(peak[0], fixp_abs(tmp)); |
459 | | |
460 | | /* channel 2 (R, Rs,...) */ |
461 | 0 | tmp = FL2FXCONST_DBL(0.f); |
462 | 0 | switch (drcComp->chanConfig) { |
463 | 0 | case MODE_6_1: |
464 | 0 | tmp += |
465 | 0 | fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> |
466 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
467 | 0 | tmp += |
468 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> |
469 | 0 | (DOWNMIX_SHIFT - 1); /* Cs */ |
470 | 0 | break; |
471 | 0 | case MODE_7_1_BACK: |
472 | 0 | case MODE_7_1_REAR_SURROUND: |
473 | 0 | tmp += |
474 | 0 | fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> |
475 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
476 | 0 | tmp += |
477 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> |
478 | 0 | (DOWNMIX_SHIFT - 1); /* Rrs / Rss */ |
479 | 0 | break; |
480 | 0 | case MODE_1_2_2_2_1: |
481 | 0 | case MODE_7_1_FRONT_CENTER: |
482 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> |
483 | 0 | DOWNMIX_SHIFT); /* R */ |
484 | 0 | tmp += |
485 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> |
486 | 0 | (DOWNMIX_SHIFT - 1); /* Rc */ |
487 | 0 | break; |
488 | 0 | case MODE_7_1_TOP_FRONT: |
489 | 0 | tmp += |
490 | 0 | fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> |
491 | 0 | (DOWNMIX_SHIFT - 1); /* R */ |
492 | 0 | tmp += |
493 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> |
494 | 0 | (DOWNMIX_SHIFT - 1); /* Rvh */ |
495 | 0 | break; |
496 | 0 | default: |
497 | 0 | break; |
498 | 0 | } |
499 | 0 | peak[0] = fixMax(peak[0], fixp_abs(tmp)); |
500 | | |
501 | | /* channel 3 (C) */ |
502 | 0 | tmp = FL2FXCONST_DBL(0.f); |
503 | 0 | switch (drcComp->chanConfig) { |
504 | 0 | case MODE_1_2_2_2_1: |
505 | 0 | case MODE_7_1_FRONT_CENTER: |
506 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> |
507 | 0 | DOWNMIX_SHIFT); /* C */ |
508 | 0 | tmp += |
509 | 0 | fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> |
510 | 0 | (DOWNMIX_SHIFT - 1); /* Lc */ |
511 | 0 | tmp += |
512 | 0 | fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> |
513 | 0 | (DOWNMIX_SHIFT - 1); /* Rc */ |
514 | 0 | break; |
515 | 0 | default: |
516 | 0 | break; |
517 | 0 | } |
518 | 0 | peak[0] = fixMax(peak[0], fixp_abs(tmp)); |
519 | |
|
520 | 0 | } /* for (blocklength) */ |
521 | | |
522 | | /* take downmix gain into accout */ |
523 | 0 | peak[0] = fMult(dmxGain5, peak[0]) |
524 | 0 | << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); |
525 | 0 | } |
526 | | |
527 | | /* 7.1 / 5.1 to stereo downmixes */ |
528 | 0 | if (drcComp->fullChannels > 2) { |
529 | | /* Lt/Rt downmix */ |
530 | 0 | for (i = 0; i < drcComp->blockLength; i++) { |
531 | 0 | const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; |
532 | | |
533 | | /* Lt */ |
534 | 0 | tmp = FL2FXCONST_DBL(0.f); |
535 | 0 | if (drcComp->channelIdx[LS] >= 0) |
536 | 0 | tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), |
537 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >> |
538 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
539 | 0 | if (drcComp->channelIdx[LS2] >= 0) |
540 | 0 | tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), |
541 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >> |
542 | 0 | (DOWNMIX_SHIFT - 1); /* Ls2 */ |
543 | 0 | if (drcComp->channelIdx[RS] >= 0) |
544 | 0 | tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), |
545 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >> |
546 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
547 | 0 | if (drcComp->channelIdx[RS2] >= 0) |
548 | 0 | tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), |
549 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >> |
550 | 0 | (DOWNMIX_SHIFT - 1); /* Rs2 */ |
551 | 0 | if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) |
552 | 0 | tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ |
553 | 0 | if (drcComp->channelIdx[S] >= 0) |
554 | 0 | tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), |
555 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >> |
556 | 0 | (DOWNMIX_SHIFT - 1); /* S */ |
557 | 0 | if (drcComp->channelIdx[C] >= 0) |
558 | 0 | tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), |
559 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> |
560 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
561 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >> |
562 | 0 | 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 | 0 | if (dmxGain2 > FL2FXCONST_DBL(0.f)) { |
568 | 0 | if (drcComp->fullChannels > 5) { |
569 | 0 | tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); |
570 | 0 | } |
571 | 0 | tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); |
572 | 0 | } |
573 | 0 | peak[0] = fixMax(peak[0], fixp_abs(tmp)); |
574 | | |
575 | | /* Rt */ |
576 | 0 | tmp = FL2FXCONST_DBL(0.f); |
577 | 0 | if (drcComp->channelIdx[LS] >= 0) |
578 | 0 | tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), |
579 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >> |
580 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
581 | 0 | if (drcComp->channelIdx[LS2] >= 0) |
582 | 0 | tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), |
583 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >> |
584 | 0 | (DOWNMIX_SHIFT - 1); /* Ls2 */ |
585 | 0 | if (drcComp->channelIdx[RS] >= 0) |
586 | 0 | tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), |
587 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >> |
588 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
589 | 0 | if (drcComp->channelIdx[RS2] >= 0) |
590 | 0 | tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), |
591 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >> |
592 | 0 | (DOWNMIX_SHIFT - 1); /* Rs2 */ |
593 | 0 | if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) |
594 | 0 | tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ |
595 | 0 | if (drcComp->channelIdx[S] >= 0) |
596 | 0 | tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), |
597 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >> |
598 | 0 | (DOWNMIX_SHIFT - 1); /* S */ |
599 | 0 | if (drcComp->channelIdx[C] >= 0) |
600 | 0 | tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), |
601 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> |
602 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
603 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >> |
604 | 0 | 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 | 0 | if (dmxGain2 > FL2FXCONST_DBL(0.f)) { |
610 | 0 | if (drcComp->fullChannels > 5) { |
611 | 0 | tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); |
612 | 0 | } |
613 | 0 | tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); |
614 | 0 | } |
615 | 0 | peak[0] = fixMax(peak[0], fixp_abs(tmp)); |
616 | 0 | } |
617 | | |
618 | | /* Lo/Ro downmix */ |
619 | 0 | for (i = 0; i < drcComp->blockLength; i++) { |
620 | 0 | const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; |
621 | | |
622 | | /* Lo */ |
623 | 0 | tmp = FL2FXCONST_DBL(0.f); |
624 | 0 | switch (drcComp->chanConfig) { |
625 | 0 | case MODE_6_1: |
626 | 0 | tmp += fMultDiv2(fMult(slev, ext_leva), |
627 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> |
628 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
629 | 0 | tmp += fMultDiv2(fMult(slev, ext_levb), |
630 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> |
631 | 0 | (DOWNMIX_SHIFT - 1); /* Cs */ |
632 | 0 | tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> |
633 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
634 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> |
635 | 0 | DOWNMIX_SHIFT); /* L */ |
636 | 0 | tmp += |
637 | 0 | fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
638 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
639 | 0 | break; |
640 | 0 | case MODE_7_1_BACK: |
641 | 0 | case MODE_7_1_REAR_SURROUND: |
642 | 0 | tmp += fMultDiv2(fMult(slev, ext_leva), |
643 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> |
644 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
645 | 0 | tmp += fMultDiv2(fMult(slev, ext_levb), |
646 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> |
647 | 0 | (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/ |
648 | 0 | tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> |
649 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
650 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> |
651 | 0 | DOWNMIX_SHIFT); /* L */ |
652 | 0 | tmp += |
653 | 0 | fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
654 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
655 | 0 | break; |
656 | 0 | case MODE_1_2_2_2_1: |
657 | 0 | case MODE_7_1_FRONT_CENTER: |
658 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> |
659 | 0 | DOWNMIX_SHIFT); /* L */ |
660 | 0 | tmp += |
661 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> |
662 | 0 | (DOWNMIX_SHIFT - 1); /* Lc */ |
663 | 0 | tmp += fMultDiv2(fMult(ext_leva, clev), |
664 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> |
665 | 0 | (DOWNMIX_SHIFT - 1); /* Lc - second path*/ |
666 | 0 | tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> |
667 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
668 | 0 | tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> |
669 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
670 | 0 | tmp += |
671 | 0 | fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
672 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
673 | 0 | break; |
674 | 0 | case MODE_7_1_TOP_FRONT: |
675 | 0 | tmp += |
676 | 0 | fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> |
677 | 0 | (DOWNMIX_SHIFT - 1); /* L */ |
678 | 0 | tmp += |
679 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> |
680 | 0 | (DOWNMIX_SHIFT - 1); /* Lvh */ |
681 | 0 | tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> |
682 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
683 | 0 | tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> |
684 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
685 | 0 | tmp += |
686 | 0 | fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
687 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
688 | 0 | break; |
689 | 0 | default: |
690 | 0 | if (drcComp->channelIdx[LS] >= 0) |
691 | 0 | tmp += |
692 | 0 | fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >> |
693 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
694 | 0 | if (drcComp->channelIdx[LS2] >= 0) |
695 | 0 | tmp += |
696 | 0 | fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >> |
697 | 0 | (DOWNMIX_SHIFT - 1); /* Ls2 */ |
698 | 0 | if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) |
699 | 0 | tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ |
700 | 0 | if (drcComp->channelIdx[S] >= 0) |
701 | 0 | tmp += |
702 | 0 | fMultDiv2(slev, |
703 | 0 | fMult(FL2FXCONST_DBL(0.7f), |
704 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >> |
705 | 0 | (DOWNMIX_SHIFT - 1); /* S */ |
706 | 0 | if (drcComp->channelIdx[C] >= 0) |
707 | 0 | tmp += |
708 | 0 | fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> |
709 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
710 | 0 | if (drcComp->channelIdx[3] >= 0) |
711 | 0 | tmp += fMultDiv2(lfe_lev, |
712 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
713 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
714 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >> |
715 | 0 | DOWNMIX_SHIFT); /* L */ |
716 | 0 | break; |
717 | 0 | } |
718 | | |
719 | | /* apply scaling of downmix gains */ |
720 | | /* only for positive values only, as legacy decoders might not know this |
721 | | * parameter */ |
722 | 0 | if (dmxGain2 > FL2FXCONST_DBL(0.f)) { |
723 | 0 | if (drcComp->fullChannels > 5) { |
724 | 0 | tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); |
725 | 0 | } |
726 | 0 | tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); |
727 | 0 | } |
728 | 0 | peak[0] = fixMax(peak[0], fixp_abs(tmp)); |
729 | | |
730 | | /* Ro */ |
731 | 0 | tmp = FL2FXCONST_DBL(0.f); |
732 | 0 | switch (drcComp->chanConfig) { |
733 | 0 | case MODE_6_1: |
734 | 0 | tmp += fMultDiv2(fMult(slev, ext_leva), |
735 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> |
736 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
737 | 0 | tmp += fMultDiv2(fMult(slev, ext_levb), |
738 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> |
739 | 0 | (DOWNMIX_SHIFT - 1); /* Cs */ |
740 | 0 | tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> |
741 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
742 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> |
743 | 0 | DOWNMIX_SHIFT); /* R */ |
744 | 0 | tmp += |
745 | 0 | fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
746 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
747 | 0 | break; |
748 | 0 | case MODE_7_1_BACK: |
749 | 0 | case MODE_7_1_REAR_SURROUND: |
750 | 0 | tmp += fMultDiv2(fMult(slev, ext_leva), |
751 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> |
752 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
753 | 0 | tmp += fMultDiv2(fMult(slev, ext_levb), |
754 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> |
755 | 0 | (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/ |
756 | 0 | tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> |
757 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
758 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> |
759 | 0 | DOWNMIX_SHIFT); /* R */ |
760 | 0 | tmp += |
761 | 0 | fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
762 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
763 | 0 | break; |
764 | 0 | case MODE_1_2_2_2_1: |
765 | 0 | case MODE_7_1_FRONT_CENTER: |
766 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> |
767 | 0 | DOWNMIX_SHIFT); /* R */ |
768 | 0 | tmp += |
769 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> |
770 | 0 | (DOWNMIX_SHIFT - 1); /* Rc */ |
771 | 0 | tmp += fMultDiv2(fMult(ext_leva, clev), |
772 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> |
773 | 0 | (DOWNMIX_SHIFT - 1); /* Rc - second path*/ |
774 | 0 | tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> |
775 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
776 | 0 | tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> |
777 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
778 | 0 | tmp += |
779 | 0 | fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
780 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
781 | 0 | break; |
782 | 0 | case MODE_7_1_TOP_FRONT: |
783 | 0 | tmp += |
784 | 0 | fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> |
785 | 0 | (DOWNMIX_SHIFT - 1); /* R */ |
786 | 0 | tmp += |
787 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> |
788 | 0 | (DOWNMIX_SHIFT - 1); /* Rvh */ |
789 | 0 | tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> |
790 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
791 | 0 | tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> |
792 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
793 | 0 | tmp += |
794 | 0 | fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
795 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
796 | 0 | break; |
797 | 0 | default: |
798 | 0 | if (drcComp->channelIdx[RS] >= 0) |
799 | 0 | tmp += |
800 | 0 | fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >> |
801 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
802 | 0 | if (drcComp->channelIdx[RS2] >= 0) |
803 | 0 | tmp += |
804 | 0 | fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >> |
805 | 0 | (DOWNMIX_SHIFT - 1); /* Rs2 */ |
806 | 0 | if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) |
807 | 0 | tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ |
808 | 0 | if (drcComp->channelIdx[S] >= 0) |
809 | 0 | tmp += |
810 | 0 | fMultDiv2(slev, |
811 | 0 | fMult(FL2FXCONST_DBL(0.7f), |
812 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >> |
813 | 0 | (DOWNMIX_SHIFT - 1); /* S */ |
814 | 0 | if (drcComp->channelIdx[C] >= 0) |
815 | 0 | tmp += |
816 | 0 | fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> |
817 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
818 | 0 | if (drcComp->channelIdx[3] >= 0) |
819 | 0 | tmp += fMultDiv2(lfe_lev, |
820 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
821 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
822 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >> |
823 | 0 | DOWNMIX_SHIFT); /* R */ |
824 | 0 | } |
825 | | |
826 | | /* apply scaling of downmix gains */ |
827 | | /* only for positive values only, as legacy decoders might not know this |
828 | | * parameter */ |
829 | 0 | if (dmxGain2 > FL2FXCONST_DBL(0.f)) { |
830 | 0 | if (drcComp->fullChannels > 5) { |
831 | 0 | tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); |
832 | 0 | } |
833 | 0 | tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); |
834 | 0 | } |
835 | 0 | peak[0] = fixMax(peak[0], fixp_abs(tmp)); |
836 | 0 | } |
837 | 0 | } |
838 | | |
839 | 0 | peak[1] = fixMax(peak[0], peak[1]); |
840 | | |
841 | | /* Mono Downmix - for comp_val only */ |
842 | 0 | if (drcComp->fullChannels > 1) { |
843 | 0 | for (i = 0; i < drcComp->blockLength; i++) { |
844 | 0 | const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; |
845 | |
|
846 | 0 | tmp = FL2FXCONST_DBL(0.f); |
847 | 0 | switch (drcComp->chanConfig) { |
848 | 0 | case MODE_6_1: |
849 | 0 | tmp += fMultDiv2(fMult(slev, ext_leva), |
850 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> |
851 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
852 | 0 | tmp += fMultDiv2(fMult(slev, ext_leva), |
853 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> |
854 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
855 | 0 | tmp += fMult(fMult(slev, ext_levb), |
856 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> |
857 | 0 | (DOWNMIX_SHIFT - 1); /* Cs */ |
858 | 0 | tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> |
859 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
860 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> |
861 | 0 | DOWNMIX_SHIFT); /* L */ |
862 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> |
863 | 0 | DOWNMIX_SHIFT); /* R */ |
864 | 0 | tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
865 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
866 | 0 | break; |
867 | 0 | case MODE_7_1_BACK: |
868 | 0 | case MODE_7_1_REAR_SURROUND: |
869 | 0 | tmp += fMultDiv2(fMult(slev, ext_leva), |
870 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> |
871 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
872 | 0 | tmp += fMultDiv2(fMult(slev, ext_leva), |
873 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> |
874 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
875 | 0 | tmp += fMultDiv2(fMult(slev, ext_levb), |
876 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> |
877 | 0 | (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/ |
878 | 0 | tmp += fMultDiv2(fMult(slev, ext_levb), |
879 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> |
880 | 0 | (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/ |
881 | 0 | tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> |
882 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
883 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> |
884 | 0 | DOWNMIX_SHIFT); /* L */ |
885 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> |
886 | 0 | DOWNMIX_SHIFT); /* R */ |
887 | 0 | tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
888 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
889 | 0 | break; |
890 | 0 | case MODE_1_2_2_2_1: |
891 | 0 | case MODE_7_1_FRONT_CENTER: |
892 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> |
893 | 0 | DOWNMIX_SHIFT); /* L */ |
894 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> |
895 | 0 | DOWNMIX_SHIFT); /* R */ |
896 | 0 | tmp += |
897 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> |
898 | 0 | (DOWNMIX_SHIFT - 1); /* Lc */ |
899 | 0 | tmp += |
900 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> |
901 | 0 | (DOWNMIX_SHIFT - 1); /* Rc */ |
902 | 0 | tmp += fMultDiv2(fMult(ext_leva, clev), |
903 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> |
904 | 0 | (DOWNMIX_SHIFT - 1); /* Lc - second path*/ |
905 | 0 | tmp += fMultDiv2(fMult(ext_leva, clev), |
906 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> |
907 | 0 | (DOWNMIX_SHIFT - 1); /* Rc - second path*/ |
908 | 0 | tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> |
909 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
910 | 0 | tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> |
911 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
912 | 0 | tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> |
913 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
914 | 0 | tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
915 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
916 | 0 | break; |
917 | 0 | case MODE_7_1_TOP_FRONT: |
918 | 0 | tmp += |
919 | 0 | fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> |
920 | 0 | (DOWNMIX_SHIFT - 1); /* L */ |
921 | 0 | tmp += |
922 | 0 | fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> |
923 | 0 | (DOWNMIX_SHIFT - 1); /* R */ |
924 | 0 | tmp += |
925 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> |
926 | 0 | (DOWNMIX_SHIFT - 1); /* Lvh */ |
927 | 0 | tmp += |
928 | 0 | fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> |
929 | 0 | (DOWNMIX_SHIFT - 1); /* Rvh */ |
930 | 0 | tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> |
931 | 0 | (DOWNMIX_SHIFT - 1); /* C */ |
932 | 0 | tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> |
933 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
934 | 0 | tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> |
935 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
936 | 0 | tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
937 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
938 | 0 | break; |
939 | 0 | default: |
940 | 0 | if (drcComp->channelIdx[LS] >= 0) |
941 | 0 | tmp += |
942 | 0 | fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >> |
943 | 0 | (DOWNMIX_SHIFT - 1); /* Ls */ |
944 | 0 | if (drcComp->channelIdx[LS2] >= 0) |
945 | 0 | tmp += |
946 | 0 | fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >> |
947 | 0 | (DOWNMIX_SHIFT - 1); /* Ls2 */ |
948 | 0 | if (drcComp->channelIdx[RS] >= 0) |
949 | 0 | tmp += |
950 | 0 | fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >> |
951 | 0 | (DOWNMIX_SHIFT - 1); /* Rs */ |
952 | 0 | if (drcComp->channelIdx[RS2] >= 0) |
953 | 0 | tmp += |
954 | 0 | fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >> |
955 | 0 | (DOWNMIX_SHIFT - 1); /* Rs2 */ |
956 | 0 | if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) |
957 | 0 | 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 | 0 | if (drcComp->channelIdx[S] >= 0) |
960 | 0 | tmp += |
961 | 0 | fMultDiv2(slev, |
962 | 0 | fMult(FL2FXCONST_DBL(0.7f), |
963 | 0 | (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >> |
964 | 0 | (DOWNMIX_SHIFT - 1); /* S */ |
965 | 0 | if (drcComp->channelIdx[C] >= 0) |
966 | 0 | tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> |
967 | 0 | (DOWNMIX_SHIFT - 1); /* C (2*clev) */ |
968 | 0 | if (drcComp->channelIdx[3] >= 0) |
969 | 0 | tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> |
970 | 0 | (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ |
971 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >> |
972 | 0 | DOWNMIX_SHIFT); /* L */ |
973 | 0 | tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >> |
974 | 0 | DOWNMIX_SHIFT); /* R */ |
975 | 0 | } |
976 | | |
977 | | /* apply scaling of downmix gains */ |
978 | | /* only for positive values only, as legacy decoders might not know this |
979 | | * parameter */ |
980 | 0 | if (dmxGain2 > FL2FXCONST_DBL(0.f)) { |
981 | 0 | if (drcComp->fullChannels > 5) { |
982 | 0 | tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); |
983 | 0 | } |
984 | 0 | tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); |
985 | 0 | } |
986 | 0 | peak[1] = fixMax(peak[1], fixp_abs(tmp)); |
987 | 0 | } |
988 | 0 | } |
989 | 0 | } |
990 | | |
991 | 0 | INT FDK_DRC_Generator_Open(HDRC_COMP* phDrcComp) { |
992 | 0 | INT err = 0; |
993 | 0 | HDRC_COMP hDcComp = NULL; |
994 | |
|
995 | 0 | if (phDrcComp == NULL) { |
996 | 0 | err = -1; |
997 | 0 | goto bail; |
998 | 0 | } |
999 | | |
1000 | | /* allocate memory */ |
1001 | 0 | hDcComp = (HDRC_COMP)FDKcalloc(1, sizeof(DRC_COMP)); |
1002 | |
|
1003 | 0 | if (hDcComp == NULL) { |
1004 | 0 | err = -1; |
1005 | 0 | goto bail; |
1006 | 0 | } |
1007 | | |
1008 | 0 | FDKmemclear(hDcComp, sizeof(DRC_COMP)); |
1009 | | |
1010 | | /* Return drc compressor instance */ |
1011 | 0 | *phDrcComp = hDcComp; |
1012 | 0 | return err; |
1013 | 0 | bail: |
1014 | 0 | FDK_DRC_Generator_Close(&hDcComp); |
1015 | 0 | return err; |
1016 | 0 | } |
1017 | | |
1018 | 0 | INT FDK_DRC_Generator_Close(HDRC_COMP* phDrcComp) { |
1019 | 0 | if (phDrcComp == NULL) { |
1020 | 0 | return -1; |
1021 | 0 | } |
1022 | 0 | if (*phDrcComp != NULL) { |
1023 | 0 | FDKfree(*phDrcComp); |
1024 | 0 | *phDrcComp = NULL; |
1025 | 0 | } |
1026 | 0 | return 0; |
1027 | 0 | } |
1028 | | |
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 | 0 | const UCHAR useWeighting) { |
1036 | 0 | int i; |
1037 | 0 | CHANNEL_MAPPING channelMapping; |
1038 | |
|
1039 | 0 | drcComp->limDecay = |
1040 | 0 | FL2FXCONST_DBL(((0.006f / 256) * blockLength) / METADATA_INT_SCALE); |
1041 | | |
1042 | | /* Save parameters. */ |
1043 | 0 | drcComp->blockLength = blockLength; |
1044 | 0 | drcComp->sampleRate = sampleRate; |
1045 | 0 | drcComp->chanConfig = channelMode; |
1046 | 0 | drcComp->useWeighting = useWeighting; |
1047 | |
|
1048 | 0 | if (FDK_DRC_Generator_setDrcProfile(drcComp, profileLine, profileRF) != |
1049 | 0 | 0) { /* expects initialized blockLength and sampleRate */ |
1050 | 0 | return (-1); |
1051 | 0 | } |
1052 | | |
1053 | | /* Set number of channels and channel offsets. */ |
1054 | 0 | if (FDKaacEnc_InitChannelMapping(channelMode, channelOrder, |
1055 | 0 | &channelMapping) != AAC_ENC_OK) { |
1056 | 0 | return (-2); |
1057 | 0 | } |
1058 | | |
1059 | 0 | for (i = 0; i < 9; i++) drcComp->channelIdx[i] = -1; |
1060 | |
|
1061 | 0 | switch (channelMode) { |
1062 | 0 | case MODE_1: /* mono */ |
1063 | 0 | drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; |
1064 | 0 | break; |
1065 | 0 | case MODE_2: /* stereo */ |
1066 | 0 | drcComp->channelIdx[L] = channelMapping.elInfo[0].ChannelIndex[0]; |
1067 | 0 | drcComp->channelIdx[R] = channelMapping.elInfo[0].ChannelIndex[1]; |
1068 | 0 | break; |
1069 | 0 | case MODE_1_2: /* 3ch */ |
1070 | 0 | drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; |
1071 | 0 | drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; |
1072 | 0 | drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; |
1073 | 0 | break; |
1074 | 0 | case MODE_1_2_1: /* 4ch */ |
1075 | 0 | drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; |
1076 | 0 | drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; |
1077 | 0 | drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; |
1078 | 0 | drcComp->channelIdx[S] = channelMapping.elInfo[2].ChannelIndex[0]; |
1079 | 0 | break; |
1080 | 0 | case MODE_1_2_2: /* 5ch */ |
1081 | 0 | drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; |
1082 | 0 | drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; |
1083 | 0 | drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; |
1084 | 0 | drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0]; |
1085 | 0 | drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1]; |
1086 | 0 | break; |
1087 | 0 | case MODE_1_2_2_1: /* 5.1 ch */ |
1088 | 0 | drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; |
1089 | 0 | drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; |
1090 | 0 | drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; |
1091 | 0 | drcComp->channelIdx[LFE] = channelMapping.elInfo[3].ChannelIndex[0]; |
1092 | 0 | drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0]; |
1093 | 0 | drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1]; |
1094 | 0 | break; |
1095 | 0 | case MODE_1_2_2_2_1: /* 7.1 ch */ |
1096 | 0 | case MODE_7_1_FRONT_CENTER: |
1097 | 0 | drcComp->channelIdx[L] = channelMapping.elInfo[2].ChannelIndex[0]; /* l */ |
1098 | 0 | drcComp->channelIdx[R] = channelMapping.elInfo[2].ChannelIndex[1]; /* r */ |
1099 | 0 | drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ |
1100 | 0 | drcComp->channelIdx[LFE] = |
1101 | 0 | channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ |
1102 | 0 | drcComp->channelIdx[LS] = |
1103 | 0 | channelMapping.elInfo[3].ChannelIndex[0]; /* ls */ |
1104 | 0 | drcComp->channelIdx[RS] = |
1105 | 0 | channelMapping.elInfo[3].ChannelIndex[1]; /* rs */ |
1106 | 0 | drcComp->channelIdx[LS2] = |
1107 | 0 | channelMapping.elInfo[1].ChannelIndex[0]; /* lc */ |
1108 | 0 | drcComp->channelIdx[RS2] = |
1109 | 0 | channelMapping.elInfo[1].ChannelIndex[1]; /* rc */ |
1110 | 0 | break; |
1111 | 0 | case MODE_7_1_BACK: |
1112 | 0 | case MODE_7_1_REAR_SURROUND: |
1113 | 0 | drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */ |
1114 | 0 | drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */ |
1115 | 0 | drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ |
1116 | 0 | drcComp->channelIdx[LFE] = |
1117 | 0 | channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ |
1118 | 0 | drcComp->channelIdx[LS] = |
1119 | 0 | channelMapping.elInfo[3].ChannelIndex[0]; /* lrear */ |
1120 | 0 | drcComp->channelIdx[RS] = |
1121 | 0 | channelMapping.elInfo[3].ChannelIndex[1]; /* rrear */ |
1122 | 0 | drcComp->channelIdx[LS2] = |
1123 | 0 | channelMapping.elInfo[2].ChannelIndex[0]; /* ls */ |
1124 | 0 | drcComp->channelIdx[RS2] = |
1125 | 0 | channelMapping.elInfo[2].ChannelIndex[1]; /* rs */ |
1126 | 0 | break; |
1127 | 0 | case MODE_6_1: |
1128 | 0 | drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */ |
1129 | 0 | drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */ |
1130 | 0 | drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ |
1131 | 0 | drcComp->channelIdx[LFE] = |
1132 | 0 | channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ |
1133 | 0 | drcComp->channelIdx[LS] = |
1134 | 0 | channelMapping.elInfo[2].ChannelIndex[0]; /* ls */ |
1135 | 0 | drcComp->channelIdx[RS] = |
1136 | 0 | channelMapping.elInfo[2].ChannelIndex[1]; /* rs */ |
1137 | 0 | drcComp->channelIdx[S] = channelMapping.elInfo[3].ChannelIndex[0]; /* s */ |
1138 | 0 | break; |
1139 | 0 | case MODE_7_1_TOP_FRONT: |
1140 | 0 | drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */ |
1141 | 0 | drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */ |
1142 | 0 | drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ |
1143 | 0 | drcComp->channelIdx[LFE] = |
1144 | 0 | channelMapping.elInfo[3].ChannelIndex[0]; /* lfe */ |
1145 | 0 | drcComp->channelIdx[LS] = |
1146 | 0 | channelMapping.elInfo[2].ChannelIndex[0]; /* ls */ |
1147 | 0 | drcComp->channelIdx[RS] = |
1148 | 0 | channelMapping.elInfo[2].ChannelIndex[1]; /* rs */ |
1149 | 0 | drcComp->channelIdx[LS2] = |
1150 | 0 | channelMapping.elInfo[4].ChannelIndex[0]; /* lvh2 */ |
1151 | 0 | drcComp->channelIdx[RS2] = |
1152 | 0 | channelMapping.elInfo[4].ChannelIndex[1]; /* rvh2 */ |
1153 | 0 | break; |
1154 | 0 | default: |
1155 | 0 | return (-1); |
1156 | 0 | } |
1157 | | |
1158 | 0 | drcComp->fullChannels = channelMapping.nChannelsEff; |
1159 | 0 | drcComp->channels = channelMapping.nChannels; |
1160 | | |
1161 | | /* Init states. */ |
1162 | 0 | drcComp->smoothLevel[0] = drcComp->smoothLevel[1] = |
1163 | 0 | (FIXP_DBL)(-(135 << METADATA_FRACT_BITS)); |
1164 | |
|
1165 | 0 | FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain)); |
1166 | 0 | FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt)); |
1167 | 0 | FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain)); |
1168 | 0 | FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak)); |
1169 | 0 | FDKmemclear(drcComp->filter, sizeof(drcComp->filter)); |
1170 | |
|
1171 | 0 | return (0); |
1172 | 0 | } |
1173 | | |
1174 | | INT FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp, |
1175 | | const DRC_PROFILE profileLine, |
1176 | 0 | const DRC_PROFILE profileRF) { |
1177 | 0 | int profileIdx, i; |
1178 | |
|
1179 | 0 | drcComp->profile[0] = profileLine; |
1180 | 0 | drcComp->profile[1] = profileRF; |
1181 | |
|
1182 | 0 | for (i = 0; i < 2; i++) { |
1183 | | /* get profile index */ |
1184 | 0 | switch (drcComp->profile[i]) { |
1185 | 0 | case DRC_NONE: |
1186 | 0 | case DRC_NOT_PRESENT: |
1187 | 0 | case DRC_FILMSTANDARD: |
1188 | 0 | profileIdx = 0; |
1189 | 0 | break; |
1190 | 0 | case DRC_FILMLIGHT: |
1191 | 0 | profileIdx = 1; |
1192 | 0 | break; |
1193 | 0 | case DRC_MUSICSTANDARD: |
1194 | 0 | profileIdx = 2; |
1195 | 0 | break; |
1196 | 0 | case DRC_MUSICLIGHT: |
1197 | 0 | profileIdx = 3; |
1198 | 0 | break; |
1199 | 0 | case DRC_SPEECH: |
1200 | 0 | profileIdx = 4; |
1201 | 0 | break; |
1202 | 0 | case DRC_DELAY_TEST: |
1203 | 0 | profileIdx = 5; |
1204 | 0 | break; |
1205 | 0 | default: |
1206 | 0 | return (-1); |
1207 | 0 | } |
1208 | | |
1209 | | /* get parameters for selected profile */ |
1210 | 0 | if (profileIdx >= 0) { |
1211 | 0 | drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx]; |
1212 | 0 | drcComp->boostThr[i] = tabBoostThr[profileIdx]; |
1213 | 0 | drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx]; |
1214 | 0 | drcComp->cutThr[i] = tabCutThr[profileIdx]; |
1215 | 0 | drcComp->maxCutThr[i] = tabMaxCutThr[profileIdx]; |
1216 | |
|
1217 | 0 | drcComp->boostFac[i] = tabBoostRatio[profileIdx]; |
1218 | 0 | drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx]; |
1219 | 0 | drcComp->cutFac[i] = tabCutRatio[profileIdx]; |
1220 | |
|
1221 | 0 | drcComp->maxBoost[i] = tabMaxBoost[profileIdx]; |
1222 | 0 | drcComp->maxCut[i] = tabMaxCut[profileIdx]; |
1223 | 0 | drcComp->maxEarlyCut[i] = |
1224 | 0 | -fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]), |
1225 | 0 | drcComp->earlyCutFac[i]); /* no scaling after mult needed, |
1226 | | earlyCutFac is in FIXP_DBL */ |
1227 | |
|
1228 | 0 | drcComp->fastAttack[i] = tc2Coeff( |
1229 | 0 | tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); |
1230 | 0 | drcComp->fastDecay[i] = tc2Coeff( |
1231 | 0 | tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); |
1232 | 0 | drcComp->slowAttack[i] = tc2Coeff( |
1233 | 0 | tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); |
1234 | 0 | drcComp->slowDecay[i] = tc2Coeff( |
1235 | 0 | tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); |
1236 | 0 | drcComp->holdOff[i] = tabHoldOff[profileIdx] * 256 / drcComp->blockLength; |
1237 | |
|
1238 | 0 | drcComp->attackThr[i] = tabAttackThr[profileIdx]; |
1239 | 0 | drcComp->decayThr[i] = tabDecayThr[profileIdx]; |
1240 | 0 | } |
1241 | |
|
1242 | 0 | drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); |
1243 | 0 | } |
1244 | 0 | return (0); |
1245 | 0 | } |
1246 | | |
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 | 0 | INT* const pDynrng, INT* const pCompr) { |
1255 | 0 | int i, c; |
1256 | 0 | FIXP_DBL peak[2]; |
1257 | | |
1258 | | /************************************************************************** |
1259 | | * compressor |
1260 | | **************************************************************************/ |
1261 | 0 | if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) { |
1262 | | /* Calc loudness level */ |
1263 | 0 | FIXP_DBL level_b = FL2FXCONST_DBL(0.f); |
1264 | 0 | int level_e = DFRACT_BITS - 1; |
1265 | | |
1266 | | /* Increase energy time resolution with shorter processing blocks. 16 is an |
1267 | | * empiric value. */ |
1268 | 0 | const int granuleLength = fixMin(16, drcComp->blockLength); |
1269 | |
|
1270 | 0 | if (drcComp->useWeighting) { |
1271 | 0 | 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 | 0 | const int granuleShift = getShiftFactor(granuleLength) - 1; |
1277 | |
|
1278 | 0 | for (c = 0; c < (int)drcComp->channels; c++) { |
1279 | 0 | const INT_PCM* pSamples = inSamples + c * inSamplesBufSize; |
1280 | |
|
1281 | 0 | if (c == drcComp->channelIdx[LFE]) { |
1282 | 0 | continue; /* skip LFE */ |
1283 | 0 | } |
1284 | | |
1285 | | /* get filter states */ |
1286 | 0 | x1 = drcComp->filter[c].x1; |
1287 | 0 | x2 = drcComp->filter[c].x2; |
1288 | 0 | y1 = drcComp->filter[c].y1; |
1289 | 0 | y2 = drcComp->filter[c].y2; |
1290 | |
|
1291 | 0 | i = 0; |
1292 | |
|
1293 | 0 | do { |
1294 | 0 | int offset = i; |
1295 | 0 | FIXP_DBL accu = FL2FXCONST_DBL(0.f); |
1296 | |
|
1297 | 0 | for (i = offset; |
1298 | 0 | i < fixMin(offset + granuleLength, drcComp->blockLength); i++) { |
1299 | | /* apply weighting filter */ |
1300 | 0 | FIXP_DBL x = |
1301 | 0 | FX_PCM2FX_DBL((FIXP_PCM)pSamples[i]) >> WEIGHTING_FILTER_SHIFT; |
1302 | | |
1303 | | /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */ |
1304 | 0 | y = fMult(b0, x - x2) - fMult(a1, y1) - fMult(a2, y2); |
1305 | |
|
1306 | 0 | x2 = x1; |
1307 | 0 | x1 = x; |
1308 | 0 | y2 = y1; |
1309 | 0 | y1 = y; |
1310 | |
|
1311 | 0 | accu += fPow2Div2(y) >> (granuleShift - 1); /* partial energy */ |
1312 | 0 | } /* i */ |
1313 | |
|
1314 | 0 | fixpAdd(accu, granuleShift + 2 * WEIGHTING_FILTER_SHIFT, &level_b, |
1315 | 0 | &level_e); /* sup up partial energies */ |
1316 | |
|
1317 | 0 | } while (i < drcComp->blockLength); |
1318 | | |
1319 | | /* save filter states */ |
1320 | 0 | drcComp->filter[c].x1 = x1; |
1321 | 0 | drcComp->filter[c].x2 = x2; |
1322 | 0 | drcComp->filter[c].y1 = y1; |
1323 | 0 | drcComp->filter[c].y2 = y2; |
1324 | 0 | } /* c */ |
1325 | 0 | } /* weighting */ |
1326 | 0 | else { |
1327 | 0 | const int granuleShift = getShiftFactor(granuleLength); |
1328 | |
|
1329 | 0 | for (c = 0; c < (int)drcComp->channels; c++) { |
1330 | 0 | const INT_PCM* pSamples = inSamples + c * inSamplesBufSize; |
1331 | |
|
1332 | 0 | if ((int)c == drcComp->channelIdx[LFE]) { |
1333 | 0 | continue; /* skip LFE */ |
1334 | 0 | } |
1335 | | |
1336 | 0 | i = 0; |
1337 | |
|
1338 | 0 | do { |
1339 | 0 | int offset = i; |
1340 | 0 | FIXP_DBL accu = FL2FXCONST_DBL(0.f); |
1341 | |
|
1342 | 0 | for (i = offset; |
1343 | 0 | i < fixMin(offset + granuleLength, drcComp->blockLength); i++) { |
1344 | | /* partial energy */ |
1345 | 0 | accu += fPow2Div2((FIXP_PCM)pSamples[i]) >> (granuleShift - 1); |
1346 | 0 | } /* i */ |
1347 | |
|
1348 | 0 | fixpAdd(accu, granuleShift, &level_b, |
1349 | 0 | &level_e); /* sup up partial energies */ |
1350 | |
|
1351 | 0 | } while (i < drcComp->blockLength); |
1352 | 0 | } |
1353 | 0 | } /* weighting */ |
1354 | | |
1355 | | /* |
1356 | | * Convert to dBFS, apply dialnorm |
1357 | | */ |
1358 | | /* level scaling */ |
1359 | | |
1360 | | /* descaled level in ld64 representation */ |
1361 | 0 | FIXP_DBL ldLevel = |
1362 | 0 | CalcLdData(level_b) + |
1363 | 0 | (FIXP_DBL)((level_e - 12) << (DFRACT_BITS - 1 - LD_DATA_SHIFT)) - |
1364 | 0 | CalcLdData((FIXP_DBL)(drcComp->blockLength << (DFRACT_BITS - 1 - 12))); |
1365 | | |
1366 | | /* if (level < 1e-10) level = 1e-10f; */ |
1367 | 0 | ldLevel = |
1368 | 0 | 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 | 0 | FIXP_DBL level = fMult( |
1385 | 0 | (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)), |
1386 | 0 | fMult(FL2FXCONST_DBL(0.30102999566398119521373889472449f), ldLevel) + |
1387 | 0 | (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 | 0 | level -= ((FIXP_DBL)(dialnorm << (METADATA_FRACT_BITS - 16)) + |
1393 | 0 | (FIXP_DBL)(31 << METADATA_FRACT_BITS)); |
1394 | |
|
1395 | 0 | for (i = 0; i < 2; i++) { |
1396 | 0 | if (drcComp->profile[i] == DRC_NONE) { |
1397 | | /* no compression */ |
1398 | 0 | drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); |
1399 | 0 | } else { |
1400 | 0 | FIXP_DBL gain, alpha, lvl2smthlvl; |
1401 | | |
1402 | | /* calc static gain */ |
1403 | 0 | if (level <= drcComp->maxBoostThr[i]) { |
1404 | | /* max boost */ |
1405 | 0 | gain = drcComp->maxBoost[i]; |
1406 | 0 | } else if (level < drcComp->boostThr[i]) { |
1407 | | /* boost range */ |
1408 | 0 | gain = fMult((level - drcComp->boostThr[i]), drcComp->boostFac[i]); |
1409 | 0 | } else if (level <= drcComp->earlyCutThr[i]) { |
1410 | | /* null band */ |
1411 | 0 | gain = FL2FXCONST_DBL(0.f); |
1412 | 0 | } else if (level <= drcComp->cutThr[i]) { |
1413 | | /* early cut range */ |
1414 | 0 | gain = |
1415 | 0 | fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); |
1416 | 0 | } else if (level < drcComp->maxCutThr[i]) { |
1417 | | /* cut range */ |
1418 | 0 | gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) - |
1419 | 0 | drcComp->maxEarlyCut[i]; |
1420 | 0 | } else { |
1421 | | /* max cut */ |
1422 | 0 | gain = -drcComp->maxCut[i]; |
1423 | 0 | } |
1424 | | |
1425 | | /* choose time constant */ |
1426 | 0 | lvl2smthlvl = level - drcComp->smoothLevel[i]; |
1427 | 0 | if (gain < drcComp->smoothGain[i]) { |
1428 | | /* attack */ |
1429 | 0 | if (lvl2smthlvl > drcComp->attackThr[i]) { |
1430 | | /* fast attack */ |
1431 | 0 | alpha = drcComp->fastAttack[i]; |
1432 | 0 | } else { |
1433 | | /* slow attack */ |
1434 | 0 | alpha = drcComp->slowAttack[i]; |
1435 | 0 | } |
1436 | 0 | } else { |
1437 | | /* release */ |
1438 | 0 | if (lvl2smthlvl < -drcComp->decayThr[i]) { |
1439 | | /* fast release */ |
1440 | 0 | alpha = drcComp->fastDecay[i]; |
1441 | 0 | } else { |
1442 | | /* slow release */ |
1443 | 0 | alpha = drcComp->slowDecay[i]; |
1444 | 0 | } |
1445 | 0 | } |
1446 | | |
1447 | | /* smooth gain & level */ |
1448 | 0 | if ((gain < drcComp->smoothGain[i]) || |
1449 | 0 | (drcComp->holdCnt[i] == |
1450 | 0 | 0)) { /* hold gain unless we have an attack or hold |
1451 | | period is over */ |
1452 | 0 | FIXP_DBL accu; |
1453 | | |
1454 | | /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] + |
1455 | | * alpha * level; */ |
1456 | 0 | accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothLevel[i]); |
1457 | 0 | accu += fMult(alpha, level); |
1458 | 0 | drcComp->smoothLevel[i] = accu; |
1459 | | |
1460 | | /* drcComp->smoothGain[i] = (1-alpha) * drcComp->smoothGain[i] + |
1461 | | * alpha * gain; */ |
1462 | 0 | accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothGain[i]); |
1463 | 0 | accu += fMult(alpha, gain); |
1464 | 0 | drcComp->smoothGain[i] = accu; |
1465 | 0 | } |
1466 | | |
1467 | | /* hold counter */ |
1468 | 0 | if (drcComp->holdCnt[i]) { |
1469 | 0 | drcComp->holdCnt[i]--; |
1470 | 0 | } |
1471 | 0 | if (gain < drcComp->smoothGain[i]) { |
1472 | 0 | drcComp->holdCnt[i] = drcComp->holdOff[i]; |
1473 | 0 | } |
1474 | 0 | } /* profile != DRC_NONE */ |
1475 | 0 | } /* for i=1..2 */ |
1476 | 0 | } else { |
1477 | | /* no compression */ |
1478 | 0 | drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f); |
1479 | 0 | drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f); |
1480 | 0 | } |
1481 | | |
1482 | | /************************************************************************** |
1483 | | * limiter |
1484 | | **************************************************************************/ |
1485 | |
|
1486 | 0 | findPeakLevels(drcComp, inSamples, clev, slev, ext_leva, ext_levb, lfe_lev, |
1487 | 0 | (FIXP_DBL)((LONG)(dmxGain5) << (METADATA_FRACT_BITS - 16)), |
1488 | 0 | (FIXP_DBL)((LONG)(dmxGain2) << (METADATA_FRACT_BITS - 16)), |
1489 | 0 | peak); |
1490 | |
|
1491 | 0 | for (i = 0; i < 2; i++) { |
1492 | 0 | FIXP_DBL tmp = drcComp->prevPeak[i]; |
1493 | 0 | drcComp->prevPeak[i] = peak[i]; |
1494 | 0 | peak[i] = fixMax(peak[i], tmp); |
1495 | | |
1496 | | /* |
1497 | | * Convert to dBFS, apply dialnorm |
1498 | | */ |
1499 | | /* descaled peak in ld64 representation */ |
1500 | 0 | FIXP_DBL ld_peak = |
1501 | 0 | CalcLdData(peak[i]) + |
1502 | 0 | (FIXP_DBL)((LONG)DOWNMIX_SHIFT << (DFRACT_BITS - 1 - LD_DATA_SHIFT)); |
1503 | | |
1504 | | /* if (peak < 1e-6) level = 1e-6f; */ |
1505 | 0 | ld_peak = |
1506 | 0 | 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 | 0 | peak[i] = fMult( |
1524 | 0 | (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)), |
1525 | 0 | fMult(FL2FX_DBL(2 * 0.30102999566398119521373889472449f), ld_peak)); |
1526 | 0 | peak[i] += |
1527 | 0 | (FL2FX_DBL(0.5f) >> METADATA_INT_BITS); /* add a little bit headroom */ |
1528 | 0 | peak[i] += drcComp->smoothGain[i]; |
1529 | 0 | } |
1530 | | |
1531 | | /* peak -= dialnorm + 31; */ /* this is Dolby style only */ |
1532 | 0 | peak[0] -= (FIXP_DBL)((dialnorm - drc_TargetRefLevel) |
1533 | 0 | << (METADATA_FRACT_BITS - |
1534 | 0 | 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 | 0 | peak[1] -= |
1540 | 0 | (FIXP_DBL)((dialnorm - comp_TargetRefLevel) |
1541 | 0 | << (METADATA_FRACT_BITS - |
1542 | 0 | 16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */ |
1543 | | |
1544 | | /* limiter gain */ |
1545 | 0 | drcComp->limGain[0] += drcComp->limDecay; /* linear limiter release */ |
1546 | 0 | drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]); |
1547 | |
|
1548 | 0 | drcComp->limGain[1] += 2 * drcComp->limDecay; /* linear limiter release */ |
1549 | 0 | drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]); |
1550 | | |
1551 | | /*************************************************************************/ |
1552 | | |
1553 | | /* apply limiting, return DRC gains*/ |
1554 | 0 | { |
1555 | 0 | FIXP_DBL tmp; |
1556 | |
|
1557 | 0 | tmp = drcComp->smoothGain[0]; |
1558 | 0 | if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) { |
1559 | 0 | tmp += drcComp->limGain[0]; |
1560 | 0 | } |
1561 | 0 | *pDynrng = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16)); |
1562 | |
|
1563 | 0 | tmp = drcComp->smoothGain[1]; |
1564 | 0 | if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) { |
1565 | 0 | tmp += drcComp->limGain[1]; |
1566 | 0 | } |
1567 | 0 | *pCompr = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16)); |
1568 | 0 | } |
1569 | |
|
1570 | 0 | return 0; |
1571 | 0 | } |
1572 | | |
1573 | 0 | DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp) { |
1574 | 0 | return drcComp->profile[0]; |
1575 | 0 | } |
1576 | | |
1577 | 0 | DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp) { |
1578 | 0 | return drcComp->profile[1]; |
1579 | 0 | } |