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