xref: /aosp_15_r20/external/aac/libDRCdec/src/drcDec_selectionProcess.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 - 2019 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 /************************* MPEG-D DRC decoder library **************************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):   Andreas Hoelzer
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: DRC Set Selection
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "drcDec_selectionProcess.h"
104*e5436536SAndroid Build Coastguard Worker #include "drcDec_tools.h"
105*e5436536SAndroid Build Coastguard Worker 
106*e5436536SAndroid Build Coastguard Worker typedef enum {
107*e5436536SAndroid Build Coastguard Worker   DETR_NONE = 0,
108*e5436536SAndroid Build Coastguard Worker   DETR_NIGHT = 1,
109*e5436536SAndroid Build Coastguard Worker   DETR_NOISY = 2,
110*e5436536SAndroid Build Coastguard Worker   DETR_LIMITED = 3,
111*e5436536SAndroid Build Coastguard Worker   DETR_LOWLEVEL = 4,
112*e5436536SAndroid Build Coastguard Worker   DETR_DIALOG = 5,
113*e5436536SAndroid Build Coastguard Worker   DETR_GENERAL_COMPR = 6,
114*e5436536SAndroid Build Coastguard Worker   DETR_EXPAND = 7,
115*e5436536SAndroid Build Coastguard Worker   DETR_ARTISTIC = 8,
116*e5436536SAndroid Build Coastguard Worker   DETR_COUNT
117*e5436536SAndroid Build Coastguard Worker } DRC_EFFECT_TYPE_REQUEST;
118*e5436536SAndroid Build Coastguard Worker 
119*e5436536SAndroid Build Coastguard Worker typedef enum {
120*e5436536SAndroid Build Coastguard Worker   DFRT_EFFECT_TYPE,
121*e5436536SAndroid Build Coastguard Worker   DFRT_DYNAMIC_RANGE,
122*e5436536SAndroid Build Coastguard Worker   DFRT_DRC_CHARACTERISTIC
123*e5436536SAndroid Build Coastguard Worker } DRC_FEATURE_REQUEST_TYPE;
124*e5436536SAndroid Build Coastguard Worker 
125*e5436536SAndroid Build Coastguard Worker typedef enum {
126*e5436536SAndroid Build Coastguard Worker   MDR_DEFAULT = 0,
127*e5436536SAndroid Build Coastguard Worker   MDR_PROGRAM_LOUDNESS = 1,
128*e5436536SAndroid Build Coastguard Worker   MDR_ANCHOR_LOUDNESS = 2
129*e5436536SAndroid Build Coastguard Worker } METHOD_DEFINITION_REQUEST;
130*e5436536SAndroid Build Coastguard Worker 
131*e5436536SAndroid Build Coastguard Worker typedef enum {
132*e5436536SAndroid Build Coastguard Worker   MSR_DEFAULT = 0,
133*e5436536SAndroid Build Coastguard Worker   MSR_BS_1770_4 = 1,
134*e5436536SAndroid Build Coastguard Worker   MSR_USER = 2,
135*e5436536SAndroid Build Coastguard Worker   MSR_EXPERT_PANEL = 3,
136*e5436536SAndroid Build Coastguard Worker   MSR_RESERVED_A = 4,
137*e5436536SAndroid Build Coastguard Worker   MSR_RESERVED_B = 5,
138*e5436536SAndroid Build Coastguard Worker   MSR_RESERVED_C = 6,
139*e5436536SAndroid Build Coastguard Worker   MSR_RESERVED_D = 7,
140*e5436536SAndroid Build Coastguard Worker   MSR_RESERVED_E = 8
141*e5436536SAndroid Build Coastguard Worker } MEASUREMENT_SYSTEM_REQUEST;
142*e5436536SAndroid Build Coastguard Worker 
143*e5436536SAndroid Build Coastguard Worker typedef enum {
144*e5436536SAndroid Build Coastguard Worker   LPR_DEFAULT = 0,
145*e5436536SAndroid Build Coastguard Worker   LPR_OFF = 1,
146*e5436536SAndroid Build Coastguard Worker   LPR_HIGHPASS = 2
147*e5436536SAndroid Build Coastguard Worker } LOUDNESS_PREPROCESSING_REQUEST;
148*e5436536SAndroid Build Coastguard Worker 
149*e5436536SAndroid Build Coastguard Worker typedef enum {
150*e5436536SAndroid Build Coastguard Worker   DRMRT_SHORT_TERM_LOUDNESS_TO_AVG = 0,
151*e5436536SAndroid Build Coastguard Worker   DRMRT_MOMENTARY_LOUDNESS_TO_AVG = 1,
152*e5436536SAndroid Build Coastguard Worker   DRMRT_TOP_OF_LOUDNESS_RANGE_TO_AVG = 2
153*e5436536SAndroid Build Coastguard Worker } DYN_RANGE_MEASUREMENT_REQUEST_TYPE;
154*e5436536SAndroid Build Coastguard Worker 
155*e5436536SAndroid Build Coastguard Worker typedef enum {
156*e5436536SAndroid Build Coastguard Worker   TCRT_DOWNMIX_ID = 0,
157*e5436536SAndroid Build Coastguard Worker   TCRT_TARGET_LAYOUT = 1,
158*e5436536SAndroid Build Coastguard Worker   TCRT_TARGET_CHANNEL_COUNT = 2
159*e5436536SAndroid Build Coastguard Worker } TARGET_CONFIG_REQUEST_TYPE;
160*e5436536SAndroid Build Coastguard Worker 
161*e5436536SAndroid Build Coastguard Worker typedef shouldBeUnion {
162*e5436536SAndroid Build Coastguard Worker   struct {
163*e5436536SAndroid Build Coastguard Worker     UCHAR numRequests;
164*e5436536SAndroid Build Coastguard Worker     UCHAR numRequestsDesired;
165*e5436536SAndroid Build Coastguard Worker     DRC_EFFECT_TYPE_REQUEST request[MAX_REQUESTS_DRC_EFFECT_TYPE];
166*e5436536SAndroid Build Coastguard Worker   } drcEffectType;
167*e5436536SAndroid Build Coastguard Worker   struct {
168*e5436536SAndroid Build Coastguard Worker     DYN_RANGE_MEASUREMENT_REQUEST_TYPE measurementRequestType;
169*e5436536SAndroid Build Coastguard Worker     UCHAR requestedIsRange;
170*e5436536SAndroid Build Coastguard Worker     FIXP_DBL requestValue;    /* e = 7 */
171*e5436536SAndroid Build Coastguard Worker     FIXP_DBL requestValueMin; /* e = 7 */
172*e5436536SAndroid Build Coastguard Worker     FIXP_DBL requestValueMax; /* e = 7 */
173*e5436536SAndroid Build Coastguard Worker   } dynamicRange;
174*e5436536SAndroid Build Coastguard Worker   UCHAR drcCharacteristic;
175*e5436536SAndroid Build Coastguard Worker }
176*e5436536SAndroid Build Coastguard Worker DRC_FEATURE_REQUEST;
177*e5436536SAndroid Build Coastguard Worker 
178*e5436536SAndroid Build Coastguard Worker typedef struct {
179*e5436536SAndroid Build Coastguard Worker   /* system parameters */
180*e5436536SAndroid Build Coastguard Worker   SCHAR baseChannelCount;
181*e5436536SAndroid Build Coastguard Worker   SCHAR baseLayout; /* not supported */
182*e5436536SAndroid Build Coastguard Worker   TARGET_CONFIG_REQUEST_TYPE targetConfigRequestType;
183*e5436536SAndroid Build Coastguard Worker   UCHAR numDownmixIdRequests;
184*e5436536SAndroid Build Coastguard Worker   UCHAR downmixIdRequested[MAX_REQUESTS_DOWNMIX_ID];
185*e5436536SAndroid Build Coastguard Worker   UCHAR targetLayoutRequested;
186*e5436536SAndroid Build Coastguard Worker   UCHAR targetChannelCountRequested;
187*e5436536SAndroid Build Coastguard Worker   LONG audioSampleRate; /* needed for complexity estimation, currently not
188*e5436536SAndroid Build Coastguard Worker                            supported */
189*e5436536SAndroid Build Coastguard Worker 
190*e5436536SAndroid Build Coastguard Worker   /* loudness normalization parameters */
191*e5436536SAndroid Build Coastguard Worker   UCHAR loudnessNormalizationOn;
192*e5436536SAndroid Build Coastguard Worker   FIXP_DBL targetLoudness; /* e = 7 */
193*e5436536SAndroid Build Coastguard Worker   UCHAR albumMode;
194*e5436536SAndroid Build Coastguard Worker   UCHAR peakLimiterPresent;
195*e5436536SAndroid Build Coastguard Worker   UCHAR loudnessDeviationMax; /* resolution: 1 dB */
196*e5436536SAndroid Build Coastguard Worker   METHOD_DEFINITION_REQUEST loudnessMeasurementMethod;
197*e5436536SAndroid Build Coastguard Worker   MEASUREMENT_SYSTEM_REQUEST loudnessMeasurementSystem;
198*e5436536SAndroid Build Coastguard Worker   LOUDNESS_PREPROCESSING_REQUEST loudnessMeasurementPreProc; /* not supported */
199*e5436536SAndroid Build Coastguard Worker   LONG deviceCutOffFrequency;                                /* not supported */
200*e5436536SAndroid Build Coastguard Worker   FIXP_DBL loudnessNormalizationGainDbMax;                   /* e = 7 */
201*e5436536SAndroid Build Coastguard Worker   FIXP_DBL loudnessNormalizationGainModificationDb;          /* e = 7 */
202*e5436536SAndroid Build Coastguard Worker   FIXP_DBL outputPeakLevelMax;                               /* e = 7 */
203*e5436536SAndroid Build Coastguard Worker 
204*e5436536SAndroid Build Coastguard Worker   /* dynamic range control parameters */
205*e5436536SAndroid Build Coastguard Worker   UCHAR dynamicRangeControlOn;
206*e5436536SAndroid Build Coastguard Worker   UCHAR numDrcFeatureRequests;
207*e5436536SAndroid Build Coastguard Worker   DRC_FEATURE_REQUEST_TYPE drcFeatureRequestType[MAX_REQUESTS_DRC_FEATURE];
208*e5436536SAndroid Build Coastguard Worker   DRC_FEATURE_REQUEST drcFeatureRequest[MAX_REQUESTS_DRC_FEATURE];
209*e5436536SAndroid Build Coastguard Worker 
210*e5436536SAndroid Build Coastguard Worker   /* other */
211*e5436536SAndroid Build Coastguard Worker   FIXP_SGL boost;                /* e = 1 */
212*e5436536SAndroid Build Coastguard Worker   FIXP_SGL compress;             /* e = 1 */
213*e5436536SAndroid Build Coastguard Worker   UCHAR drcCharacteristicTarget; /* not supported */
214*e5436536SAndroid Build Coastguard Worker } SEL_PROC_INPUT, *HANDLE_SEL_PROC_INPUT;
215*e5436536SAndroid Build Coastguard Worker 
216*e5436536SAndroid Build Coastguard Worker /* Table E.1 of ISO/IEC DIS 23003-4: Recommended order of fallback effect type
217*e5436536SAndroid Build Coastguard Worker  * requests */
218*e5436536SAndroid Build Coastguard Worker static DRC_EFFECT_TYPE_REQUEST fallbackEffectTypeRequests[6][5] = {
219*e5436536SAndroid Build Coastguard Worker     /* Night */ {DETR_GENERAL_COMPR, DETR_NOISY, DETR_LIMITED, DETR_LOWLEVEL,
220*e5436536SAndroid Build Coastguard Worker                  DETR_DIALOG},
221*e5436536SAndroid Build Coastguard Worker     /* Noisy */
222*e5436536SAndroid Build Coastguard Worker     {DETR_GENERAL_COMPR, DETR_NIGHT, DETR_LIMITED, DETR_LOWLEVEL, DETR_DIALOG},
223*e5436536SAndroid Build Coastguard Worker     /* Limited */
224*e5436536SAndroid Build Coastguard Worker     {DETR_GENERAL_COMPR, DETR_NIGHT, DETR_NOISY, DETR_LOWLEVEL, DETR_DIALOG},
225*e5436536SAndroid Build Coastguard Worker     /* LowLevel */
226*e5436536SAndroid Build Coastguard Worker     {DETR_GENERAL_COMPR, DETR_NOISY, DETR_NIGHT, DETR_LIMITED, DETR_DIALOG},
227*e5436536SAndroid Build Coastguard Worker     /* Dialog */
228*e5436536SAndroid Build Coastguard Worker     {DETR_GENERAL_COMPR, DETR_NIGHT, DETR_NOISY, DETR_LIMITED, DETR_LOWLEVEL},
229*e5436536SAndroid Build Coastguard Worker     /* General */
230*e5436536SAndroid Build Coastguard Worker     {DETR_NIGHT, DETR_NOISY, DETR_LIMITED, DETR_LOWLEVEL, DETR_DIALOG}};
231*e5436536SAndroid Build Coastguard Worker 
232*e5436536SAndroid Build Coastguard Worker /*******************************************/
233*e5436536SAndroid Build Coastguard Worker typedef struct {
234*e5436536SAndroid Build Coastguard Worker   UCHAR selectionFlag;
235*e5436536SAndroid Build Coastguard Worker   UCHAR downmixIdRequestIndex;
236*e5436536SAndroid Build Coastguard Worker   FIXP_DBL outputPeakLevel;                     /* e = 7 */
237*e5436536SAndroid Build Coastguard Worker   FIXP_DBL loudnessNormalizationGainDbAdjusted; /* e = 7 */
238*e5436536SAndroid Build Coastguard Worker   FIXP_DBL outputLoudness;                      /* e = 7 */
239*e5436536SAndroid Build Coastguard Worker   DRC_INSTRUCTIONS_UNI_DRC* pInst;
240*e5436536SAndroid Build Coastguard Worker 
241*e5436536SAndroid Build Coastguard Worker } DRCDEC_SELECTION_DATA;
242*e5436536SAndroid Build Coastguard Worker 
243*e5436536SAndroid Build Coastguard Worker typedef struct {
244*e5436536SAndroid Build Coastguard Worker   UCHAR numData;
245*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_DATA data[(12 + 1 + 6)];
246*e5436536SAndroid Build Coastguard Worker 
247*e5436536SAndroid Build Coastguard Worker } DRCDEC_SELECTION;
248*e5436536SAndroid Build Coastguard Worker 
249*e5436536SAndroid Build Coastguard Worker /*******************************************/
250*e5436536SAndroid Build Coastguard Worker /* helper functions                        */
251*e5436536SAndroid Build Coastguard Worker /*******************************************/
252*e5436536SAndroid Build Coastguard Worker 
_isError(int x)253*e5436536SAndroid Build Coastguard Worker static int _isError(int x) {
254*e5436536SAndroid Build Coastguard Worker   if (x < DRCDEC_SELECTION_PROCESS_WARNING) {
255*e5436536SAndroid Build Coastguard Worker     return 1;
256*e5436536SAndroid Build Coastguard Worker   }
257*e5436536SAndroid Build Coastguard Worker 
258*e5436536SAndroid Build Coastguard Worker   return 0;
259*e5436536SAndroid Build Coastguard Worker }
260*e5436536SAndroid Build Coastguard Worker 
261*e5436536SAndroid Build Coastguard Worker /* compare and assign */
_compAssign(UCHAR * dest,const UCHAR src)262*e5436536SAndroid Build Coastguard Worker static inline int _compAssign(UCHAR* dest, const UCHAR src) {
263*e5436536SAndroid Build Coastguard Worker   int diff = 0;
264*e5436536SAndroid Build Coastguard Worker   if (*dest != src) diff = 1;
265*e5436536SAndroid Build Coastguard Worker   *dest = src;
266*e5436536SAndroid Build Coastguard Worker   return diff;
267*e5436536SAndroid Build Coastguard Worker }
268*e5436536SAndroid Build Coastguard Worker 
_compAssign(SCHAR * dest,const SCHAR src)269*e5436536SAndroid Build Coastguard Worker static inline int _compAssign(SCHAR* dest, const SCHAR src) {
270*e5436536SAndroid Build Coastguard Worker   int diff = 0;
271*e5436536SAndroid Build Coastguard Worker   if (*dest != src) diff = 1;
272*e5436536SAndroid Build Coastguard Worker   *dest = src;
273*e5436536SAndroid Build Coastguard Worker   return diff;
274*e5436536SAndroid Build Coastguard Worker }
275*e5436536SAndroid Build Coastguard Worker 
_compAssign(FIXP_DBL * dest,const FIXP_DBL src)276*e5436536SAndroid Build Coastguard Worker static inline int _compAssign(FIXP_DBL* dest, const FIXP_DBL src) {
277*e5436536SAndroid Build Coastguard Worker   int diff = 0;
278*e5436536SAndroid Build Coastguard Worker   if (*dest != src) diff = 1;
279*e5436536SAndroid Build Coastguard Worker   *dest = src;
280*e5436536SAndroid Build Coastguard Worker   return diff;
281*e5436536SAndroid Build Coastguard Worker }
282*e5436536SAndroid Build Coastguard Worker 
_compAssign(FIXP_SGL * dest,const FIXP_SGL src)283*e5436536SAndroid Build Coastguard Worker static inline int _compAssign(FIXP_SGL* dest, const FIXP_SGL src) {
284*e5436536SAndroid Build Coastguard Worker   int diff = 0;
285*e5436536SAndroid Build Coastguard Worker   if (*dest != src) diff = 1;
286*e5436536SAndroid Build Coastguard Worker   *dest = src;
287*e5436536SAndroid Build Coastguard Worker   return diff;
288*e5436536SAndroid Build Coastguard Worker }
289*e5436536SAndroid Build Coastguard Worker 
_compAssign(TARGET_CONFIG_REQUEST_TYPE * dest,const int src)290*e5436536SAndroid Build Coastguard Worker static inline int _compAssign(TARGET_CONFIG_REQUEST_TYPE* dest, const int src) {
291*e5436536SAndroid Build Coastguard Worker   int diff = 0;
292*e5436536SAndroid Build Coastguard Worker   if (*dest != src) diff = 1;
293*e5436536SAndroid Build Coastguard Worker   *dest = (TARGET_CONFIG_REQUEST_TYPE)src;
294*e5436536SAndroid Build Coastguard Worker   return diff;
295*e5436536SAndroid Build Coastguard Worker }
296*e5436536SAndroid Build Coastguard Worker 
_compAssign(METHOD_DEFINITION_REQUEST * dest,const int src)297*e5436536SAndroid Build Coastguard Worker static inline int _compAssign(METHOD_DEFINITION_REQUEST* dest, const int src) {
298*e5436536SAndroid Build Coastguard Worker   int diff = 0;
299*e5436536SAndroid Build Coastguard Worker   if (*dest != src) diff = 1;
300*e5436536SAndroid Build Coastguard Worker   *dest = (METHOD_DEFINITION_REQUEST)src;
301*e5436536SAndroid Build Coastguard Worker   return diff;
302*e5436536SAndroid Build Coastguard Worker }
303*e5436536SAndroid Build Coastguard Worker 
_compAssign(DRC_FEATURE_REQUEST_TYPE * dest,const int src)304*e5436536SAndroid Build Coastguard Worker static inline int _compAssign(DRC_FEATURE_REQUEST_TYPE* dest, const int src) {
305*e5436536SAndroid Build Coastguard Worker   int diff = 0;
306*e5436536SAndroid Build Coastguard Worker   if (*dest != src) diff = 1;
307*e5436536SAndroid Build Coastguard Worker   *dest = (DRC_FEATURE_REQUEST_TYPE)src;
308*e5436536SAndroid Build Coastguard Worker   return diff;
309*e5436536SAndroid Build Coastguard Worker }
310*e5436536SAndroid Build Coastguard Worker 
_compAssign(DRC_EFFECT_TYPE_REQUEST * dest,const int src)311*e5436536SAndroid Build Coastguard Worker static inline int _compAssign(DRC_EFFECT_TYPE_REQUEST* dest, const int src) {
312*e5436536SAndroid Build Coastguard Worker   int diff = 0;
313*e5436536SAndroid Build Coastguard Worker   if (*dest != src) diff = 1;
314*e5436536SAndroid Build Coastguard Worker   *dest = (DRC_EFFECT_TYPE_REQUEST)src;
315*e5436536SAndroid Build Coastguard Worker   return diff;
316*e5436536SAndroid Build Coastguard Worker }
317*e5436536SAndroid Build Coastguard Worker 
318*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_DATA* _drcdec_selection_addNew(
319*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pSelection);
320*e5436536SAndroid Build Coastguard Worker 
321*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_DATA* _drcdec_selection_add(
322*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pSelection, DRCDEC_SELECTION_DATA* pDataIn);
323*e5436536SAndroid Build Coastguard Worker 
324*e5436536SAndroid Build Coastguard Worker static int _drcdec_selection_clear(DRCDEC_SELECTION* pSelection);
325*e5436536SAndroid Build Coastguard Worker 
326*e5436536SAndroid Build Coastguard Worker static int _drcdec_selection_getNumber(DRCDEC_SELECTION* pSelection);
327*e5436536SAndroid Build Coastguard Worker 
328*e5436536SAndroid Build Coastguard Worker static int _drcdec_selection_setNumber(DRCDEC_SELECTION* pSelection, int num);
329*e5436536SAndroid Build Coastguard Worker 
330*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_DATA* _drcdec_selection_getAt(
331*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pSelection, int at);
332*e5436536SAndroid Build Coastguard Worker 
333*e5436536SAndroid Build Coastguard Worker static int _swapSelectionAndClear(DRCDEC_SELECTION** ppCandidatesPotential,
334*e5436536SAndroid Build Coastguard Worker                                   DRCDEC_SELECTION** ppCandidatesSelected);
335*e5436536SAndroid Build Coastguard Worker 
336*e5436536SAndroid Build Coastguard Worker static int _swapSelection(DRCDEC_SELECTION** ppCandidatesPotential,
337*e5436536SAndroid Build Coastguard Worker                           DRCDEC_SELECTION** ppCandidatesSelected);
338*e5436536SAndroid Build Coastguard Worker 
339*e5436536SAndroid Build Coastguard Worker /*******************************************/
340*e5436536SAndroid Build Coastguard Worker /* declarations of static functions        */
341*e5436536SAndroid Build Coastguard Worker /*******************************************/
342*e5436536SAndroid Build Coastguard Worker 
343*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _initDefaultParams(
344*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput);
345*e5436536SAndroid Build Coastguard Worker 
346*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _initCodecModeParams(
347*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput, const SEL_PROC_CODEC_MODE codecMode);
348*e5436536SAndroid Build Coastguard Worker 
349*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelection(
350*e5436536SAndroid Build Coastguard Worker     SEL_PROC_INPUT* hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
351*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
352*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesPotential,
353*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesSelected, SEL_PROC_CODEC_MODE codecMode);
354*e5436536SAndroid Build Coastguard Worker 
355*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_peakValue0(
356*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesPotential,
357*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected);
358*e5436536SAndroid Build Coastguard Worker 
359*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _dynamicRangeMeasurement(
360*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, DRC_INSTRUCTIONS_UNI_DRC* pInst,
361*e5436536SAndroid Build Coastguard Worker     UCHAR downmixIdRequested,
362*e5436536SAndroid Build Coastguard Worker     DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,
363*e5436536SAndroid Build Coastguard Worker     int albumMode, int* peakToAveragePresent, FIXP_DBL* peakToAverage);
364*e5436536SAndroid Build Coastguard Worker 
365*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _channelLayoutToDownmixIdMapping(
366*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig);
367*e5436536SAndroid Build Coastguard Worker 
368*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _generateVirtualDrcSets(
369*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
370*e5436536SAndroid Build Coastguard Worker     SEL_PROC_CODEC_MODE codecMode);
371*e5436536SAndroid Build Coastguard Worker 
372*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetRequestSelection(
373*e5436536SAndroid Build Coastguard Worker     SEL_PROC_INPUT* hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
374*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
375*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesPotential,
376*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesSelected);
377*e5436536SAndroid Build Coastguard Worker 
378*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection(
379*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
380*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesPotential,
381*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesSelected, SEL_PROC_CODEC_MODE codecMode);
382*e5436536SAndroid Build Coastguard Worker 
383*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
384*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
385*e5436536SAndroid Build Coastguard Worker     HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
386*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
387*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION_DATA* pSelectionData, SEL_PROC_CODEC_MODE codecMode);
388*e5436536SAndroid Build Coastguard Worker 
389*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _selectDownmixMatrix(
390*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_OUTPUT hSelProcOutput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig);
391*e5436536SAndroid Build Coastguard Worker 
392*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _getLoudness(
393*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int albumMode,
394*e5436536SAndroid Build Coastguard Worker     METHOD_DEFINITION_REQUEST measurementMethodRequested,
395*e5436536SAndroid Build Coastguard Worker     MEASUREMENT_SYSTEM_REQUEST measurementSystemRequested,
396*e5436536SAndroid Build Coastguard Worker     FIXP_DBL targetLoudness, int drcSetId, int downmixIdRequested,
397*e5436536SAndroid Build Coastguard Worker     FIXP_DBL* pLoudnessNormalizationGain, FIXP_DBL* pLoudness);
398*e5436536SAndroid Build Coastguard Worker 
399*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _getMixingLevel(
400*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int downmixIdRequested,
401*e5436536SAndroid Build Coastguard Worker     int drcSetIdRequested, int albumMode, FIXP_DBL* pMixingLevel);
402*e5436536SAndroid Build Coastguard Worker 
403*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _getSignalPeakLevel(
404*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
405*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, DRC_INSTRUCTIONS_UNI_DRC* pInst,
406*e5436536SAndroid Build Coastguard Worker     int downmixIdRequested, int* explicitPeakInformationPresent,
407*e5436536SAndroid Build Coastguard Worker     FIXP_DBL* signalPeakLevelOut, /* e = 7 */
408*e5436536SAndroid Build Coastguard Worker     SEL_PROC_CODEC_MODE codecMode);
409*e5436536SAndroid Build Coastguard Worker 
410*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _extractLoudnessPeakToAverageValue(
411*e5436536SAndroid Build Coastguard Worker     LOUDNESS_INFO* loudnessInfo,
412*e5436536SAndroid Build Coastguard Worker     DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,
413*e5436536SAndroid Build Coastguard Worker     int* pLoudnessPeakToAverageValuePresent,
414*e5436536SAndroid Build Coastguard Worker     FIXP_DBL* pLoudnessPeakToAverageValue);
415*e5436536SAndroid Build Coastguard Worker 
416*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _selectAlbumLoudness(
417*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
418*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesPotential,
419*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected);
420*e5436536SAndroid Build Coastguard Worker 
421*e5436536SAndroid Build Coastguard Worker static int _findMethodDefinition(LOUDNESS_INFO* pLoudnessInfo,
422*e5436536SAndroid Build Coastguard Worker                                  int methodDefinition, int startIndex);
423*e5436536SAndroid Build Coastguard Worker 
424*e5436536SAndroid Build Coastguard Worker /*******************************************/
425*e5436536SAndroid Build Coastguard Worker /* public functions                        */
426*e5436536SAndroid Build Coastguard Worker /*******************************************/
427*e5436536SAndroid Build Coastguard Worker 
428*e5436536SAndroid Build Coastguard Worker struct s_drcdec_selection_process {
429*e5436536SAndroid Build Coastguard Worker   SEL_PROC_CODEC_MODE codecMode;
430*e5436536SAndroid Build Coastguard Worker   SEL_PROC_INPUT selProcInput;
431*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION
432*e5436536SAndroid Build Coastguard Worker   selectionData[2]; /* 2 instances, one before and one after selection */
433*e5436536SAndroid Build Coastguard Worker };
434*e5436536SAndroid Build Coastguard Worker 
435*e5436536SAndroid Build Coastguard Worker DRCDEC_SELECTION_PROCESS_RETURN
drcDec_SelectionProcess_Create(HANDLE_DRC_SELECTION_PROCESS * phInstance)436*e5436536SAndroid Build Coastguard Worker drcDec_SelectionProcess_Create(HANDLE_DRC_SELECTION_PROCESS* phInstance) {
437*e5436536SAndroid Build Coastguard Worker   HANDLE_DRC_SELECTION_PROCESS hInstance;
438*e5436536SAndroid Build Coastguard Worker   hInstance = (HANDLE_DRC_SELECTION_PROCESS)FDKcalloc(
439*e5436536SAndroid Build Coastguard Worker       1, sizeof(struct s_drcdec_selection_process));
440*e5436536SAndroid Build Coastguard Worker 
441*e5436536SAndroid Build Coastguard Worker   if (!hInstance) return DRCDEC_SELECTION_PROCESS_OUTOFMEMORY;
442*e5436536SAndroid Build Coastguard Worker 
443*e5436536SAndroid Build Coastguard Worker   hInstance->codecMode = SEL_PROC_CODEC_MODE_UNDEFINED;
444*e5436536SAndroid Build Coastguard Worker 
445*e5436536SAndroid Build Coastguard Worker   *phInstance = hInstance;
446*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
447*e5436536SAndroid Build Coastguard Worker }
448*e5436536SAndroid Build Coastguard Worker 
449*e5436536SAndroid Build Coastguard Worker DRCDEC_SELECTION_PROCESS_RETURN
drcDec_SelectionProcess_Init(HANDLE_DRC_SELECTION_PROCESS hInstance)450*e5436536SAndroid Build Coastguard Worker drcDec_SelectionProcess_Init(HANDLE_DRC_SELECTION_PROCESS hInstance) {
451*e5436536SAndroid Build Coastguard Worker   if (!hInstance) return DRCDEC_SELECTION_PROCESS_NOT_OK;
452*e5436536SAndroid Build Coastguard Worker 
453*e5436536SAndroid Build Coastguard Worker   _initDefaultParams(&hInstance->selProcInput);
454*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
455*e5436536SAndroid Build Coastguard Worker }
456*e5436536SAndroid Build Coastguard Worker 
457*e5436536SAndroid Build Coastguard Worker DRCDEC_SELECTION_PROCESS_RETURN
drcDec_SelectionProcess_SetCodecMode(HANDLE_DRC_SELECTION_PROCESS hInstance,const SEL_PROC_CODEC_MODE codecMode)458*e5436536SAndroid Build Coastguard Worker drcDec_SelectionProcess_SetCodecMode(HANDLE_DRC_SELECTION_PROCESS hInstance,
459*e5436536SAndroid Build Coastguard Worker                                      const SEL_PROC_CODEC_MODE codecMode) {
460*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
461*e5436536SAndroid Build Coastguard Worker 
462*e5436536SAndroid Build Coastguard Worker   if (!hInstance) return DRCDEC_SELECTION_PROCESS_NOT_OK;
463*e5436536SAndroid Build Coastguard Worker 
464*e5436536SAndroid Build Coastguard Worker   switch (codecMode) {
465*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_MPEG_4_AAC:
466*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_MPEG_D_USAC:
467*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_TEST_TIME_DOMAIN:
468*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_TEST_QMF_DOMAIN:
469*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_TEST_STFT_DOMAIN:
470*e5436536SAndroid Build Coastguard Worker       hInstance->codecMode = codecMode;
471*e5436536SAndroid Build Coastguard Worker       break;
472*e5436536SAndroid Build Coastguard Worker 
473*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_CODEC_MODE_UNDEFINED:
474*e5436536SAndroid Build Coastguard Worker     default:
475*e5436536SAndroid Build Coastguard Worker       return DRCDEC_SELECTION_PROCESS_NOT_OK;
476*e5436536SAndroid Build Coastguard Worker   }
477*e5436536SAndroid Build Coastguard Worker 
478*e5436536SAndroid Build Coastguard Worker   retVal = _initCodecModeParams(&(hInstance->selProcInput),
479*e5436536SAndroid Build Coastguard Worker                                 hInstance->codecMode = codecMode);
480*e5436536SAndroid Build Coastguard Worker 
481*e5436536SAndroid Build Coastguard Worker   return retVal;
482*e5436536SAndroid Build Coastguard Worker }
483*e5436536SAndroid Build Coastguard Worker 
484*e5436536SAndroid Build Coastguard Worker DRCDEC_SELECTION_PROCESS_RETURN
drcDec_SelectionProcess_SetParam(HANDLE_DRC_SELECTION_PROCESS hInstance,const SEL_PROC_USER_PARAM requestType,FIXP_DBL requestValue,int * pDiff)485*e5436536SAndroid Build Coastguard Worker drcDec_SelectionProcess_SetParam(HANDLE_DRC_SELECTION_PROCESS hInstance,
486*e5436536SAndroid Build Coastguard Worker                                  const SEL_PROC_USER_PARAM requestType,
487*e5436536SAndroid Build Coastguard Worker                                  FIXP_DBL requestValue, int* pDiff) {
488*e5436536SAndroid Build Coastguard Worker   INT requestValueInt = (INT)requestValue;
489*e5436536SAndroid Build Coastguard Worker   int i, diff = 0;
490*e5436536SAndroid Build Coastguard Worker   SEL_PROC_INPUT* pSelProcInput = &(hInstance->selProcInput);
491*e5436536SAndroid Build Coastguard Worker 
492*e5436536SAndroid Build Coastguard Worker   switch (requestType) {
493*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_LOUDNESS_NORMALIZATION_ON:
494*e5436536SAndroid Build Coastguard Worker       if ((requestValueInt != 0) && (requestValueInt != 1))
495*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
496*e5436536SAndroid Build Coastguard Worker       diff |=
497*e5436536SAndroid Build Coastguard Worker           _compAssign(&pSelProcInput->loudnessNormalizationOn, requestValueInt);
498*e5436536SAndroid Build Coastguard Worker       break;
499*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_TARGET_LOUDNESS:
500*e5436536SAndroid Build Coastguard Worker       /* Lower boundary: drcSetTargetLoudnessValueLower default value.
501*e5436536SAndroid Build Coastguard Worker          Upper boundary: drcSetTargetLoudnessValueUpper default value */
502*e5436536SAndroid Build Coastguard Worker       if ((requestValue < FL2FXCONST_DBL(-63.0f / (float)(1 << 7))) ||
503*e5436536SAndroid Build Coastguard Worker           (requestValue > (FIXP_DBL)0))
504*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
505*e5436536SAndroid Build Coastguard Worker       if (requestValue >
506*e5436536SAndroid Build Coastguard Worker           FL2FXCONST_DBL(-10.0f /
507*e5436536SAndroid Build Coastguard Worker                          (float)(1 << 7))) /* recommended maximum value */
508*e5436536SAndroid Build Coastguard Worker         requestValue = FL2FXCONST_DBL(-10.0f / (float)(1 << 7));
509*e5436536SAndroid Build Coastguard Worker       diff |= _compAssign(&pSelProcInput->targetLoudness, requestValue);
510*e5436536SAndroid Build Coastguard Worker       break;
511*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_EFFECT_TYPE:
512*e5436536SAndroid Build Coastguard Worker       if ((requestValueInt < -1) || (requestValueInt >= DETR_COUNT))
513*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
514*e5436536SAndroid Build Coastguard Worker       /* Caution. This overrides all drcFeatureRequests requested so far! */
515*e5436536SAndroid Build Coastguard Worker       if (requestValueInt == -1) {
516*e5436536SAndroid Build Coastguard Worker         diff |= _compAssign(&pSelProcInput->dynamicRangeControlOn, 0);
517*e5436536SAndroid Build Coastguard Worker       } else if (requestValueInt == DETR_NONE) {
518*e5436536SAndroid Build Coastguard Worker         diff |= _compAssign(&pSelProcInput->dynamicRangeControlOn, 1);
519*e5436536SAndroid Build Coastguard Worker         diff |= _compAssign(&pSelProcInput->numDrcFeatureRequests, 0);
520*e5436536SAndroid Build Coastguard Worker       } else {
521*e5436536SAndroid Build Coastguard Worker         diff |= _compAssign(&pSelProcInput->dynamicRangeControlOn, 1);
522*e5436536SAndroid Build Coastguard Worker         diff |= _compAssign(&pSelProcInput->numDrcFeatureRequests, 1);
523*e5436536SAndroid Build Coastguard Worker         diff |= _compAssign(&pSelProcInput->drcFeatureRequestType[0],
524*e5436536SAndroid Build Coastguard Worker                             DFRT_EFFECT_TYPE);
525*e5436536SAndroid Build Coastguard Worker         diff |= _compAssign(&pSelProcInput->drcFeatureRequest[0]
526*e5436536SAndroid Build Coastguard Worker                                  .drcEffectType.numRequestsDesired,
527*e5436536SAndroid Build Coastguard Worker                             1);
528*e5436536SAndroid Build Coastguard Worker         diff |= _compAssign(
529*e5436536SAndroid Build Coastguard Worker             &pSelProcInput->drcFeatureRequest[0].drcEffectType.request[0],
530*e5436536SAndroid Build Coastguard Worker             requestValueInt);
531*e5436536SAndroid Build Coastguard Worker         if ((requestValueInt > DETR_NONE) &&
532*e5436536SAndroid Build Coastguard Worker             (requestValueInt <= DETR_GENERAL_COMPR)) {
533*e5436536SAndroid Build Coastguard Worker           /* use fallback effect type requests */
534*e5436536SAndroid Build Coastguard Worker           for (i = 0; i < 5; i++) {
535*e5436536SAndroid Build Coastguard Worker             diff |=
536*e5436536SAndroid Build Coastguard Worker                 _compAssign(&pSelProcInput->drcFeatureRequest[0]
537*e5436536SAndroid Build Coastguard Worker                                  .drcEffectType.request[i + 1],
538*e5436536SAndroid Build Coastguard Worker                             fallbackEffectTypeRequests[requestValueInt - 1][i]);
539*e5436536SAndroid Build Coastguard Worker           }
540*e5436536SAndroid Build Coastguard Worker           diff |= _compAssign(
541*e5436536SAndroid Build Coastguard Worker               &pSelProcInput->drcFeatureRequest[0].drcEffectType.numRequests,
542*e5436536SAndroid Build Coastguard Worker               6);
543*e5436536SAndroid Build Coastguard Worker         } else {
544*e5436536SAndroid Build Coastguard Worker           diff |= _compAssign(
545*e5436536SAndroid Build Coastguard Worker               &pSelProcInput->drcFeatureRequest[0].drcEffectType.numRequests,
546*e5436536SAndroid Build Coastguard Worker               1);
547*e5436536SAndroid Build Coastguard Worker         }
548*e5436536SAndroid Build Coastguard Worker       }
549*e5436536SAndroid Build Coastguard Worker       break;
550*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_LOUDNESS_MEASUREMENT_METHOD:
551*e5436536SAndroid Build Coastguard Worker       if ((requestValueInt < 0) || (requestValueInt > 2))
552*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
553*e5436536SAndroid Build Coastguard Worker       diff |= _compAssign(&pSelProcInput->loudnessMeasurementMethod,
554*e5436536SAndroid Build Coastguard Worker                           requestValueInt);
555*e5436536SAndroid Build Coastguard Worker       break;
556*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_ALBUM_MODE:
557*e5436536SAndroid Build Coastguard Worker       if ((requestValueInt < 0) || (requestValueInt > 1))
558*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
559*e5436536SAndroid Build Coastguard Worker       diff |= _compAssign(&pSelProcInput->albumMode, requestValueInt);
560*e5436536SAndroid Build Coastguard Worker       break;
561*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_DOWNMIX_ID:
562*e5436536SAndroid Build Coastguard Worker       diff |=
563*e5436536SAndroid Build Coastguard Worker           _compAssign(&pSelProcInput->targetConfigRequestType, TCRT_DOWNMIX_ID);
564*e5436536SAndroid Build Coastguard Worker       if (requestValueInt < 0) { /* negative requests signal no downmixId */
565*e5436536SAndroid Build Coastguard Worker         diff |= _compAssign(&pSelProcInput->numDownmixIdRequests, 0);
566*e5436536SAndroid Build Coastguard Worker       } else {
567*e5436536SAndroid Build Coastguard Worker         diff |= _compAssign(&pSelProcInput->numDownmixIdRequests, 1);
568*e5436536SAndroid Build Coastguard Worker         diff |=
569*e5436536SAndroid Build Coastguard Worker             _compAssign(&pSelProcInput->downmixIdRequested[0], requestValueInt);
570*e5436536SAndroid Build Coastguard Worker       }
571*e5436536SAndroid Build Coastguard Worker       break;
572*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_TARGET_LAYOUT:
573*e5436536SAndroid Build Coastguard Worker       /* Request target layout according to ChannelConfiguration in ISO/IEC
574*e5436536SAndroid Build Coastguard Worker        * 23001-8 (CICP) */
575*e5436536SAndroid Build Coastguard Worker       if ((requestValueInt < 1) || (requestValueInt > 63))
576*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
577*e5436536SAndroid Build Coastguard Worker       diff |= _compAssign(&pSelProcInput->targetConfigRequestType,
578*e5436536SAndroid Build Coastguard Worker                           TCRT_TARGET_LAYOUT);
579*e5436536SAndroid Build Coastguard Worker       diff |=
580*e5436536SAndroid Build Coastguard Worker           _compAssign(&pSelProcInput->targetLayoutRequested, requestValueInt);
581*e5436536SAndroid Build Coastguard Worker       break;
582*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_TARGET_CHANNEL_COUNT:
583*e5436536SAndroid Build Coastguard Worker       if ((requestValueInt < 1) || (requestValueInt > 8))
584*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
585*e5436536SAndroid Build Coastguard Worker       diff |= _compAssign(&pSelProcInput->targetConfigRequestType,
586*e5436536SAndroid Build Coastguard Worker                           TCRT_TARGET_CHANNEL_COUNT);
587*e5436536SAndroid Build Coastguard Worker       diff |= _compAssign(&pSelProcInput->targetChannelCountRequested,
588*e5436536SAndroid Build Coastguard Worker                           requestValueInt);
589*e5436536SAndroid Build Coastguard Worker       break;
590*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_BASE_CHANNEL_COUNT:
591*e5436536SAndroid Build Coastguard Worker       if (requestValueInt < 0)
592*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
593*e5436536SAndroid Build Coastguard Worker       diff |= _compAssign(&pSelProcInput->baseChannelCount, requestValueInt);
594*e5436536SAndroid Build Coastguard Worker       break;
595*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_SAMPLE_RATE:
596*e5436536SAndroid Build Coastguard Worker       if (requestValueInt < 0)
597*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
598*e5436536SAndroid Build Coastguard Worker       diff |= _compAssign(&pSelProcInput->audioSampleRate, requestValueInt);
599*e5436536SAndroid Build Coastguard Worker       break;
600*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_BOOST:
601*e5436536SAndroid Build Coastguard Worker       if ((requestValue < (FIXP_DBL)0) ||
602*e5436536SAndroid Build Coastguard Worker           (requestValue > FL2FXCONST_DBL(1.0f / (float)(1 << 1))))
603*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
604*e5436536SAndroid Build Coastguard Worker       diff |= _compAssign(
605*e5436536SAndroid Build Coastguard Worker           &pSelProcInput->boost,
606*e5436536SAndroid Build Coastguard Worker           FX_DBL2FX_SGL(
607*e5436536SAndroid Build Coastguard Worker               requestValue +
608*e5436536SAndroid Build Coastguard Worker               (FIXP_DBL)(1 << 15))); /* convert to FIXP_SGL with rounding */
609*e5436536SAndroid Build Coastguard Worker       break;
610*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_COMPRESS:
611*e5436536SAndroid Build Coastguard Worker       if ((requestValue < (FIXP_DBL)0) ||
612*e5436536SAndroid Build Coastguard Worker           (requestValue > FL2FXCONST_DBL(1.0f / (float)(1 << 1))))
613*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
614*e5436536SAndroid Build Coastguard Worker       diff |= _compAssign(
615*e5436536SAndroid Build Coastguard Worker           &pSelProcInput->compress,
616*e5436536SAndroid Build Coastguard Worker           FX_DBL2FX_SGL(
617*e5436536SAndroid Build Coastguard Worker               requestValue +
618*e5436536SAndroid Build Coastguard Worker               (FIXP_DBL)(1 << 15))); /* convert to FIXP_SGL with rounding */
619*e5436536SAndroid Build Coastguard Worker       break;
620*e5436536SAndroid Build Coastguard Worker     default:
621*e5436536SAndroid Build Coastguard Worker       return DRCDEC_SELECTION_PROCESS_INVALID_PARAM;
622*e5436536SAndroid Build Coastguard Worker   }
623*e5436536SAndroid Build Coastguard Worker 
624*e5436536SAndroid Build Coastguard Worker   if (pDiff != NULL) {
625*e5436536SAndroid Build Coastguard Worker     *pDiff |= diff;
626*e5436536SAndroid Build Coastguard Worker   }
627*e5436536SAndroid Build Coastguard Worker 
628*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
629*e5436536SAndroid Build Coastguard Worker }
630*e5436536SAndroid Build Coastguard Worker 
631*e5436536SAndroid Build Coastguard Worker FIXP_DBL
drcDec_SelectionProcess_GetParam(HANDLE_DRC_SELECTION_PROCESS hInstance,const SEL_PROC_USER_PARAM requestType)632*e5436536SAndroid Build Coastguard Worker drcDec_SelectionProcess_GetParam(HANDLE_DRC_SELECTION_PROCESS hInstance,
633*e5436536SAndroid Build Coastguard Worker                                  const SEL_PROC_USER_PARAM requestType) {
634*e5436536SAndroid Build Coastguard Worker   SEL_PROC_INPUT* pSelProcInput = &(hInstance->selProcInput);
635*e5436536SAndroid Build Coastguard Worker 
636*e5436536SAndroid Build Coastguard Worker   switch (requestType) {
637*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_LOUDNESS_NORMALIZATION_ON:
638*e5436536SAndroid Build Coastguard Worker       return (FIXP_DBL)pSelProcInput->loudnessNormalizationOn;
639*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_DYNAMIC_RANGE_CONTROL_ON:
640*e5436536SAndroid Build Coastguard Worker       return (FIXP_DBL)pSelProcInput->dynamicRangeControlOn;
641*e5436536SAndroid Build Coastguard Worker     default:
642*e5436536SAndroid Build Coastguard Worker       return (FIXP_DBL)0;
643*e5436536SAndroid Build Coastguard Worker   }
644*e5436536SAndroid Build Coastguard Worker }
645*e5436536SAndroid Build Coastguard Worker 
646*e5436536SAndroid Build Coastguard Worker DRCDEC_SELECTION_PROCESS_RETURN
drcDec_SelectionProcess_Delete(HANDLE_DRC_SELECTION_PROCESS * phInstance)647*e5436536SAndroid Build Coastguard Worker drcDec_SelectionProcess_Delete(HANDLE_DRC_SELECTION_PROCESS* phInstance) {
648*e5436536SAndroid Build Coastguard Worker   if (phInstance == NULL || *phInstance == NULL)
649*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_INVALID_HANDLE;
650*e5436536SAndroid Build Coastguard Worker 
651*e5436536SAndroid Build Coastguard Worker   FDKfree(*phInstance);
652*e5436536SAndroid Build Coastguard Worker   *phInstance = NULL;
653*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
654*e5436536SAndroid Build Coastguard Worker }
655*e5436536SAndroid Build Coastguard Worker 
656*e5436536SAndroid Build Coastguard Worker DRCDEC_SELECTION_PROCESS_RETURN
drcDec_SelectionProcess_Process(HANDLE_DRC_SELECTION_PROCESS hInstance,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,HANDLE_SEL_PROC_OUTPUT hSelProcOutput)657*e5436536SAndroid Build Coastguard Worker drcDec_SelectionProcess_Process(HANDLE_DRC_SELECTION_PROCESS hInstance,
658*e5436536SAndroid Build Coastguard Worker                                 HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
659*e5436536SAndroid Build Coastguard Worker                                 HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
660*e5436536SAndroid Build Coastguard Worker                                 HANDLE_SEL_PROC_OUTPUT hSelProcOutput) {
661*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
662*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION* pCandidatesSelected;
663*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION* pCandidatesPotential;
664*e5436536SAndroid Build Coastguard Worker 
665*e5436536SAndroid Build Coastguard Worker   if (hInstance == NULL) return DRCDEC_SELECTION_PROCESS_INVALID_HANDLE;
666*e5436536SAndroid Build Coastguard Worker 
667*e5436536SAndroid Build Coastguard Worker   pCandidatesSelected = &(hInstance->selectionData[0]);
668*e5436536SAndroid Build Coastguard Worker   pCandidatesPotential = &(hInstance->selectionData[1]);
669*e5436536SAndroid Build Coastguard Worker   _drcdec_selection_setNumber(pCandidatesSelected, 0);
670*e5436536SAndroid Build Coastguard Worker   _drcdec_selection_setNumber(pCandidatesPotential, 0);
671*e5436536SAndroid Build Coastguard Worker 
672*e5436536SAndroid Build Coastguard Worker   retVal = _generateVirtualDrcSets(&(hInstance->selProcInput), hUniDrcConfig,
673*e5436536SAndroid Build Coastguard Worker                                    hInstance->codecMode);
674*e5436536SAndroid Build Coastguard Worker   if (retVal) return (retVal);
675*e5436536SAndroid Build Coastguard Worker 
676*e5436536SAndroid Build Coastguard Worker   if (hInstance->selProcInput.baseChannelCount !=
677*e5436536SAndroid Build Coastguard Worker       hUniDrcConfig->channelLayout.baseChannelCount) {
678*e5436536SAndroid Build Coastguard Worker     hInstance->selProcInput.baseChannelCount =
679*e5436536SAndroid Build Coastguard Worker         hUniDrcConfig->channelLayout.baseChannelCount;
680*e5436536SAndroid Build Coastguard Worker   }
681*e5436536SAndroid Build Coastguard Worker 
682*e5436536SAndroid Build Coastguard Worker   if ((hInstance->selProcInput.targetConfigRequestType != 0) ||
683*e5436536SAndroid Build Coastguard Worker       (hInstance->selProcInput.targetConfigRequestType == 0 &&
684*e5436536SAndroid Build Coastguard Worker        hInstance->selProcInput.numDownmixIdRequests == 0)) {
685*e5436536SAndroid Build Coastguard Worker     retVal = _channelLayoutToDownmixIdMapping(&(hInstance->selProcInput),
686*e5436536SAndroid Build Coastguard Worker                                               hUniDrcConfig);
687*e5436536SAndroid Build Coastguard Worker 
688*e5436536SAndroid Build Coastguard Worker     if (_isError(retVal)) return (retVal);
689*e5436536SAndroid Build Coastguard Worker   }
690*e5436536SAndroid Build Coastguard Worker 
691*e5436536SAndroid Build Coastguard Worker   retVal = _drcSetPreSelection(&(hInstance->selProcInput), hUniDrcConfig,
692*e5436536SAndroid Build Coastguard Worker                                hLoudnessInfoSet, &pCandidatesPotential,
693*e5436536SAndroid Build Coastguard Worker                                &pCandidatesSelected, hInstance->codecMode);
694*e5436536SAndroid Build Coastguard Worker   if (retVal) return (retVal);
695*e5436536SAndroid Build Coastguard Worker 
696*e5436536SAndroid Build Coastguard Worker   if (hInstance->selProcInput.albumMode) {
697*e5436536SAndroid Build Coastguard Worker     _swapSelectionAndClear(&pCandidatesPotential, &pCandidatesSelected);
698*e5436536SAndroid Build Coastguard Worker 
699*e5436536SAndroid Build Coastguard Worker     retVal = _selectAlbumLoudness(hLoudnessInfoSet, pCandidatesPotential,
700*e5436536SAndroid Build Coastguard Worker                                   pCandidatesSelected);
701*e5436536SAndroid Build Coastguard Worker     if (retVal) return (retVal);
702*e5436536SAndroid Build Coastguard Worker 
703*e5436536SAndroid Build Coastguard Worker     if (_drcdec_selection_getNumber(pCandidatesSelected) == 0) {
704*e5436536SAndroid Build Coastguard Worker       _swapSelection(&pCandidatesPotential, &pCandidatesSelected);
705*e5436536SAndroid Build Coastguard Worker     }
706*e5436536SAndroid Build Coastguard Worker   }
707*e5436536SAndroid Build Coastguard Worker 
708*e5436536SAndroid Build Coastguard Worker   _swapSelectionAndClear(&pCandidatesPotential, &pCandidatesSelected);
709*e5436536SAndroid Build Coastguard Worker 
710*e5436536SAndroid Build Coastguard Worker   retVal = _drcSetRequestSelection(&(hInstance->selProcInput), hUniDrcConfig,
711*e5436536SAndroid Build Coastguard Worker                                    hLoudnessInfoSet, &pCandidatesPotential,
712*e5436536SAndroid Build Coastguard Worker                                    &pCandidatesSelected);
713*e5436536SAndroid Build Coastguard Worker   if (retVal) return (retVal);
714*e5436536SAndroid Build Coastguard Worker 
715*e5436536SAndroid Build Coastguard Worker   retVal = _drcSetFinalSelection(&(hInstance->selProcInput), hUniDrcConfig,
716*e5436536SAndroid Build Coastguard Worker                                  &pCandidatesPotential, &pCandidatesSelected,
717*e5436536SAndroid Build Coastguard Worker                                  hInstance->codecMode);
718*e5436536SAndroid Build Coastguard Worker   if (retVal) return (retVal);
719*e5436536SAndroid Build Coastguard Worker 
720*e5436536SAndroid Build Coastguard Worker   retVal = _generateOutputInfo(
721*e5436536SAndroid Build Coastguard Worker       &(hInstance->selProcInput), hSelProcOutput, hUniDrcConfig,
722*e5436536SAndroid Build Coastguard Worker       hLoudnessInfoSet, &(pCandidatesSelected->data[0]), hInstance->codecMode);
723*e5436536SAndroid Build Coastguard Worker 
724*e5436536SAndroid Build Coastguard Worker   if (_isError(retVal)) return (retVal);
725*e5436536SAndroid Build Coastguard Worker 
726*e5436536SAndroid Build Coastguard Worker   retVal = _selectDownmixMatrix(hSelProcOutput, hUniDrcConfig);
727*e5436536SAndroid Build Coastguard Worker   if (retVal) return (retVal);
728*e5436536SAndroid Build Coastguard Worker 
729*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
730*e5436536SAndroid Build Coastguard Worker }
731*e5436536SAndroid Build Coastguard Worker 
732*e5436536SAndroid Build Coastguard Worker /*******************************************/
733*e5436536SAndroid Build Coastguard Worker /* static functions                        */
734*e5436536SAndroid Build Coastguard Worker /*******************************************/
735*e5436536SAndroid Build Coastguard Worker 
_initDefaultParams(HANDLE_SEL_PROC_INPUT hSelProcInput)736*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _initDefaultParams(
737*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput) {
738*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
739*e5436536SAndroid Build Coastguard Worker 
740*e5436536SAndroid Build Coastguard Worker   if (hSelProcInput == NULL) return DRCDEC_SELECTION_PROCESS_INVALID_HANDLE;
741*e5436536SAndroid Build Coastguard Worker 
742*e5436536SAndroid Build Coastguard Worker   /* system parameters */
743*e5436536SAndroid Build Coastguard Worker   hSelProcInput->baseChannelCount = -1;
744*e5436536SAndroid Build Coastguard Worker   hSelProcInput->baseLayout = -1;
745*e5436536SAndroid Build Coastguard Worker   hSelProcInput->targetConfigRequestType = TCRT_DOWNMIX_ID;
746*e5436536SAndroid Build Coastguard Worker   hSelProcInput->numDownmixIdRequests = 0;
747*e5436536SAndroid Build Coastguard Worker 
748*e5436536SAndroid Build Coastguard Worker   /* loudness normalization parameters */
749*e5436536SAndroid Build Coastguard Worker   hSelProcInput->albumMode = 0;
750*e5436536SAndroid Build Coastguard Worker   hSelProcInput->peakLimiterPresent = 0;
751*e5436536SAndroid Build Coastguard Worker   hSelProcInput->loudnessNormalizationOn = 1;
752*e5436536SAndroid Build Coastguard Worker   hSelProcInput->targetLoudness = FL2FXCONST_DBL(-24.0f / (float)(1 << 7));
753*e5436536SAndroid Build Coastguard Worker   hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX;
754*e5436536SAndroid Build Coastguard Worker   hSelProcInput->loudnessMeasurementMethod = MDR_ANCHOR_LOUDNESS;
755*e5436536SAndroid Build Coastguard Worker   hSelProcInput->loudnessMeasurementSystem = MSR_EXPERT_PANEL;
756*e5436536SAndroid Build Coastguard Worker   hSelProcInput->loudnessMeasurementPreProc = LPR_DEFAULT;
757*e5436536SAndroid Build Coastguard Worker   hSelProcInput->deviceCutOffFrequency = 500;
758*e5436536SAndroid Build Coastguard Worker   hSelProcInput->loudnessNormalizationGainDbMax =
759*e5436536SAndroid Build Coastguard Worker       (FIXP_DBL)MAXVAL_DBL; /* infinity as default */
760*e5436536SAndroid Build Coastguard Worker   hSelProcInput->loudnessNormalizationGainModificationDb = (FIXP_DBL)0;
761*e5436536SAndroid Build Coastguard Worker   hSelProcInput->outputPeakLevelMax = (FIXP_DBL)0;
762*e5436536SAndroid Build Coastguard Worker   if (hSelProcInput->peakLimiterPresent == 1) {
763*e5436536SAndroid Build Coastguard Worker     hSelProcInput->outputPeakLevelMax = FL2FXCONST_DBL(6.0f / (float)(1 << 7));
764*e5436536SAndroid Build Coastguard Worker   }
765*e5436536SAndroid Build Coastguard Worker 
766*e5436536SAndroid Build Coastguard Worker   /* dynamic range control parameters */
767*e5436536SAndroid Build Coastguard Worker   hSelProcInput->dynamicRangeControlOn = 1;
768*e5436536SAndroid Build Coastguard Worker 
769*e5436536SAndroid Build Coastguard Worker   hSelProcInput->numDrcFeatureRequests = 0;
770*e5436536SAndroid Build Coastguard Worker 
771*e5436536SAndroid Build Coastguard Worker   /* other parameters */
772*e5436536SAndroid Build Coastguard Worker   hSelProcInput->boost = FL2FXCONST_SGL(1.f / (float)(1 << 1));
773*e5436536SAndroid Build Coastguard Worker   hSelProcInput->compress = FL2FXCONST_SGL(1.f / (float)(1 << 1));
774*e5436536SAndroid Build Coastguard Worker   hSelProcInput->drcCharacteristicTarget = 0;
775*e5436536SAndroid Build Coastguard Worker 
776*e5436536SAndroid Build Coastguard Worker   return retVal;
777*e5436536SAndroid Build Coastguard Worker }
778*e5436536SAndroid Build Coastguard Worker 
_initCodecModeParams(HANDLE_SEL_PROC_INPUT hSelProcInput,const SEL_PROC_CODEC_MODE codecMode)779*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _initCodecModeParams(
780*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput, const SEL_PROC_CODEC_MODE codecMode) {
781*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
782*e5436536SAndroid Build Coastguard Worker 
783*e5436536SAndroid Build Coastguard Worker   if (hSelProcInput == NULL) return DRCDEC_SELECTION_PROCESS_INVALID_HANDLE;
784*e5436536SAndroid Build Coastguard Worker 
785*e5436536SAndroid Build Coastguard Worker   switch (codecMode) {
786*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_MPEG_H_3DA:
787*e5436536SAndroid Build Coastguard Worker       hSelProcInput->loudnessDeviationMax = 0;
788*e5436536SAndroid Build Coastguard Worker       hSelProcInput->peakLimiterPresent = 1; /* peak limiter is mandatory */
789*e5436536SAndroid Build Coastguard Worker       /* The peak limiter also has to catch overshoots due to user
790*e5436536SAndroid Build Coastguard Worker       interactivity, downmixing etc. Therefore the maximum output peak level is
791*e5436536SAndroid Build Coastguard Worker       reduced to 0 dB. */
792*e5436536SAndroid Build Coastguard Worker       hSelProcInput->outputPeakLevelMax = (FIXP_DBL)0;
793*e5436536SAndroid Build Coastguard Worker       break;
794*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_MPEG_4_AAC:
795*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_MPEG_D_USAC:
796*e5436536SAndroid Build Coastguard Worker       hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX;
797*e5436536SAndroid Build Coastguard Worker       hSelProcInput->peakLimiterPresent = 1;
798*e5436536SAndroid Build Coastguard Worker       /* A peak limiter is present at the end of the decoder, therefore we can
799*e5436536SAndroid Build Coastguard Worker        * allow for a maximum output peak level greater than full scale
800*e5436536SAndroid Build Coastguard Worker        */
801*e5436536SAndroid Build Coastguard Worker       hSelProcInput->outputPeakLevelMax =
802*e5436536SAndroid Build Coastguard Worker           FL2FXCONST_DBL(6.0f / (float)(1 << 7));
803*e5436536SAndroid Build Coastguard Worker       break;
804*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_TEST_TIME_DOMAIN:
805*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_TEST_QMF_DOMAIN:
806*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_TEST_STFT_DOMAIN:
807*e5436536SAndroid Build Coastguard Worker       /* for testing, adapt to default settings in reference software */
808*e5436536SAndroid Build Coastguard Worker       hSelProcInput->loudnessNormalizationOn = 0;
809*e5436536SAndroid Build Coastguard Worker       hSelProcInput->dynamicRangeControlOn = 0;
810*e5436536SAndroid Build Coastguard Worker       break;
811*e5436536SAndroid Build Coastguard Worker     case SEL_PROC_CODEC_MODE_UNDEFINED:
812*e5436536SAndroid Build Coastguard Worker     default:
813*e5436536SAndroid Build Coastguard Worker       hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX;
814*e5436536SAndroid Build Coastguard Worker       hSelProcInput->peakLimiterPresent = 0;
815*e5436536SAndroid Build Coastguard Worker   }
816*e5436536SAndroid Build Coastguard Worker 
817*e5436536SAndroid Build Coastguard Worker   return retVal;
818*e5436536SAndroid Build Coastguard Worker }
819*e5436536SAndroid Build Coastguard Worker 
_channelLayoutToDownmixIdMapping(HANDLE_SEL_PROC_INPUT hSelProcInput,HANDLE_UNI_DRC_CONFIG hUniDrcConfig)820*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _channelLayoutToDownmixIdMapping(
821*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
822*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
823*e5436536SAndroid Build Coastguard Worker 
824*e5436536SAndroid Build Coastguard Worker   DOWNMIX_INSTRUCTIONS* pDown = NULL;
825*e5436536SAndroid Build Coastguard Worker 
826*e5436536SAndroid Build Coastguard Worker   int i;
827*e5436536SAndroid Build Coastguard Worker 
828*e5436536SAndroid Build Coastguard Worker   hSelProcInput->numDownmixIdRequests = 0;
829*e5436536SAndroid Build Coastguard Worker 
830*e5436536SAndroid Build Coastguard Worker   switch (hSelProcInput->targetConfigRequestType) {
831*e5436536SAndroid Build Coastguard Worker     case TCRT_DOWNMIX_ID:
832*e5436536SAndroid Build Coastguard Worker       if (hSelProcInput->numDownmixIdRequests == 0) {
833*e5436536SAndroid Build Coastguard Worker         hSelProcInput->downmixIdRequested[0] = 0;
834*e5436536SAndroid Build Coastguard Worker         hSelProcInput->numDownmixIdRequests = 1;
835*e5436536SAndroid Build Coastguard Worker       }
836*e5436536SAndroid Build Coastguard Worker 
837*e5436536SAndroid Build Coastguard Worker       break;
838*e5436536SAndroid Build Coastguard Worker 
839*e5436536SAndroid Build Coastguard Worker     case TCRT_TARGET_LAYOUT:
840*e5436536SAndroid Build Coastguard Worker       if (hSelProcInput->targetLayoutRequested == hSelProcInput->baseLayout) {
841*e5436536SAndroid Build Coastguard Worker         hSelProcInput->downmixIdRequested[0] = 0;
842*e5436536SAndroid Build Coastguard Worker         hSelProcInput->numDownmixIdRequests = 1;
843*e5436536SAndroid Build Coastguard Worker       }
844*e5436536SAndroid Build Coastguard Worker 
845*e5436536SAndroid Build Coastguard Worker       if (hSelProcInput->numDownmixIdRequests == 0) {
846*e5436536SAndroid Build Coastguard Worker         for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
847*e5436536SAndroid Build Coastguard Worker           pDown = &(hUniDrcConfig->downmixInstructions[i]);
848*e5436536SAndroid Build Coastguard Worker 
849*e5436536SAndroid Build Coastguard Worker           if (hSelProcInput->targetLayoutRequested == pDown->targetLayout) {
850*e5436536SAndroid Build Coastguard Worker             hSelProcInput
851*e5436536SAndroid Build Coastguard Worker                 ->downmixIdRequested[hSelProcInput->numDownmixIdRequests] =
852*e5436536SAndroid Build Coastguard Worker                 pDown->downmixId;
853*e5436536SAndroid Build Coastguard Worker             hSelProcInput->numDownmixIdRequests++;
854*e5436536SAndroid Build Coastguard Worker           }
855*e5436536SAndroid Build Coastguard Worker         }
856*e5436536SAndroid Build Coastguard Worker       }
857*e5436536SAndroid Build Coastguard Worker 
858*e5436536SAndroid Build Coastguard Worker       if (hSelProcInput->baseLayout == -1) {
859*e5436536SAndroid Build Coastguard Worker         retVal = DRCDEC_SELECTION_PROCESS_WARNING;
860*e5436536SAndroid Build Coastguard Worker       }
861*e5436536SAndroid Build Coastguard Worker 
862*e5436536SAndroid Build Coastguard Worker       if (hSelProcInput->numDownmixIdRequests == 0) {
863*e5436536SAndroid Build Coastguard Worker         hSelProcInput->downmixIdRequested[0] = 0;
864*e5436536SAndroid Build Coastguard Worker         hSelProcInput->numDownmixIdRequests = 1;
865*e5436536SAndroid Build Coastguard Worker         retVal = DRCDEC_SELECTION_PROCESS_WARNING;
866*e5436536SAndroid Build Coastguard Worker       }
867*e5436536SAndroid Build Coastguard Worker 
868*e5436536SAndroid Build Coastguard Worker       break;
869*e5436536SAndroid Build Coastguard Worker 
870*e5436536SAndroid Build Coastguard Worker     case TCRT_TARGET_CHANNEL_COUNT:
871*e5436536SAndroid Build Coastguard Worker       if (hSelProcInput->targetChannelCountRequested ==
872*e5436536SAndroid Build Coastguard Worker           hSelProcInput->baseChannelCount) {
873*e5436536SAndroid Build Coastguard Worker         hSelProcInput->downmixIdRequested[0] = 0;
874*e5436536SAndroid Build Coastguard Worker         hSelProcInput->numDownmixIdRequests = 1;
875*e5436536SAndroid Build Coastguard Worker       }
876*e5436536SAndroid Build Coastguard Worker 
877*e5436536SAndroid Build Coastguard Worker       if (hSelProcInput->numDownmixIdRequests == 0) {
878*e5436536SAndroid Build Coastguard Worker         for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
879*e5436536SAndroid Build Coastguard Worker           pDown = &(hUniDrcConfig->downmixInstructions[i]);
880*e5436536SAndroid Build Coastguard Worker 
881*e5436536SAndroid Build Coastguard Worker           if (hSelProcInput->targetChannelCountRequested ==
882*e5436536SAndroid Build Coastguard Worker               pDown->targetChannelCount) {
883*e5436536SAndroid Build Coastguard Worker             hSelProcInput
884*e5436536SAndroid Build Coastguard Worker                 ->downmixIdRequested[hSelProcInput->numDownmixIdRequests] =
885*e5436536SAndroid Build Coastguard Worker                 pDown->downmixId;
886*e5436536SAndroid Build Coastguard Worker             hSelProcInput->numDownmixIdRequests++;
887*e5436536SAndroid Build Coastguard Worker           }
888*e5436536SAndroid Build Coastguard Worker         }
889*e5436536SAndroid Build Coastguard Worker       }
890*e5436536SAndroid Build Coastguard Worker 
891*e5436536SAndroid Build Coastguard Worker       if (hSelProcInput->baseChannelCount == -1) {
892*e5436536SAndroid Build Coastguard Worker         retVal = DRCDEC_SELECTION_PROCESS_WARNING;
893*e5436536SAndroid Build Coastguard Worker       }
894*e5436536SAndroid Build Coastguard Worker 
895*e5436536SAndroid Build Coastguard Worker       if (hSelProcInput->numDownmixIdRequests == 0) {
896*e5436536SAndroid Build Coastguard Worker         retVal = DRCDEC_SELECTION_PROCESS_WARNING;
897*e5436536SAndroid Build Coastguard Worker         hSelProcInput->downmixIdRequested[0] = 0;
898*e5436536SAndroid Build Coastguard Worker         hSelProcInput->numDownmixIdRequests = 1;
899*e5436536SAndroid Build Coastguard Worker       }
900*e5436536SAndroid Build Coastguard Worker 
901*e5436536SAndroid Build Coastguard Worker       break;
902*e5436536SAndroid Build Coastguard Worker 
903*e5436536SAndroid Build Coastguard Worker     default:
904*e5436536SAndroid Build Coastguard Worker       return DRCDEC_SELECTION_PROCESS_NOT_OK;
905*e5436536SAndroid Build Coastguard Worker   }
906*e5436536SAndroid Build Coastguard Worker 
907*e5436536SAndroid Build Coastguard Worker   return retVal;
908*e5436536SAndroid Build Coastguard Worker }
909*e5436536SAndroid Build Coastguard Worker 
910*e5436536SAndroid Build Coastguard Worker /*******************************************/
911*e5436536SAndroid Build Coastguard Worker 
912*e5436536SAndroid Build Coastguard Worker /* Note: Numbering of DRC pre-selection steps according to MPEG-D Part-4 DRC
913*e5436536SAndroid Build Coastguard Worker  * Amd1 */
914*e5436536SAndroid Build Coastguard Worker 
915*e5436536SAndroid Build Coastguard Worker /* #1: DownmixId of DRC set matches the requested downmixId.
916*e5436536SAndroid Build Coastguard Worker    #2: Output channel layout of DRC set matches the requested layout.
917*e5436536SAndroid Build Coastguard Worker    #3: Channel count of DRC set matches the requested channel count. */
_preSelectionRequirement123(int nRequestedDownmixId,DRC_INSTRUCTIONS_UNI_DRC * pDrcInstructionUniDrc,int * pMatchFound)918*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement123(
919*e5436536SAndroid Build Coastguard Worker     int nRequestedDownmixId, DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
920*e5436536SAndroid Build Coastguard Worker     int* pMatchFound) {
921*e5436536SAndroid Build Coastguard Worker   int i;
922*e5436536SAndroid Build Coastguard Worker   *pMatchFound = 0;
923*e5436536SAndroid Build Coastguard Worker 
924*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < pDrcInstructionUniDrc->downmixIdCount; i++) {
925*e5436536SAndroid Build Coastguard Worker     if ((pDrcInstructionUniDrc->downmixId[i] == nRequestedDownmixId) ||
926*e5436536SAndroid Build Coastguard Worker         (pDrcInstructionUniDrc->downmixId[i] == DOWNMIX_ID_ANY_DOWNMIX) ||
927*e5436536SAndroid Build Coastguard Worker         ((pDrcInstructionUniDrc->downmixId[i] == DOWNMIX_ID_BASE_LAYOUT) &&
928*e5436536SAndroid Build Coastguard Worker          (pDrcInstructionUniDrc->drcSetId > 0))) {
929*e5436536SAndroid Build Coastguard Worker       *pMatchFound = 1;
930*e5436536SAndroid Build Coastguard Worker       break;
931*e5436536SAndroid Build Coastguard Worker     }
932*e5436536SAndroid Build Coastguard Worker   }
933*e5436536SAndroid Build Coastguard Worker 
934*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
935*e5436536SAndroid Build Coastguard Worker }
936*e5436536SAndroid Build Coastguard Worker 
937*e5436536SAndroid Build Coastguard Worker /* #4: The DRC set is not a "Fade-" or "Ducking-" only DRC set. */
_preSelectionRequirement4(DRC_INSTRUCTIONS_UNI_DRC * pDrcInstruction,int nDynamicRangeControlOn,int * pMatchFound)938*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement4(
939*e5436536SAndroid Build Coastguard Worker     DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction, int nDynamicRangeControlOn,
940*e5436536SAndroid Build Coastguard Worker     int* pMatchFound) {
941*e5436536SAndroid Build Coastguard Worker   *pMatchFound = 0;
942*e5436536SAndroid Build Coastguard Worker 
943*e5436536SAndroid Build Coastguard Worker   if (nDynamicRangeControlOn == 1) {
944*e5436536SAndroid Build Coastguard Worker     if ((pDrcInstruction->drcSetEffect != EB_FADE) &&
945*e5436536SAndroid Build Coastguard Worker         (pDrcInstruction->drcSetEffect != EB_DUCK_OTHER) &&
946*e5436536SAndroid Build Coastguard Worker         (pDrcInstruction->drcSetEffect != EB_DUCK_SELF) &&
947*e5436536SAndroid Build Coastguard Worker         (pDrcInstruction->drcSetEffect != 0 || pDrcInstruction->drcSetId < 0)) {
948*e5436536SAndroid Build Coastguard Worker       *pMatchFound = 1;
949*e5436536SAndroid Build Coastguard Worker     }
950*e5436536SAndroid Build Coastguard Worker   } else {
951*e5436536SAndroid Build Coastguard Worker     *pMatchFound = 1;
952*e5436536SAndroid Build Coastguard Worker   }
953*e5436536SAndroid Build Coastguard Worker 
954*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
955*e5436536SAndroid Build Coastguard Worker }
956*e5436536SAndroid Build Coastguard Worker 
957*e5436536SAndroid Build Coastguard Worker /* #5: The number of DRC bands is supported. Moreover, gainSetIndex and
958*e5436536SAndroid Build Coastguard Worker  * gainSequenceIndex are within the allowed range. */
_preSelectionRequirement5(DRC_INSTRUCTIONS_UNI_DRC * pDrcInstructionUniDrc,DRC_COEFFICIENTS_UNI_DRC * pCoef,int * pMatchFound)959*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5(
960*e5436536SAndroid Build Coastguard Worker     DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
961*e5436536SAndroid Build Coastguard Worker     DRC_COEFFICIENTS_UNI_DRC* pCoef, int* pMatchFound) {
962*e5436536SAndroid Build Coastguard Worker   int b, i;
963*e5436536SAndroid Build Coastguard Worker 
964*e5436536SAndroid Build Coastguard Worker   *pMatchFound = 1;
965*e5436536SAndroid Build Coastguard Worker 
966*e5436536SAndroid Build Coastguard Worker   if (pDrcInstructionUniDrc->drcSetId < 0) /* virtual DRC sets are okay */
967*e5436536SAndroid Build Coastguard Worker   {
968*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NO_ERROR;
969*e5436536SAndroid Build Coastguard Worker   }
970*e5436536SAndroid Build Coastguard Worker 
971*e5436536SAndroid Build Coastguard Worker   if (pCoef == NULL) /* check for parametricDRC */
972*e5436536SAndroid Build Coastguard Worker   {
973*e5436536SAndroid Build Coastguard Worker     *pMatchFound = 0; /* parametricDRC not supported */
974*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NO_ERROR;
975*e5436536SAndroid Build Coastguard Worker   }
976*e5436536SAndroid Build Coastguard Worker 
977*e5436536SAndroid Build Coastguard Worker   if (pCoef->drcLocation !=
978*e5436536SAndroid Build Coastguard Worker       pDrcInstructionUniDrc
979*e5436536SAndroid Build Coastguard Worker           ->drcLocation) /* drcLocation must be LOCATION_SELECTED */
980*e5436536SAndroid Build Coastguard Worker   {
981*e5436536SAndroid Build Coastguard Worker     *pMatchFound = 0;
982*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NO_ERROR;
983*e5436536SAndroid Build Coastguard Worker   }
984*e5436536SAndroid Build Coastguard Worker 
985*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < pDrcInstructionUniDrc->nDrcChannelGroups; i++) {
986*e5436536SAndroid Build Coastguard Worker     int indexDrcCoeff = pDrcInstructionUniDrc->gainSetIndexForChannelGroup[i];
987*e5436536SAndroid Build Coastguard Worker     int bandCount = 0;
988*e5436536SAndroid Build Coastguard Worker 
989*e5436536SAndroid Build Coastguard Worker     if (indexDrcCoeff >= 12) {
990*e5436536SAndroid Build Coastguard Worker       *pMatchFound = 0;
991*e5436536SAndroid Build Coastguard Worker       return DRCDEC_SELECTION_PROCESS_NO_ERROR;
992*e5436536SAndroid Build Coastguard Worker     }
993*e5436536SAndroid Build Coastguard Worker 
994*e5436536SAndroid Build Coastguard Worker     if (indexDrcCoeff > pCoef->gainSetCount - 1) /* check for parametricDRC */
995*e5436536SAndroid Build Coastguard Worker     {
996*e5436536SAndroid Build Coastguard Worker       continue;
997*e5436536SAndroid Build Coastguard Worker     }
998*e5436536SAndroid Build Coastguard Worker 
999*e5436536SAndroid Build Coastguard Worker     GAIN_SET* gainSet = &(pCoef->gainSet[indexDrcCoeff]);
1000*e5436536SAndroid Build Coastguard Worker     bandCount = gainSet->bandCount;
1001*e5436536SAndroid Build Coastguard Worker 
1002*e5436536SAndroid Build Coastguard Worker     if (bandCount > 4) {
1003*e5436536SAndroid Build Coastguard Worker       *pMatchFound = 0;
1004*e5436536SAndroid Build Coastguard Worker     }
1005*e5436536SAndroid Build Coastguard Worker 
1006*e5436536SAndroid Build Coastguard Worker     for (b = 0; b < bandCount; b++) {
1007*e5436536SAndroid Build Coastguard Worker       if ((gainSet->gainSequenceIndex[b] >= 12) ||
1008*e5436536SAndroid Build Coastguard Worker           (gainSet->gainSequenceIndex[b] >= pCoef->gainSequenceCount)) {
1009*e5436536SAndroid Build Coastguard Worker         *pMatchFound = 0;
1010*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1011*e5436536SAndroid Build Coastguard Worker       }
1012*e5436536SAndroid Build Coastguard Worker     }
1013*e5436536SAndroid Build Coastguard Worker   }
1014*e5436536SAndroid Build Coastguard Worker 
1015*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1016*e5436536SAndroid Build Coastguard Worker }
1017*e5436536SAndroid Build Coastguard Worker 
1018*e5436536SAndroid Build Coastguard Worker /* #6: Independent use of DRC set is permitted.*/
_preSelectionRequirement6(DRC_INSTRUCTIONS_UNI_DRC * pDrcInstructionUniDrc,int * pMatchFound)1019*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement6(
1020*e5436536SAndroid Build Coastguard Worker     DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc, int* pMatchFound) {
1021*e5436536SAndroid Build Coastguard Worker   *pMatchFound = 0;
1022*e5436536SAndroid Build Coastguard Worker 
1023*e5436536SAndroid Build Coastguard Worker   if (((pDrcInstructionUniDrc->dependsOnDrcSetPresent == 0) &&
1024*e5436536SAndroid Build Coastguard Worker        (pDrcInstructionUniDrc->noIndependentUse == 0)) ||
1025*e5436536SAndroid Build Coastguard Worker       (pDrcInstructionUniDrc->dependsOnDrcSetPresent == 1)) {
1026*e5436536SAndroid Build Coastguard Worker     *pMatchFound = 1;
1027*e5436536SAndroid Build Coastguard Worker   }
1028*e5436536SAndroid Build Coastguard Worker 
1029*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1030*e5436536SAndroid Build Coastguard Worker }
1031*e5436536SAndroid Build Coastguard Worker 
1032*e5436536SAndroid Build Coastguard Worker /* #7: DRC sets that require EQ are only permitted if EQ is supported. */
_preSelectionRequirement7(DRC_INSTRUCTIONS_UNI_DRC * pDrcInstructionUniDrc,int * pMatchFound)1033*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement7(
1034*e5436536SAndroid Build Coastguard Worker     DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc, int* pMatchFound) {
1035*e5436536SAndroid Build Coastguard Worker   *pMatchFound = 1;
1036*e5436536SAndroid Build Coastguard Worker 
1037*e5436536SAndroid Build Coastguard Worker   if (pDrcInstructionUniDrc->requiresEq) {
1038*e5436536SAndroid Build Coastguard Worker     /* EQ is not supported */
1039*e5436536SAndroid Build Coastguard Worker     *pMatchFound = 0;
1040*e5436536SAndroid Build Coastguard Worker   }
1041*e5436536SAndroid Build Coastguard Worker 
1042*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1043*e5436536SAndroid Build Coastguard Worker }
1044*e5436536SAndroid Build Coastguard Worker 
_setSelectionDataInfo(DRCDEC_SELECTION_DATA * pData,FIXP_DBL loudness,FIXP_DBL loudnessNormalizationGainDb,FIXP_DBL loudnessNormalizationGainDbMax,FIXP_DBL loudnessDeviationMax,FIXP_DBL signalPeakLevel,FIXP_DBL outputPeakLevelMax,int applyAdjustment)1045*e5436536SAndroid Build Coastguard Worker static void _setSelectionDataInfo(
1046*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION_DATA* pData, FIXP_DBL loudness, /* e = 7 */
1047*e5436536SAndroid Build Coastguard Worker     FIXP_DBL loudnessNormalizationGainDb,            /* e = 7 */
1048*e5436536SAndroid Build Coastguard Worker     FIXP_DBL loudnessNormalizationGainDbMax,         /* e = 7 */
1049*e5436536SAndroid Build Coastguard Worker     FIXP_DBL loudnessDeviationMax,                   /* e = 7 */
1050*e5436536SAndroid Build Coastguard Worker     FIXP_DBL signalPeakLevel,                        /* e = 7 */
1051*e5436536SAndroid Build Coastguard Worker     FIXP_DBL outputPeakLevelMax,                     /* e = 7 */
1052*e5436536SAndroid Build Coastguard Worker     int applyAdjustment) {
1053*e5436536SAndroid Build Coastguard Worker   FIXP_DBL adjustment = 0; /* e = 8 */
1054*e5436536SAndroid Build Coastguard Worker 
1055*e5436536SAndroid Build Coastguard Worker   /* use e = 8 for all function parameters to prevent overflow */
1056*e5436536SAndroid Build Coastguard Worker   loudness >>= 1;
1057*e5436536SAndroid Build Coastguard Worker   loudnessNormalizationGainDb >>= 1;
1058*e5436536SAndroid Build Coastguard Worker   loudnessNormalizationGainDbMax >>= 1;
1059*e5436536SAndroid Build Coastguard Worker   loudnessDeviationMax >>= 1;
1060*e5436536SAndroid Build Coastguard Worker   signalPeakLevel >>= 1;
1061*e5436536SAndroid Build Coastguard Worker   outputPeakLevelMax >>= 1;
1062*e5436536SAndroid Build Coastguard Worker 
1063*e5436536SAndroid Build Coastguard Worker   if (applyAdjustment) {
1064*e5436536SAndroid Build Coastguard Worker     adjustment =
1065*e5436536SAndroid Build Coastguard Worker         fMax((FIXP_DBL)0, signalPeakLevel + loudnessNormalizationGainDb -
1066*e5436536SAndroid Build Coastguard Worker                               outputPeakLevelMax);
1067*e5436536SAndroid Build Coastguard Worker     adjustment = fMin(adjustment, fMax((FIXP_DBL)0, loudnessDeviationMax));
1068*e5436536SAndroid Build Coastguard Worker   }
1069*e5436536SAndroid Build Coastguard Worker 
1070*e5436536SAndroid Build Coastguard Worker   pData->loudnessNormalizationGainDbAdjusted = fMin(
1071*e5436536SAndroid Build Coastguard Worker       loudnessNormalizationGainDb - adjustment, loudnessNormalizationGainDbMax);
1072*e5436536SAndroid Build Coastguard Worker   pData->outputLoudness = loudness + pData->loudnessNormalizationGainDbAdjusted;
1073*e5436536SAndroid Build Coastguard Worker   pData->outputPeakLevel =
1074*e5436536SAndroid Build Coastguard Worker       signalPeakLevel + pData->loudnessNormalizationGainDbAdjusted;
1075*e5436536SAndroid Build Coastguard Worker 
1076*e5436536SAndroid Build Coastguard Worker   /* shift back to e = 7 using saturation */
1077*e5436536SAndroid Build Coastguard Worker   pData->loudnessNormalizationGainDbAdjusted = SATURATE_LEFT_SHIFT(
1078*e5436536SAndroid Build Coastguard Worker       pData->loudnessNormalizationGainDbAdjusted, 1, DFRACT_BITS);
1079*e5436536SAndroid Build Coastguard Worker   pData->outputLoudness =
1080*e5436536SAndroid Build Coastguard Worker       SATURATE_LEFT_SHIFT(pData->outputLoudness, 1, DFRACT_BITS);
1081*e5436536SAndroid Build Coastguard Worker   pData->outputPeakLevel =
1082*e5436536SAndroid Build Coastguard Worker       SATURATE_LEFT_SHIFT(pData->outputPeakLevel, 1, DFRACT_BITS);
1083*e5436536SAndroid Build Coastguard Worker }
1084*e5436536SAndroid Build Coastguard Worker 
_targetLoudnessInRange(DRC_INSTRUCTIONS_UNI_DRC * pDrcInstructionUniDrc,FIXP_DBL targetLoudness)1085*e5436536SAndroid Build Coastguard Worker static int _targetLoudnessInRange(
1086*e5436536SAndroid Build Coastguard Worker     DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc, FIXP_DBL targetLoudness) {
1087*e5436536SAndroid Build Coastguard Worker   int retVal = 0;
1088*e5436536SAndroid Build Coastguard Worker 
1089*e5436536SAndroid Build Coastguard Worker   FIXP_DBL drcSetTargetLoudnessValueUpper =
1090*e5436536SAndroid Build Coastguard Worker       ((FIXP_DBL)pDrcInstructionUniDrc->drcSetTargetLoudnessValueUpper)
1091*e5436536SAndroid Build Coastguard Worker       << (DFRACT_BITS - 1 - 7);
1092*e5436536SAndroid Build Coastguard Worker   FIXP_DBL drcSetTargetLoudnessValueLower =
1093*e5436536SAndroid Build Coastguard Worker       ((FIXP_DBL)pDrcInstructionUniDrc->drcSetTargetLoudnessValueLower)
1094*e5436536SAndroid Build Coastguard Worker       << (DFRACT_BITS - 1 - 7);
1095*e5436536SAndroid Build Coastguard Worker 
1096*e5436536SAndroid Build Coastguard Worker   if (pDrcInstructionUniDrc->drcSetTargetLoudnessPresent &&
1097*e5436536SAndroid Build Coastguard Worker       drcSetTargetLoudnessValueUpper >= targetLoudness &&
1098*e5436536SAndroid Build Coastguard Worker       drcSetTargetLoudnessValueLower < targetLoudness) {
1099*e5436536SAndroid Build Coastguard Worker     retVal = 1;
1100*e5436536SAndroid Build Coastguard Worker   }
1101*e5436536SAndroid Build Coastguard Worker 
1102*e5436536SAndroid Build Coastguard Worker   return retVal;
1103*e5436536SAndroid Build Coastguard Worker }
1104*e5436536SAndroid Build Coastguard Worker 
_drcSetIsUsable(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,DRC_INSTRUCTIONS_UNI_DRC * pInst)1105*e5436536SAndroid Build Coastguard Worker static int _drcSetIsUsable(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
1106*e5436536SAndroid Build Coastguard Worker                            DRC_INSTRUCTIONS_UNI_DRC* pInst) {
1107*e5436536SAndroid Build Coastguard Worker   int usable = 0;
1108*e5436536SAndroid Build Coastguard Worker   DRC_COEFFICIENTS_UNI_DRC* pCoef =
1109*e5436536SAndroid Build Coastguard Worker       selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
1110*e5436536SAndroid Build Coastguard Worker 
1111*e5436536SAndroid Build Coastguard Worker   /* check if ID is unique */
1112*e5436536SAndroid Build Coastguard Worker   if (selectDrcInstructions(hUniDrcConfig, pInst->drcSetId) != pInst) return 0;
1113*e5436536SAndroid Build Coastguard Worker   /* sanity check on drcInstructions */
1114*e5436536SAndroid Build Coastguard Worker   _preSelectionRequirement5(pInst, pCoef, &usable);
1115*e5436536SAndroid Build Coastguard Worker   return usable;
1116*e5436536SAndroid Build Coastguard Worker }
1117*e5436536SAndroid Build Coastguard Worker 
1118*e5436536SAndroid Build Coastguard Worker /* #8: The range of the target loudness specified for a DRC set has to include
1119*e5436536SAndroid Build Coastguard Worker  * the requested decoder target loudness. */
_preSelectionRequirement8(SEL_PROC_INPUT * hSelProcInput,int downmixIdIndex,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,DRC_INSTRUCTIONS_UNI_DRC * pDrcInstructionUniDrc,DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * pCandidatesSelected,SEL_PROC_CODEC_MODE codecMode)1120*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
1121*e5436536SAndroid Build Coastguard Worker     SEL_PROC_INPUT* hSelProcInput, int downmixIdIndex,
1122*e5436536SAndroid Build Coastguard Worker     HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
1123*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
1124*e5436536SAndroid Build Coastguard Worker     DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
1125*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesPotential,
1126*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected, SEL_PROC_CODEC_MODE codecMode) {
1127*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
1128*e5436536SAndroid Build Coastguard Worker   int explicitPeakInformationPresent;
1129*e5436536SAndroid Build Coastguard Worker   FIXP_DBL signalPeakLevel;
1130*e5436536SAndroid Build Coastguard Worker   int addToCandidate = 0;
1131*e5436536SAndroid Build Coastguard Worker 
1132*e5436536SAndroid Build Coastguard Worker   FIXP_DBL loudnessNormalizationGainDb;
1133*e5436536SAndroid Build Coastguard Worker   FIXP_DBL loudness;
1134*e5436536SAndroid Build Coastguard Worker 
1135*e5436536SAndroid Build Coastguard Worker   FIXP_DBL loudnessDeviationMax =
1136*e5436536SAndroid Build Coastguard Worker       ((FIXP_DBL)hSelProcInput->loudnessDeviationMax) << (DFRACT_BITS - 1 - 7);
1137*e5436536SAndroid Build Coastguard Worker 
1138*e5436536SAndroid Build Coastguard Worker   {
1139*e5436536SAndroid Build Coastguard Worker     retVal = _getLoudness(hLoudnessInfoSet, hSelProcInput->albumMode,
1140*e5436536SAndroid Build Coastguard Worker                           hSelProcInput->loudnessMeasurementMethod,
1141*e5436536SAndroid Build Coastguard Worker                           hSelProcInput->loudnessMeasurementSystem,
1142*e5436536SAndroid Build Coastguard Worker                           hSelProcInput->targetLoudness,
1143*e5436536SAndroid Build Coastguard Worker                           pDrcInstructionUniDrc->drcSetId,
1144*e5436536SAndroid Build Coastguard Worker                           hSelProcInput->downmixIdRequested[downmixIdIndex],
1145*e5436536SAndroid Build Coastguard Worker                           &loudnessNormalizationGainDb, &loudness);
1146*e5436536SAndroid Build Coastguard Worker     if (retVal) return (retVal);
1147*e5436536SAndroid Build Coastguard Worker   }
1148*e5436536SAndroid Build Coastguard Worker 
1149*e5436536SAndroid Build Coastguard Worker   if (!hSelProcInput->loudnessNormalizationOn) {
1150*e5436536SAndroid Build Coastguard Worker     loudnessNormalizationGainDb = (FIXP_DBL)0;
1151*e5436536SAndroid Build Coastguard Worker   }
1152*e5436536SAndroid Build Coastguard Worker 
1153*e5436536SAndroid Build Coastguard Worker   retVal = _getSignalPeakLevel(
1154*e5436536SAndroid Build Coastguard Worker       hSelProcInput, hUniDrcConfig, hLoudnessInfoSet, pDrcInstructionUniDrc,
1155*e5436536SAndroid Build Coastguard Worker       hSelProcInput->downmixIdRequested[downmixIdIndex],
1156*e5436536SAndroid Build Coastguard Worker       &explicitPeakInformationPresent, &signalPeakLevel, codecMode
1157*e5436536SAndroid Build Coastguard Worker 
1158*e5436536SAndroid Build Coastguard Worker   );
1159*e5436536SAndroid Build Coastguard Worker   if (retVal) return (retVal);
1160*e5436536SAndroid Build Coastguard Worker 
1161*e5436536SAndroid Build Coastguard Worker   if (hSelProcInput->dynamicRangeControlOn) {
1162*e5436536SAndroid Build Coastguard Worker     if (explicitPeakInformationPresent == 0) {
1163*e5436536SAndroid Build Coastguard Worker       if (pDrcInstructionUniDrc->drcSetTargetLoudnessPresent &&
1164*e5436536SAndroid Build Coastguard Worker           ((hSelProcInput->loudnessNormalizationOn &&
1165*e5436536SAndroid Build Coastguard Worker             _targetLoudnessInRange(pDrcInstructionUniDrc,
1166*e5436536SAndroid Build Coastguard Worker                                    hSelProcInput->targetLoudness)) ||
1167*e5436536SAndroid Build Coastguard Worker            !hSelProcInput->loudnessNormalizationOn)) {
1168*e5436536SAndroid Build Coastguard Worker         DRCDEC_SELECTION_DATA* pData =
1169*e5436536SAndroid Build Coastguard Worker             _drcdec_selection_addNew(pCandidatesSelected);
1170*e5436536SAndroid Build Coastguard Worker         if (pData == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1171*e5436536SAndroid Build Coastguard Worker 
1172*e5436536SAndroid Build Coastguard Worker         _setSelectionDataInfo(pData, loudness, loudnessNormalizationGainDb,
1173*e5436536SAndroid Build Coastguard Worker                               hSelProcInput->loudnessNormalizationGainDbMax,
1174*e5436536SAndroid Build Coastguard Worker                               loudnessDeviationMax, signalPeakLevel,
1175*e5436536SAndroid Build Coastguard Worker                               hSelProcInput->outputPeakLevelMax, 0);
1176*e5436536SAndroid Build Coastguard Worker         pData->downmixIdRequestIndex = downmixIdIndex;
1177*e5436536SAndroid Build Coastguard Worker         pData->pInst = pDrcInstructionUniDrc;
1178*e5436536SAndroid Build Coastguard Worker         pData->selectionFlag =
1179*e5436536SAndroid Build Coastguard Worker             1; /* signal pre-selection step dealing with drcSetTargetLoudness */
1180*e5436536SAndroid Build Coastguard Worker 
1181*e5436536SAndroid Build Coastguard Worker         if (hSelProcInput->loudnessNormalizationOn) {
1182*e5436536SAndroid Build Coastguard Worker           pData->outputPeakLevel =
1183*e5436536SAndroid Build Coastguard Worker               hSelProcInput->targetLoudness -
1184*e5436536SAndroid Build Coastguard Worker               (((FIXP_DBL)pData->pInst->drcSetTargetLoudnessValueUpper)
1185*e5436536SAndroid Build Coastguard Worker                << (DFRACT_BITS - 1 - 7));
1186*e5436536SAndroid Build Coastguard Worker         } else {
1187*e5436536SAndroid Build Coastguard Worker           pData->outputPeakLevel = (FIXP_DBL)0;
1188*e5436536SAndroid Build Coastguard Worker         }
1189*e5436536SAndroid Build Coastguard Worker       } else {
1190*e5436536SAndroid Build Coastguard Worker         if ((!hSelProcInput->loudnessNormalizationOn) ||
1191*e5436536SAndroid Build Coastguard Worker             (!pDrcInstructionUniDrc->drcSetTargetLoudnessPresent) ||
1192*e5436536SAndroid Build Coastguard Worker             (hSelProcInput->loudnessNormalizationOn &&
1193*e5436536SAndroid Build Coastguard Worker              _targetLoudnessInRange(pDrcInstructionUniDrc,
1194*e5436536SAndroid Build Coastguard Worker                                     hSelProcInput->targetLoudness))) {
1195*e5436536SAndroid Build Coastguard Worker           addToCandidate = 1;
1196*e5436536SAndroid Build Coastguard Worker         }
1197*e5436536SAndroid Build Coastguard Worker       }
1198*e5436536SAndroid Build Coastguard Worker     } else {
1199*e5436536SAndroid Build Coastguard Worker       addToCandidate = 1;
1200*e5436536SAndroid Build Coastguard Worker     }
1201*e5436536SAndroid Build Coastguard Worker 
1202*e5436536SAndroid Build Coastguard Worker     if (addToCandidate) {
1203*e5436536SAndroid Build Coastguard Worker       DRCDEC_SELECTION_DATA* pData =
1204*e5436536SAndroid Build Coastguard Worker           _drcdec_selection_addNew(pCandidatesPotential);
1205*e5436536SAndroid Build Coastguard Worker       if (pData == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1206*e5436536SAndroid Build Coastguard Worker 
1207*e5436536SAndroid Build Coastguard Worker       _setSelectionDataInfo(pData, loudness, loudnessNormalizationGainDb,
1208*e5436536SAndroid Build Coastguard Worker                             hSelProcInput->loudnessNormalizationGainDbMax,
1209*e5436536SAndroid Build Coastguard Worker                             loudnessDeviationMax, signalPeakLevel,
1210*e5436536SAndroid Build Coastguard Worker                             hSelProcInput->outputPeakLevelMax, 0);
1211*e5436536SAndroid Build Coastguard Worker       pData->downmixIdRequestIndex = downmixIdIndex;
1212*e5436536SAndroid Build Coastguard Worker       pData->pInst = pDrcInstructionUniDrc;
1213*e5436536SAndroid Build Coastguard Worker       pData->selectionFlag = 0;
1214*e5436536SAndroid Build Coastguard Worker     }
1215*e5436536SAndroid Build Coastguard Worker   } else {
1216*e5436536SAndroid Build Coastguard Worker     if (pDrcInstructionUniDrc->drcSetId < 0) {
1217*e5436536SAndroid Build Coastguard Worker       DRCDEC_SELECTION_DATA* pData =
1218*e5436536SAndroid Build Coastguard Worker           _drcdec_selection_addNew(pCandidatesSelected);
1219*e5436536SAndroid Build Coastguard Worker       if (pData == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1220*e5436536SAndroid Build Coastguard Worker 
1221*e5436536SAndroid Build Coastguard Worker       _setSelectionDataInfo(pData, loudness, loudnessNormalizationGainDb,
1222*e5436536SAndroid Build Coastguard Worker                             hSelProcInput->loudnessNormalizationGainDbMax,
1223*e5436536SAndroid Build Coastguard Worker                             loudnessDeviationMax, signalPeakLevel,
1224*e5436536SAndroid Build Coastguard Worker                             hSelProcInput->outputPeakLevelMax, 1);
1225*e5436536SAndroid Build Coastguard Worker 
1226*e5436536SAndroid Build Coastguard Worker       pData->downmixIdRequestIndex = downmixIdIndex;
1227*e5436536SAndroid Build Coastguard Worker       pData->pInst = pDrcInstructionUniDrc;
1228*e5436536SAndroid Build Coastguard Worker       pData->selectionFlag = 0;
1229*e5436536SAndroid Build Coastguard Worker     }
1230*e5436536SAndroid Build Coastguard Worker   }
1231*e5436536SAndroid Build Coastguard Worker 
1232*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1233*e5436536SAndroid Build Coastguard Worker }
1234*e5436536SAndroid Build Coastguard Worker 
1235*e5436536SAndroid Build Coastguard Worker /* #9: Clipping is minimized. */
_preSelectionRequirement9(SEL_PROC_INPUT * hSelProcInput,DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * pCandidatesSelected)1236*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement9(
1237*e5436536SAndroid Build Coastguard Worker     SEL_PROC_INPUT* hSelProcInput, DRCDEC_SELECTION* pCandidatesPotential,
1238*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected) {
1239*e5436536SAndroid Build Coastguard Worker   int i;
1240*e5436536SAndroid Build Coastguard Worker 
1241*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1242*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION_DATA* pCandidate =
1243*e5436536SAndroid Build Coastguard Worker         _drcdec_selection_getAt(pCandidatesPotential, i);
1244*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1245*e5436536SAndroid Build Coastguard Worker 
1246*e5436536SAndroid Build Coastguard Worker     if (pCandidate->outputPeakLevel <= hSelProcInput->outputPeakLevelMax) {
1247*e5436536SAndroid Build Coastguard Worker       if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
1248*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_NOT_OK;
1249*e5436536SAndroid Build Coastguard Worker     }
1250*e5436536SAndroid Build Coastguard Worker   }
1251*e5436536SAndroid Build Coastguard Worker 
1252*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1253*e5436536SAndroid Build Coastguard Worker }
1254*e5436536SAndroid Build Coastguard Worker 
_drcSetPreSelectionSingleInstruction(SEL_PROC_INPUT * hSelProcInput,int downmixIdIndex,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,DRC_INSTRUCTIONS_UNI_DRC * pDrcInstructionUniDrc,DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * pCandidatesSelected,SEL_PROC_CODEC_MODE codecMode)1255*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelectionSingleInstruction(
1256*e5436536SAndroid Build Coastguard Worker     SEL_PROC_INPUT* hSelProcInput, int downmixIdIndex,
1257*e5436536SAndroid Build Coastguard Worker     HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
1258*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
1259*e5436536SAndroid Build Coastguard Worker     DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
1260*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesPotential,
1261*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected, SEL_PROC_CODEC_MODE codecMode) {
1262*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
1263*e5436536SAndroid Build Coastguard Worker   int matchFound = 0;
1264*e5436536SAndroid Build Coastguard Worker   DRC_COEFFICIENTS_UNI_DRC* pCoef =
1265*e5436536SAndroid Build Coastguard Worker       selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
1266*e5436536SAndroid Build Coastguard Worker 
1267*e5436536SAndroid Build Coastguard Worker   retVal = _preSelectionRequirement123(
1268*e5436536SAndroid Build Coastguard Worker       hSelProcInput->downmixIdRequested[downmixIdIndex], pDrcInstructionUniDrc,
1269*e5436536SAndroid Build Coastguard Worker       &matchFound);
1270*e5436536SAndroid Build Coastguard Worker 
1271*e5436536SAndroid Build Coastguard Worker   if (!retVal && matchFound)
1272*e5436536SAndroid Build Coastguard Worker     retVal = _preSelectionRequirement4(pDrcInstructionUniDrc,
1273*e5436536SAndroid Build Coastguard Worker                                        hSelProcInput->dynamicRangeControlOn,
1274*e5436536SAndroid Build Coastguard Worker                                        &matchFound);
1275*e5436536SAndroid Build Coastguard Worker 
1276*e5436536SAndroid Build Coastguard Worker   if (!retVal && matchFound)
1277*e5436536SAndroid Build Coastguard Worker     retVal =
1278*e5436536SAndroid Build Coastguard Worker         _preSelectionRequirement5(pDrcInstructionUniDrc, pCoef, &matchFound);
1279*e5436536SAndroid Build Coastguard Worker 
1280*e5436536SAndroid Build Coastguard Worker   if (!retVal && matchFound)
1281*e5436536SAndroid Build Coastguard Worker     retVal = _preSelectionRequirement6(pDrcInstructionUniDrc, &matchFound);
1282*e5436536SAndroid Build Coastguard Worker 
1283*e5436536SAndroid Build Coastguard Worker   if (!retVal && matchFound)
1284*e5436536SAndroid Build Coastguard Worker     retVal = _preSelectionRequirement7(pDrcInstructionUniDrc, &matchFound);
1285*e5436536SAndroid Build Coastguard Worker 
1286*e5436536SAndroid Build Coastguard Worker   if (!retVal && matchFound)
1287*e5436536SAndroid Build Coastguard Worker     retVal = _preSelectionRequirement8(
1288*e5436536SAndroid Build Coastguard Worker         hSelProcInput, downmixIdIndex, hUniDrcConfig, hLoudnessInfoSet,
1289*e5436536SAndroid Build Coastguard Worker         pDrcInstructionUniDrc, pCandidatesPotential, pCandidatesSelected,
1290*e5436536SAndroid Build Coastguard Worker         codecMode);
1291*e5436536SAndroid Build Coastguard Worker 
1292*e5436536SAndroid Build Coastguard Worker   return retVal;
1293*e5436536SAndroid Build Coastguard Worker }
1294*e5436536SAndroid Build Coastguard Worker 
_drcSetSelectionAddCandidates(SEL_PROC_INPUT * hSelProcInput,DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * pCandidatesSelected)1295*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetSelectionAddCandidates(
1296*e5436536SAndroid Build Coastguard Worker     SEL_PROC_INPUT* hSelProcInput, DRCDEC_SELECTION* pCandidatesPotential,
1297*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected) {
1298*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
1299*e5436536SAndroid Build Coastguard Worker   int nHitCount = 0;
1300*e5436536SAndroid Build Coastguard Worker   int i;
1301*e5436536SAndroid Build Coastguard Worker 
1302*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_DATA* pCandidate = NULL;
1303*e5436536SAndroid Build Coastguard Worker   DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc = NULL;
1304*e5436536SAndroid Build Coastguard Worker 
1305*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1306*e5436536SAndroid Build Coastguard Worker     pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
1307*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1308*e5436536SAndroid Build Coastguard Worker 
1309*e5436536SAndroid Build Coastguard Worker     pDrcInstructionUniDrc = pCandidate->pInst;
1310*e5436536SAndroid Build Coastguard Worker 
1311*e5436536SAndroid Build Coastguard Worker     if (_targetLoudnessInRange(pDrcInstructionUniDrc,
1312*e5436536SAndroid Build Coastguard Worker                                hSelProcInput->targetLoudness)) {
1313*e5436536SAndroid Build Coastguard Worker       nHitCount++;
1314*e5436536SAndroid Build Coastguard Worker     }
1315*e5436536SAndroid Build Coastguard Worker   }
1316*e5436536SAndroid Build Coastguard Worker 
1317*e5436536SAndroid Build Coastguard Worker   if (nHitCount != 0) {
1318*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1319*e5436536SAndroid Build Coastguard Worker       pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
1320*e5436536SAndroid Build Coastguard Worker       if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1321*e5436536SAndroid Build Coastguard Worker 
1322*e5436536SAndroid Build Coastguard Worker       pDrcInstructionUniDrc = pCandidate->pInst;
1323*e5436536SAndroid Build Coastguard Worker 
1324*e5436536SAndroid Build Coastguard Worker       if (_targetLoudnessInRange(pDrcInstructionUniDrc,
1325*e5436536SAndroid Build Coastguard Worker                                  hSelProcInput->targetLoudness)) {
1326*e5436536SAndroid Build Coastguard Worker         if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
1327*e5436536SAndroid Build Coastguard Worker           return DRCDEC_SELECTION_PROCESS_NOT_OK;
1328*e5436536SAndroid Build Coastguard Worker       }
1329*e5436536SAndroid Build Coastguard Worker     }
1330*e5436536SAndroid Build Coastguard Worker   } else {
1331*e5436536SAndroid Build Coastguard Worker     FIXP_DBL lowestPeakLevel = MAXVAL_DBL; /* e = 7 */
1332*e5436536SAndroid Build Coastguard Worker     FIXP_DBL peakLevel = 0;                /* e = 7 */
1333*e5436536SAndroid Build Coastguard Worker 
1334*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1335*e5436536SAndroid Build Coastguard Worker       pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
1336*e5436536SAndroid Build Coastguard Worker       if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1337*e5436536SAndroid Build Coastguard Worker 
1338*e5436536SAndroid Build Coastguard Worker       peakLevel = pCandidate->outputPeakLevel;
1339*e5436536SAndroid Build Coastguard Worker 
1340*e5436536SAndroid Build Coastguard Worker       if (peakLevel < lowestPeakLevel) {
1341*e5436536SAndroid Build Coastguard Worker         lowestPeakLevel = peakLevel;
1342*e5436536SAndroid Build Coastguard Worker       }
1343*e5436536SAndroid Build Coastguard Worker     }
1344*e5436536SAndroid Build Coastguard Worker 
1345*e5436536SAndroid Build Coastguard Worker     /* add all with lowest peak level or max 1dB above */
1346*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1347*e5436536SAndroid Build Coastguard Worker       FIXP_DBL loudnessDeviationMax =
1348*e5436536SAndroid Build Coastguard Worker           ((FIXP_DBL)hSelProcInput->loudnessDeviationMax)
1349*e5436536SAndroid Build Coastguard Worker           << (DFRACT_BITS - 1 - 7); /* e = 7 */
1350*e5436536SAndroid Build Coastguard Worker 
1351*e5436536SAndroid Build Coastguard Worker       pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
1352*e5436536SAndroid Build Coastguard Worker       if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1353*e5436536SAndroid Build Coastguard Worker 
1354*e5436536SAndroid Build Coastguard Worker       peakLevel = pCandidate->outputPeakLevel;
1355*e5436536SAndroid Build Coastguard Worker 
1356*e5436536SAndroid Build Coastguard Worker       if (peakLevel == lowestPeakLevel ||
1357*e5436536SAndroid Build Coastguard Worker           peakLevel <=
1358*e5436536SAndroid Build Coastguard Worker               lowestPeakLevel + FL2FXCONST_DBL(1.0f / (float)(1 << 7))) {
1359*e5436536SAndroid Build Coastguard Worker         FIXP_DBL adjustment =
1360*e5436536SAndroid Build Coastguard Worker             fMax((FIXP_DBL)0, peakLevel - hSelProcInput->outputPeakLevelMax);
1361*e5436536SAndroid Build Coastguard Worker         adjustment = fMin(adjustment, fMax((FIXP_DBL)0, loudnessDeviationMax));
1362*e5436536SAndroid Build Coastguard Worker 
1363*e5436536SAndroid Build Coastguard Worker         pCandidate->loudnessNormalizationGainDbAdjusted -= adjustment;
1364*e5436536SAndroid Build Coastguard Worker         pCandidate->outputPeakLevel -= adjustment;
1365*e5436536SAndroid Build Coastguard Worker         pCandidate->outputLoudness -= adjustment;
1366*e5436536SAndroid Build Coastguard Worker         if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
1367*e5436536SAndroid Build Coastguard Worker           return DRCDEC_SELECTION_PROCESS_NOT_OK;
1368*e5436536SAndroid Build Coastguard Worker       }
1369*e5436536SAndroid Build Coastguard Worker     }
1370*e5436536SAndroid Build Coastguard Worker   }
1371*e5436536SAndroid Build Coastguard Worker 
1372*e5436536SAndroid Build Coastguard Worker   return retVal;
1373*e5436536SAndroid Build Coastguard Worker }
1374*e5436536SAndroid Build Coastguard Worker 
_dependentDrcInstruction(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,DRC_INSTRUCTIONS_UNI_DRC * pInst,DRC_INSTRUCTIONS_UNI_DRC ** ppDrcInstructionsDependent)1375*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _dependentDrcInstruction(
1376*e5436536SAndroid Build Coastguard Worker     HANDLE_UNI_DRC_CONFIG hUniDrcConfig, DRC_INSTRUCTIONS_UNI_DRC* pInst,
1377*e5436536SAndroid Build Coastguard Worker     DRC_INSTRUCTIONS_UNI_DRC** ppDrcInstructionsDependent) {
1378*e5436536SAndroid Build Coastguard Worker   int i;
1379*e5436536SAndroid Build Coastguard Worker   DRC_INSTRUCTIONS_UNI_DRC* pDependentDrc = NULL;
1380*e5436536SAndroid Build Coastguard Worker 
1381*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
1382*e5436536SAndroid Build Coastguard Worker     pDependentDrc =
1383*e5436536SAndroid Build Coastguard Worker         (DRC_INSTRUCTIONS_UNI_DRC*)&(hUniDrcConfig->drcInstructionsUniDrc[i]);
1384*e5436536SAndroid Build Coastguard Worker 
1385*e5436536SAndroid Build Coastguard Worker     if (pDependentDrc->drcSetId == pInst->dependsOnDrcSet) {
1386*e5436536SAndroid Build Coastguard Worker       break;
1387*e5436536SAndroid Build Coastguard Worker     }
1388*e5436536SAndroid Build Coastguard Worker   }
1389*e5436536SAndroid Build Coastguard Worker 
1390*e5436536SAndroid Build Coastguard Worker   if (i == hUniDrcConfig->drcInstructionsUniDrcCount) {
1391*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NOT_OK;
1392*e5436536SAndroid Build Coastguard Worker   }
1393*e5436536SAndroid Build Coastguard Worker 
1394*e5436536SAndroid Build Coastguard Worker   if (pDependentDrc->dependsOnDrcSetPresent == 1) {
1395*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NOT_OK;
1396*e5436536SAndroid Build Coastguard Worker   }
1397*e5436536SAndroid Build Coastguard Worker 
1398*e5436536SAndroid Build Coastguard Worker   *ppDrcInstructionsDependent = pDependentDrc;
1399*e5436536SAndroid Build Coastguard Worker 
1400*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1401*e5436536SAndroid Build Coastguard Worker }
1402*e5436536SAndroid Build Coastguard Worker 
_selectDrcSetEffectNone(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * pCandidatesSelected)1403*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _selectDrcSetEffectNone(
1404*e5436536SAndroid Build Coastguard Worker     HANDLE_UNI_DRC_CONFIG hUniDrcConfig, DRCDEC_SELECTION* pCandidatesPotential,
1405*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected) {
1406*e5436536SAndroid Build Coastguard Worker   int i;
1407*e5436536SAndroid Build Coastguard Worker 
1408*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1409*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION_DATA* pCandidate =
1410*e5436536SAndroid Build Coastguard Worker         _drcdec_selection_getAt(pCandidatesPotential, i);
1411*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1412*e5436536SAndroid Build Coastguard Worker 
1413*e5436536SAndroid Build Coastguard Worker     if ((pCandidate->pInst->drcSetEffect & 0xff) == 0) {
1414*e5436536SAndroid Build Coastguard Worker       if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
1415*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_NOT_OK;
1416*e5436536SAndroid Build Coastguard Worker     }
1417*e5436536SAndroid Build Coastguard Worker   }
1418*e5436536SAndroid Build Coastguard Worker 
1419*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1420*e5436536SAndroid Build Coastguard Worker }
1421*e5436536SAndroid Build Coastguard Worker 
_selectSingleEffectType(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,DRC_EFFECT_TYPE_REQUEST effectType,DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * pCandidatesSelected)1422*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _selectSingleEffectType(
1423*e5436536SAndroid Build Coastguard Worker     HANDLE_UNI_DRC_CONFIG hUniDrcConfig, DRC_EFFECT_TYPE_REQUEST effectType,
1424*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesPotential,
1425*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected) {
1426*e5436536SAndroid Build Coastguard Worker   int i;
1427*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
1428*e5436536SAndroid Build Coastguard Worker   DRC_INSTRUCTIONS_UNI_DRC* pInst;
1429*e5436536SAndroid Build Coastguard Worker   DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionsDependent;
1430*e5436536SAndroid Build Coastguard Worker 
1431*e5436536SAndroid Build Coastguard Worker   if (effectType == DETR_NONE) {
1432*e5436536SAndroid Build Coastguard Worker     retVal = _selectDrcSetEffectNone(hUniDrcConfig, pCandidatesPotential,
1433*e5436536SAndroid Build Coastguard Worker                                      pCandidatesSelected);
1434*e5436536SAndroid Build Coastguard Worker     if (retVal) return (retVal);
1435*e5436536SAndroid Build Coastguard Worker   } else {
1436*e5436536SAndroid Build Coastguard Worker     int effectBitPosition = 1 << (effectType - 1);
1437*e5436536SAndroid Build Coastguard Worker 
1438*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1439*e5436536SAndroid Build Coastguard Worker       DRCDEC_SELECTION_DATA* pCandidate =
1440*e5436536SAndroid Build Coastguard Worker           _drcdec_selection_getAt(pCandidatesPotential, i);
1441*e5436536SAndroid Build Coastguard Worker       if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1442*e5436536SAndroid Build Coastguard Worker 
1443*e5436536SAndroid Build Coastguard Worker       pInst = pCandidate->pInst;
1444*e5436536SAndroid Build Coastguard Worker 
1445*e5436536SAndroid Build Coastguard Worker       if (!pInst->dependsOnDrcSetPresent) {
1446*e5436536SAndroid Build Coastguard Worker         if ((pInst->drcSetEffect & effectBitPosition)) {
1447*e5436536SAndroid Build Coastguard Worker           if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
1448*e5436536SAndroid Build Coastguard Worker             return DRCDEC_SELECTION_PROCESS_NOT_OK;
1449*e5436536SAndroid Build Coastguard Worker         }
1450*e5436536SAndroid Build Coastguard Worker       } else {
1451*e5436536SAndroid Build Coastguard Worker         retVal = _dependentDrcInstruction(hUniDrcConfig, pInst,
1452*e5436536SAndroid Build Coastguard Worker                                           &pDrcInstructionsDependent);
1453*e5436536SAndroid Build Coastguard Worker         if (retVal) return (retVal);
1454*e5436536SAndroid Build Coastguard Worker 
1455*e5436536SAndroid Build Coastguard Worker         if (((pInst->drcSetEffect & effectBitPosition)) ||
1456*e5436536SAndroid Build Coastguard Worker             ((pDrcInstructionsDependent->drcSetEffect & effectBitPosition))) {
1457*e5436536SAndroid Build Coastguard Worker           if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
1458*e5436536SAndroid Build Coastguard Worker             return DRCDEC_SELECTION_PROCESS_NOT_OK;
1459*e5436536SAndroid Build Coastguard Worker         }
1460*e5436536SAndroid Build Coastguard Worker       }
1461*e5436536SAndroid Build Coastguard Worker     }
1462*e5436536SAndroid Build Coastguard Worker   }
1463*e5436536SAndroid Build Coastguard Worker 
1464*e5436536SAndroid Build Coastguard Worker   return retVal;
1465*e5436536SAndroid Build Coastguard Worker }
1466*e5436536SAndroid Build Coastguard Worker 
_selectEffectTypeFeature(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,DRC_FEATURE_REQUEST drcFeatureRequest,DRCDEC_SELECTION ** ppCandidatesPotential,DRCDEC_SELECTION ** ppCandidatesSelected)1467*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _selectEffectTypeFeature(
1468*e5436536SAndroid Build Coastguard Worker     HANDLE_UNI_DRC_CONFIG hUniDrcConfig, DRC_FEATURE_REQUEST drcFeatureRequest,
1469*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesPotential,
1470*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesSelected) {
1471*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
1472*e5436536SAndroid Build Coastguard Worker   int i;
1473*e5436536SAndroid Build Coastguard Worker   int desiredEffectTypeFound = 0;
1474*e5436536SAndroid Build Coastguard Worker 
1475*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < drcFeatureRequest.drcEffectType.numRequestsDesired; i++) {
1476*e5436536SAndroid Build Coastguard Worker     retVal = _selectSingleEffectType(
1477*e5436536SAndroid Build Coastguard Worker         hUniDrcConfig, drcFeatureRequest.drcEffectType.request[i],
1478*e5436536SAndroid Build Coastguard Worker         *ppCandidatesPotential, *ppCandidatesSelected);
1479*e5436536SAndroid Build Coastguard Worker     if (retVal) return (retVal);
1480*e5436536SAndroid Build Coastguard Worker 
1481*e5436536SAndroid Build Coastguard Worker     if (_drcdec_selection_getNumber(*ppCandidatesSelected)) {
1482*e5436536SAndroid Build Coastguard Worker       desiredEffectTypeFound = 1;
1483*e5436536SAndroid Build Coastguard Worker       _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
1484*e5436536SAndroid Build Coastguard Worker     }
1485*e5436536SAndroid Build Coastguard Worker   }
1486*e5436536SAndroid Build Coastguard Worker 
1487*e5436536SAndroid Build Coastguard Worker   if (!desiredEffectTypeFound) {
1488*e5436536SAndroid Build Coastguard Worker     for (i = drcFeatureRequest.drcEffectType.numRequestsDesired;
1489*e5436536SAndroid Build Coastguard Worker          i < drcFeatureRequest.drcEffectType.numRequests; i++) {
1490*e5436536SAndroid Build Coastguard Worker       retVal = _selectSingleEffectType(
1491*e5436536SAndroid Build Coastguard Worker           hUniDrcConfig, drcFeatureRequest.drcEffectType.request[i],
1492*e5436536SAndroid Build Coastguard Worker           *ppCandidatesPotential, *ppCandidatesSelected);
1493*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
1494*e5436536SAndroid Build Coastguard Worker 
1495*e5436536SAndroid Build Coastguard Worker       if (_drcdec_selection_getNumber(*ppCandidatesSelected)) {
1496*e5436536SAndroid Build Coastguard Worker         _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
1497*e5436536SAndroid Build Coastguard Worker         break;
1498*e5436536SAndroid Build Coastguard Worker       }
1499*e5436536SAndroid Build Coastguard Worker     }
1500*e5436536SAndroid Build Coastguard Worker   }
1501*e5436536SAndroid Build Coastguard Worker 
1502*e5436536SAndroid Build Coastguard Worker   _swapSelection(ppCandidatesPotential, ppCandidatesSelected);
1503*e5436536SAndroid Build Coastguard Worker 
1504*e5436536SAndroid Build Coastguard Worker   return retVal;
1505*e5436536SAndroid Build Coastguard Worker }
1506*e5436536SAndroid Build Coastguard Worker 
_selectDynamicRange(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,DRC_FEATURE_REQUEST drcFeatureRequest,UCHAR * pDownmixIdRequested,int albumMode,DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * ppCandidatesSelected)1507*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _selectDynamicRange(
1508*e5436536SAndroid Build Coastguard Worker     HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
1509*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
1510*e5436536SAndroid Build Coastguard Worker     DRC_FEATURE_REQUEST drcFeatureRequest, UCHAR* pDownmixIdRequested,
1511*e5436536SAndroid Build Coastguard Worker     int albumMode, DRCDEC_SELECTION* pCandidatesPotential,
1512*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* ppCandidatesSelected) {
1513*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
1514*e5436536SAndroid Build Coastguard Worker   int i;
1515*e5436536SAndroid Build Coastguard Worker   int peakToAveragePresent;
1516*e5436536SAndroid Build Coastguard Worker   FIXP_DBL peakToAverage;
1517*e5436536SAndroid Build Coastguard Worker 
1518*e5436536SAndroid Build Coastguard Worker   FIXP_DBL minVal = MAXVAL_DBL;
1519*e5436536SAndroid Build Coastguard Worker   FIXP_DBL val = 0;
1520*e5436536SAndroid Build Coastguard Worker 
1521*e5436536SAndroid Build Coastguard Worker   int numSelectedCandidates = _drcdec_selection_getNumber(ppCandidatesSelected);
1522*e5436536SAndroid Build Coastguard Worker 
1523*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1524*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION_DATA* pCandidate =
1525*e5436536SAndroid Build Coastguard Worker         _drcdec_selection_getAt(pCandidatesPotential, i);
1526*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1527*e5436536SAndroid Build Coastguard Worker 
1528*e5436536SAndroid Build Coastguard Worker     retVal = _dynamicRangeMeasurement(
1529*e5436536SAndroid Build Coastguard Worker         hLoudnessInfoSet, pCandidate->pInst,
1530*e5436536SAndroid Build Coastguard Worker         pDownmixIdRequested[pCandidate->downmixIdRequestIndex],
1531*e5436536SAndroid Build Coastguard Worker         drcFeatureRequest.dynamicRange.measurementRequestType, albumMode,
1532*e5436536SAndroid Build Coastguard Worker         &peakToAveragePresent, &peakToAverage);
1533*e5436536SAndroid Build Coastguard Worker     if (retVal) return (retVal);
1534*e5436536SAndroid Build Coastguard Worker 
1535*e5436536SAndroid Build Coastguard Worker     if (peakToAveragePresent) {
1536*e5436536SAndroid Build Coastguard Worker       if (!drcFeatureRequest.dynamicRange.requestedIsRange) {
1537*e5436536SAndroid Build Coastguard Worker         val = fAbs(drcFeatureRequest.dynamicRange.requestValue - peakToAverage);
1538*e5436536SAndroid Build Coastguard Worker 
1539*e5436536SAndroid Build Coastguard Worker         if (minVal > val) {
1540*e5436536SAndroid Build Coastguard Worker           minVal = val;
1541*e5436536SAndroid Build Coastguard Worker 
1542*e5436536SAndroid Build Coastguard Worker           _drcdec_selection_setNumber(ppCandidatesSelected,
1543*e5436536SAndroid Build Coastguard Worker                                       numSelectedCandidates);
1544*e5436536SAndroid Build Coastguard Worker         }
1545*e5436536SAndroid Build Coastguard Worker         if (_drcdec_selection_add(ppCandidatesSelected, pCandidate) == NULL)
1546*e5436536SAndroid Build Coastguard Worker           return DRCDEC_SELECTION_PROCESS_NOT_OK;
1547*e5436536SAndroid Build Coastguard Worker       } else {
1548*e5436536SAndroid Build Coastguard Worker         if ((peakToAverage >= drcFeatureRequest.dynamicRange.requestValueMin) &&
1549*e5436536SAndroid Build Coastguard Worker             (peakToAverage <= drcFeatureRequest.dynamicRange.requestValueMax)) {
1550*e5436536SAndroid Build Coastguard Worker           if (_drcdec_selection_add(ppCandidatesSelected, pCandidate) == NULL)
1551*e5436536SAndroid Build Coastguard Worker             return DRCDEC_SELECTION_PROCESS_NOT_OK;
1552*e5436536SAndroid Build Coastguard Worker         }
1553*e5436536SAndroid Build Coastguard Worker       }
1554*e5436536SAndroid Build Coastguard Worker     }
1555*e5436536SAndroid Build Coastguard Worker   }
1556*e5436536SAndroid Build Coastguard Worker 
1557*e5436536SAndroid Build Coastguard Worker   return retVal;
1558*e5436536SAndroid Build Coastguard Worker }
1559*e5436536SAndroid Build Coastguard Worker 
_selectSingleDrcCharacteristic(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,int requestedDrcCharacteristic,DRCDEC_SELECTION ** ppCandidatesPotential,DRCDEC_SELECTION ** ppCandidatesSelected)1560*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _selectSingleDrcCharacteristic(
1561*e5436536SAndroid Build Coastguard Worker     HANDLE_UNI_DRC_CONFIG hUniDrcConfig, int requestedDrcCharacteristic,
1562*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesPotential,
1563*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesSelected) {
1564*e5436536SAndroid Build Coastguard Worker   int i, j, b;
1565*e5436536SAndroid Build Coastguard Worker   int hit = 0;
1566*e5436536SAndroid Build Coastguard Worker 
1567*e5436536SAndroid Build Coastguard Worker   DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL;
1568*e5436536SAndroid Build Coastguard Worker   DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL;
1569*e5436536SAndroid Build Coastguard Worker   GAIN_SET* pGainSet = NULL;
1570*e5436536SAndroid Build Coastguard Worker 
1571*e5436536SAndroid Build Coastguard Worker   if (requestedDrcCharacteristic < 1) {
1572*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NOT_OK;
1573*e5436536SAndroid Build Coastguard Worker   }
1574*e5436536SAndroid Build Coastguard Worker 
1575*e5436536SAndroid Build Coastguard Worker   pCoef = selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
1576*e5436536SAndroid Build Coastguard Worker 
1577*e5436536SAndroid Build Coastguard Worker   if (pCoef == NULL) /* check for parametricDRC */
1578*e5436536SAndroid Build Coastguard Worker   {
1579*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1580*e5436536SAndroid Build Coastguard Worker   }
1581*e5436536SAndroid Build Coastguard Worker 
1582*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(*ppCandidatesPotential); i++) {
1583*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION_DATA* pCandidate =
1584*e5436536SAndroid Build Coastguard Worker         _drcdec_selection_getAt(*ppCandidatesPotential, i);
1585*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1586*e5436536SAndroid Build Coastguard Worker 
1587*e5436536SAndroid Build Coastguard Worker     pInst = pCandidate->pInst;
1588*e5436536SAndroid Build Coastguard Worker 
1589*e5436536SAndroid Build Coastguard Worker     hit = 0;
1590*e5436536SAndroid Build Coastguard Worker 
1591*e5436536SAndroid Build Coastguard Worker     for (j = 0; j < pInst->nDrcChannelGroups; j++) {
1592*e5436536SAndroid Build Coastguard Worker       int bandCount = 0;
1593*e5436536SAndroid Build Coastguard Worker       int indexDrcCoeff = pInst->gainSetIndexForChannelGroup[j];
1594*e5436536SAndroid Build Coastguard Worker 
1595*e5436536SAndroid Build Coastguard Worker       if (indexDrcCoeff > pCoef->gainSetCount - 1) /* check for parametricDRC */
1596*e5436536SAndroid Build Coastguard Worker       {
1597*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1598*e5436536SAndroid Build Coastguard Worker       }
1599*e5436536SAndroid Build Coastguard Worker 
1600*e5436536SAndroid Build Coastguard Worker       pGainSet = &(pCoef->gainSet[indexDrcCoeff]);
1601*e5436536SAndroid Build Coastguard Worker       bandCount = pGainSet->bandCount;
1602*e5436536SAndroid Build Coastguard Worker 
1603*e5436536SAndroid Build Coastguard Worker       for (b = 0; b < bandCount; b++) {
1604*e5436536SAndroid Build Coastguard Worker         if ((pGainSet->drcCharacteristic[b].isCICP) &&
1605*e5436536SAndroid Build Coastguard Worker             (pGainSet->drcCharacteristic[b].cicpIndex ==
1606*e5436536SAndroid Build Coastguard Worker              requestedDrcCharacteristic)) {
1607*e5436536SAndroid Build Coastguard Worker           hit = 1;
1608*e5436536SAndroid Build Coastguard Worker           break;
1609*e5436536SAndroid Build Coastguard Worker         }
1610*e5436536SAndroid Build Coastguard Worker       }
1611*e5436536SAndroid Build Coastguard Worker 
1612*e5436536SAndroid Build Coastguard Worker       if (hit) break;
1613*e5436536SAndroid Build Coastguard Worker     }
1614*e5436536SAndroid Build Coastguard Worker 
1615*e5436536SAndroid Build Coastguard Worker     if (hit) {
1616*e5436536SAndroid Build Coastguard Worker       if (_drcdec_selection_add(*ppCandidatesSelected, pCandidate) == NULL)
1617*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_NOT_OK;
1618*e5436536SAndroid Build Coastguard Worker     }
1619*e5436536SAndroid Build Coastguard Worker   }
1620*e5436536SAndroid Build Coastguard Worker 
1621*e5436536SAndroid Build Coastguard Worker   if (_drcdec_selection_getNumber(*ppCandidatesSelected)) {
1622*e5436536SAndroid Build Coastguard Worker     _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
1623*e5436536SAndroid Build Coastguard Worker   }
1624*e5436536SAndroid Build Coastguard Worker 
1625*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1626*e5436536SAndroid Build Coastguard Worker }
1627*e5436536SAndroid Build Coastguard Worker 
_selectDrcCharacteristic(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,int drcCharacteristicRequested,DRCDEC_SELECTION ** ppCandidatesPotential,DRCDEC_SELECTION ** ppCandidatesSelected)1628*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _selectDrcCharacteristic(
1629*e5436536SAndroid Build Coastguard Worker     HANDLE_UNI_DRC_CONFIG hUniDrcConfig, int drcCharacteristicRequested,
1630*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesPotential,
1631*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesSelected) {
1632*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
1633*e5436536SAndroid Build Coastguard Worker 
1634*e5436536SAndroid Build Coastguard Worker   const int secondTry[12] = {0, 2, 3, 4, 5, 6, 5, 9, 10, 7, 8, 10};
1635*e5436536SAndroid Build Coastguard Worker 
1636*e5436536SAndroid Build Coastguard Worker   retVal = _selectSingleDrcCharacteristic(
1637*e5436536SAndroid Build Coastguard Worker       hUniDrcConfig, drcCharacteristicRequested, ppCandidatesPotential,
1638*e5436536SAndroid Build Coastguard Worker       ppCandidatesSelected);
1639*e5436536SAndroid Build Coastguard Worker   if (retVal) return (retVal);
1640*e5436536SAndroid Build Coastguard Worker 
1641*e5436536SAndroid Build Coastguard Worker   if ((drcCharacteristicRequested <= 11) &&
1642*e5436536SAndroid Build Coastguard Worker       (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0)) {
1643*e5436536SAndroid Build Coastguard Worker     retVal = _selectSingleDrcCharacteristic(
1644*e5436536SAndroid Build Coastguard Worker         hUniDrcConfig, secondTry[drcCharacteristicRequested],
1645*e5436536SAndroid Build Coastguard Worker         ppCandidatesPotential, ppCandidatesSelected);
1646*e5436536SAndroid Build Coastguard Worker     if (retVal) return (retVal);
1647*e5436536SAndroid Build Coastguard Worker   }
1648*e5436536SAndroid Build Coastguard Worker 
1649*e5436536SAndroid Build Coastguard Worker   if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
1650*e5436536SAndroid Build Coastguard Worker     if ((drcCharacteristicRequested >= 2) &&
1651*e5436536SAndroid Build Coastguard Worker         (drcCharacteristicRequested <= 5)) {
1652*e5436536SAndroid Build Coastguard Worker       retVal = _selectSingleDrcCharacteristic(
1653*e5436536SAndroid Build Coastguard Worker           hUniDrcConfig, drcCharacteristicRequested - 1, ppCandidatesPotential,
1654*e5436536SAndroid Build Coastguard Worker           ppCandidatesSelected);
1655*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
1656*e5436536SAndroid Build Coastguard Worker     } else if (drcCharacteristicRequested == 11) {
1657*e5436536SAndroid Build Coastguard Worker       retVal = _selectSingleDrcCharacteristic(
1658*e5436536SAndroid Build Coastguard Worker           hUniDrcConfig, 9, ppCandidatesPotential, ppCandidatesSelected);
1659*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
1660*e5436536SAndroid Build Coastguard Worker     }
1661*e5436536SAndroid Build Coastguard Worker   }
1662*e5436536SAndroid Build Coastguard Worker 
1663*e5436536SAndroid Build Coastguard Worker   _swapSelection(ppCandidatesPotential, ppCandidatesSelected);
1664*e5436536SAndroid Build Coastguard Worker 
1665*e5436536SAndroid Build Coastguard Worker   return retVal;
1666*e5436536SAndroid Build Coastguard Worker }
1667*e5436536SAndroid Build Coastguard Worker 
_drcSetFinalSelection_peakValue0(DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * pCandidatesSelected)1668*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_peakValue0(
1669*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesPotential,
1670*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected) {
1671*e5436536SAndroid Build Coastguard Worker   int i;
1672*e5436536SAndroid Build Coastguard Worker 
1673*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1674*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION_DATA* pCandidate =
1675*e5436536SAndroid Build Coastguard Worker         _drcdec_selection_getAt(pCandidatesPotential, i);
1676*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1677*e5436536SAndroid Build Coastguard Worker 
1678*e5436536SAndroid Build Coastguard Worker     if (pCandidate->outputPeakLevel <= FIXP_DBL(0)) {
1679*e5436536SAndroid Build Coastguard Worker       if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
1680*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_NOT_OK;
1681*e5436536SAndroid Build Coastguard Worker     }
1682*e5436536SAndroid Build Coastguard Worker   }
1683*e5436536SAndroid Build Coastguard Worker 
1684*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1685*e5436536SAndroid Build Coastguard Worker }
1686*e5436536SAndroid Build Coastguard Worker 
_drcSetFinalSelection_downmixId(HANDLE_SEL_PROC_INPUT hSelProcInput,DRCDEC_SELECTION ** ppCandidatesPotential,DRCDEC_SELECTION ** ppCandidatesSelected)1687*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_downmixId(
1688*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput,
1689*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesPotential,
1690*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesSelected) {
1691*e5436536SAndroid Build Coastguard Worker   int i, j;
1692*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_DATA* pCandidate = NULL;
1693*e5436536SAndroid Build Coastguard Worker   DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL;
1694*e5436536SAndroid Build Coastguard Worker 
1695*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(*ppCandidatesPotential); i++) {
1696*e5436536SAndroid Build Coastguard Worker     pCandidate = _drcdec_selection_getAt(*ppCandidatesPotential, i);
1697*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1698*e5436536SAndroid Build Coastguard Worker 
1699*e5436536SAndroid Build Coastguard Worker     pInst = pCandidate->pInst;
1700*e5436536SAndroid Build Coastguard Worker 
1701*e5436536SAndroid Build Coastguard Worker     for (j = 0; j < pInst->downmixIdCount; j++) {
1702*e5436536SAndroid Build Coastguard Worker       if (DOWNMIX_ID_BASE_LAYOUT != pInst->downmixId[j] &&
1703*e5436536SAndroid Build Coastguard Worker           DOWNMIX_ID_ANY_DOWNMIX != pInst->downmixId[j] &&
1704*e5436536SAndroid Build Coastguard Worker           hSelProcInput
1705*e5436536SAndroid Build Coastguard Worker                   ->downmixIdRequested[pCandidate->downmixIdRequestIndex] ==
1706*e5436536SAndroid Build Coastguard Worker               pInst->downmixId[j]) {
1707*e5436536SAndroid Build Coastguard Worker         if (_drcdec_selection_add(*ppCandidatesSelected, pCandidate) == NULL)
1708*e5436536SAndroid Build Coastguard Worker           return DRCDEC_SELECTION_PROCESS_NOT_OK;
1709*e5436536SAndroid Build Coastguard Worker       }
1710*e5436536SAndroid Build Coastguard Worker     }
1711*e5436536SAndroid Build Coastguard Worker   }
1712*e5436536SAndroid Build Coastguard Worker 
1713*e5436536SAndroid Build Coastguard Worker   if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
1714*e5436536SAndroid Build Coastguard Worker     _swapSelection(ppCandidatesPotential, ppCandidatesSelected);
1715*e5436536SAndroid Build Coastguard Worker   }
1716*e5436536SAndroid Build Coastguard Worker 
1717*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1718*e5436536SAndroid Build Coastguard Worker }
1719*e5436536SAndroid Build Coastguard Worker 
_crossSum(int value)1720*e5436536SAndroid Build Coastguard Worker static int _crossSum(int value) {
1721*e5436536SAndroid Build Coastguard Worker   int sum = 0;
1722*e5436536SAndroid Build Coastguard Worker 
1723*e5436536SAndroid Build Coastguard Worker   while (value != 0) {
1724*e5436536SAndroid Build Coastguard Worker     if ((value & 1) == 1) {
1725*e5436536SAndroid Build Coastguard Worker       sum++;
1726*e5436536SAndroid Build Coastguard Worker     }
1727*e5436536SAndroid Build Coastguard Worker 
1728*e5436536SAndroid Build Coastguard Worker     value >>= 1;
1729*e5436536SAndroid Build Coastguard Worker   }
1730*e5436536SAndroid Build Coastguard Worker 
1731*e5436536SAndroid Build Coastguard Worker   return sum;
1732*e5436536SAndroid Build Coastguard Worker }
1733*e5436536SAndroid Build Coastguard Worker 
_drcSetFinalSelection_effectTypes(DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * pCandidatesSelected)1734*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_effectTypes(
1735*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesPotential,
1736*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected) {
1737*e5436536SAndroid Build Coastguard Worker   int i;
1738*e5436536SAndroid Build Coastguard Worker   int minNumEffects = 1000;
1739*e5436536SAndroid Build Coastguard Worker   int numEffects = 0;
1740*e5436536SAndroid Build Coastguard Worker   int effects = 0;
1741*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_DATA* pCandidate = NULL;
1742*e5436536SAndroid Build Coastguard Worker   DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL;
1743*e5436536SAndroid Build Coastguard Worker 
1744*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1745*e5436536SAndroid Build Coastguard Worker     pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
1746*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1747*e5436536SAndroid Build Coastguard Worker 
1748*e5436536SAndroid Build Coastguard Worker     pInst = pCandidate->pInst;
1749*e5436536SAndroid Build Coastguard Worker 
1750*e5436536SAndroid Build Coastguard Worker     effects = pInst->drcSetEffect;
1751*e5436536SAndroid Build Coastguard Worker     effects &= 0xffff ^ (EB_GENERAL_COMPR);
1752*e5436536SAndroid Build Coastguard Worker     numEffects = _crossSum(effects);
1753*e5436536SAndroid Build Coastguard Worker 
1754*e5436536SAndroid Build Coastguard Worker     if (numEffects < minNumEffects) {
1755*e5436536SAndroid Build Coastguard Worker       minNumEffects = numEffects;
1756*e5436536SAndroid Build Coastguard Worker     }
1757*e5436536SAndroid Build Coastguard Worker   }
1758*e5436536SAndroid Build Coastguard Worker 
1759*e5436536SAndroid Build Coastguard Worker   /* add all with minimum number of effects */
1760*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1761*e5436536SAndroid Build Coastguard Worker     pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
1762*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1763*e5436536SAndroid Build Coastguard Worker 
1764*e5436536SAndroid Build Coastguard Worker     pInst = pCandidate->pInst;
1765*e5436536SAndroid Build Coastguard Worker 
1766*e5436536SAndroid Build Coastguard Worker     effects = pInst->drcSetEffect;
1767*e5436536SAndroid Build Coastguard Worker     effects &= 0xffff ^ (EB_GENERAL_COMPR);
1768*e5436536SAndroid Build Coastguard Worker     numEffects = _crossSum(effects);
1769*e5436536SAndroid Build Coastguard Worker 
1770*e5436536SAndroid Build Coastguard Worker     if (numEffects == minNumEffects) {
1771*e5436536SAndroid Build Coastguard Worker       if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
1772*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_NOT_OK;
1773*e5436536SAndroid Build Coastguard Worker     }
1774*e5436536SAndroid Build Coastguard Worker   }
1775*e5436536SAndroid Build Coastguard Worker 
1776*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1777*e5436536SAndroid Build Coastguard Worker }
1778*e5436536SAndroid Build Coastguard Worker 
_selectSmallestTargetLoudnessValueUpper(DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * pCandidatesSelected)1779*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _selectSmallestTargetLoudnessValueUpper(
1780*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesPotential,
1781*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected) {
1782*e5436536SAndroid Build Coastguard Worker   int i;
1783*e5436536SAndroid Build Coastguard Worker   SCHAR minVal = 0x7F;
1784*e5436536SAndroid Build Coastguard Worker   SCHAR val = 0;
1785*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_DATA* pCandidate = NULL;
1786*e5436536SAndroid Build Coastguard Worker 
1787*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1788*e5436536SAndroid Build Coastguard Worker     pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
1789*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1790*e5436536SAndroid Build Coastguard Worker 
1791*e5436536SAndroid Build Coastguard Worker     val = pCandidate->pInst->drcSetTargetLoudnessValueUpper;
1792*e5436536SAndroid Build Coastguard Worker 
1793*e5436536SAndroid Build Coastguard Worker     if (val < minVal) {
1794*e5436536SAndroid Build Coastguard Worker       minVal = val;
1795*e5436536SAndroid Build Coastguard Worker     }
1796*e5436536SAndroid Build Coastguard Worker   }
1797*e5436536SAndroid Build Coastguard Worker 
1798*e5436536SAndroid Build Coastguard Worker   /* add all with same smallest drcSetTargetLoudnessValueUpper */
1799*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1800*e5436536SAndroid Build Coastguard Worker     pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
1801*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1802*e5436536SAndroid Build Coastguard Worker 
1803*e5436536SAndroid Build Coastguard Worker     val = pCandidate->pInst->drcSetTargetLoudnessValueUpper;
1804*e5436536SAndroid Build Coastguard Worker 
1805*e5436536SAndroid Build Coastguard Worker     if (val == minVal) {
1806*e5436536SAndroid Build Coastguard Worker       if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
1807*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_NOT_OK;
1808*e5436536SAndroid Build Coastguard Worker     }
1809*e5436536SAndroid Build Coastguard Worker   }
1810*e5436536SAndroid Build Coastguard Worker 
1811*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1812*e5436536SAndroid Build Coastguard Worker }
1813*e5436536SAndroid Build Coastguard Worker 
_drcSetFinalSelection_targetLoudness(FIXP_DBL targetLoudness,DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * pCandidatesSelected)1814*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_targetLoudness(
1815*e5436536SAndroid Build Coastguard Worker     FIXP_DBL targetLoudness, DRCDEC_SELECTION* pCandidatesPotential,
1816*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected) {
1817*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
1818*e5436536SAndroid Build Coastguard Worker   int i;
1819*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_DATA* pCandidate = NULL;
1820*e5436536SAndroid Build Coastguard Worker 
1821*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1822*e5436536SAndroid Build Coastguard Worker     pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
1823*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1824*e5436536SAndroid Build Coastguard Worker 
1825*e5436536SAndroid Build Coastguard Worker     if (pCandidate->selectionFlag == 0) {
1826*e5436536SAndroid Build Coastguard Worker       if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
1827*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_NOT_OK;
1828*e5436536SAndroid Build Coastguard Worker     }
1829*e5436536SAndroid Build Coastguard Worker   }
1830*e5436536SAndroid Build Coastguard Worker 
1831*e5436536SAndroid Build Coastguard Worker   if (_drcdec_selection_getNumber(pCandidatesSelected) == 0) {
1832*e5436536SAndroid Build Coastguard Worker     retVal = _selectSmallestTargetLoudnessValueUpper(pCandidatesPotential,
1833*e5436536SAndroid Build Coastguard Worker                                                      pCandidatesSelected);
1834*e5436536SAndroid Build Coastguard Worker     if (retVal) return (retVal);
1835*e5436536SAndroid Build Coastguard Worker   }
1836*e5436536SAndroid Build Coastguard Worker 
1837*e5436536SAndroid Build Coastguard Worker   if (_drcdec_selection_getNumber(pCandidatesSelected) > 1) {
1838*e5436536SAndroid Build Coastguard Worker     DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc = NULL;
1839*e5436536SAndroid Build Coastguard Worker 
1840*e5436536SAndroid Build Coastguard Worker     _swapSelectionAndClear(&pCandidatesPotential, &pCandidatesSelected);
1841*e5436536SAndroid Build Coastguard Worker 
1842*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1843*e5436536SAndroid Build Coastguard Worker       pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
1844*e5436536SAndroid Build Coastguard Worker       if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1845*e5436536SAndroid Build Coastguard Worker 
1846*e5436536SAndroid Build Coastguard Worker       pDrcInstructionUniDrc = pCandidate->pInst;
1847*e5436536SAndroid Build Coastguard Worker 
1848*e5436536SAndroid Build Coastguard Worker       if (_targetLoudnessInRange(pDrcInstructionUniDrc, targetLoudness)) {
1849*e5436536SAndroid Build Coastguard Worker         if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
1850*e5436536SAndroid Build Coastguard Worker           return DRCDEC_SELECTION_PROCESS_NOT_OK;
1851*e5436536SAndroid Build Coastguard Worker       }
1852*e5436536SAndroid Build Coastguard Worker     }
1853*e5436536SAndroid Build Coastguard Worker 
1854*e5436536SAndroid Build Coastguard Worker     if (_drcdec_selection_getNumber(pCandidatesSelected) > 1) {
1855*e5436536SAndroid Build Coastguard Worker       _swapSelectionAndClear(&pCandidatesPotential, &pCandidatesSelected);
1856*e5436536SAndroid Build Coastguard Worker 
1857*e5436536SAndroid Build Coastguard Worker       retVal = _selectSmallestTargetLoudnessValueUpper(pCandidatesPotential,
1858*e5436536SAndroid Build Coastguard Worker                                                        pCandidatesSelected);
1859*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
1860*e5436536SAndroid Build Coastguard Worker     }
1861*e5436536SAndroid Build Coastguard Worker   }
1862*e5436536SAndroid Build Coastguard Worker 
1863*e5436536SAndroid Build Coastguard Worker   return retVal;
1864*e5436536SAndroid Build Coastguard Worker }
1865*e5436536SAndroid Build Coastguard Worker 
_drcSetFinalSelection_peakValueLargest(DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * pCandidatesSelected)1866*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_peakValueLargest(
1867*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesPotential,
1868*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected) {
1869*e5436536SAndroid Build Coastguard Worker   int i;
1870*e5436536SAndroid Build Coastguard Worker   FIXP_DBL largestPeakLevel = MINVAL_DBL;
1871*e5436536SAndroid Build Coastguard Worker   FIXP_DBL peakLevel = 0;
1872*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_DATA* pCandidate = NULL;
1873*e5436536SAndroid Build Coastguard Worker 
1874*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1875*e5436536SAndroid Build Coastguard Worker     pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
1876*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1877*e5436536SAndroid Build Coastguard Worker 
1878*e5436536SAndroid Build Coastguard Worker     peakLevel = pCandidate->outputPeakLevel;
1879*e5436536SAndroid Build Coastguard Worker 
1880*e5436536SAndroid Build Coastguard Worker     if (peakLevel > largestPeakLevel) {
1881*e5436536SAndroid Build Coastguard Worker       largestPeakLevel = peakLevel;
1882*e5436536SAndroid Build Coastguard Worker     }
1883*e5436536SAndroid Build Coastguard Worker   }
1884*e5436536SAndroid Build Coastguard Worker 
1885*e5436536SAndroid Build Coastguard Worker   /* add all with same largest peak level */
1886*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1887*e5436536SAndroid Build Coastguard Worker     pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
1888*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1889*e5436536SAndroid Build Coastguard Worker 
1890*e5436536SAndroid Build Coastguard Worker     peakLevel = pCandidate->outputPeakLevel;
1891*e5436536SAndroid Build Coastguard Worker 
1892*e5436536SAndroid Build Coastguard Worker     if (peakLevel == largestPeakLevel) {
1893*e5436536SAndroid Build Coastguard Worker       if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
1894*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_NOT_OK;
1895*e5436536SAndroid Build Coastguard Worker     }
1896*e5436536SAndroid Build Coastguard Worker   }
1897*e5436536SAndroid Build Coastguard Worker 
1898*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1899*e5436536SAndroid Build Coastguard Worker }
1900*e5436536SAndroid Build Coastguard Worker 
_drcSetFinalSelection_drcSetId(DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * pCandidatesSelected)1901*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_drcSetId(
1902*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesPotential,
1903*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected) {
1904*e5436536SAndroid Build Coastguard Worker   int i;
1905*e5436536SAndroid Build Coastguard Worker   int largestId = -1000;
1906*e5436536SAndroid Build Coastguard Worker   int id = 0;
1907*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_DATA* pCandidate = NULL;
1908*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_DATA* pCandidateSelected = NULL;
1909*e5436536SAndroid Build Coastguard Worker 
1910*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
1911*e5436536SAndroid Build Coastguard Worker     pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
1912*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
1913*e5436536SAndroid Build Coastguard Worker 
1914*e5436536SAndroid Build Coastguard Worker     id = pCandidate->pInst->drcSetId;
1915*e5436536SAndroid Build Coastguard Worker 
1916*e5436536SAndroid Build Coastguard Worker     if (id > largestId) {
1917*e5436536SAndroid Build Coastguard Worker       largestId = id;
1918*e5436536SAndroid Build Coastguard Worker       pCandidateSelected = pCandidate;
1919*e5436536SAndroid Build Coastguard Worker     }
1920*e5436536SAndroid Build Coastguard Worker   }
1921*e5436536SAndroid Build Coastguard Worker 
1922*e5436536SAndroid Build Coastguard Worker   if (pCandidateSelected != NULL) {
1923*e5436536SAndroid Build Coastguard Worker     if (_drcdec_selection_add(pCandidatesSelected, pCandidateSelected) == NULL)
1924*e5436536SAndroid Build Coastguard Worker       return DRCDEC_SELECTION_PROCESS_NOT_OK;
1925*e5436536SAndroid Build Coastguard Worker   } else {
1926*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NOT_OK;
1927*e5436536SAndroid Build Coastguard Worker   }
1928*e5436536SAndroid Build Coastguard Worker 
1929*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
1930*e5436536SAndroid Build Coastguard Worker }
1931*e5436536SAndroid Build Coastguard Worker 
_drcSetFinalSelection(HANDLE_SEL_PROC_INPUT hSelProcInput,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,DRCDEC_SELECTION ** ppCandidatesPotential,DRCDEC_SELECTION ** ppCandidatesSelected,SEL_PROC_CODEC_MODE codecMode)1932*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection(
1933*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
1934*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesPotential,
1935*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesSelected, SEL_PROC_CODEC_MODE codecMode) {
1936*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
1937*e5436536SAndroid Build Coastguard Worker 
1938*e5436536SAndroid Build Coastguard Worker   if (_drcdec_selection_getNumber(*ppCandidatesPotential) == 0) {
1939*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NOT_OK;
1940*e5436536SAndroid Build Coastguard Worker   } else if (_drcdec_selection_getNumber(*ppCandidatesPotential) == 1) {
1941*e5436536SAndroid Build Coastguard Worker     _swapSelection(ppCandidatesPotential, ppCandidatesSelected);
1942*e5436536SAndroid Build Coastguard Worker     /* finished */
1943*e5436536SAndroid Build Coastguard Worker   } else /* > 1 */
1944*e5436536SAndroid Build Coastguard Worker   {
1945*e5436536SAndroid Build Coastguard Worker     retVal = _drcSetFinalSelection_peakValue0(*ppCandidatesPotential,
1946*e5436536SAndroid Build Coastguard Worker                                               *ppCandidatesSelected);
1947*e5436536SAndroid Build Coastguard Worker     if (retVal) return (retVal);
1948*e5436536SAndroid Build Coastguard Worker 
1949*e5436536SAndroid Build Coastguard Worker     if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
1950*e5436536SAndroid Build Coastguard Worker       _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
1951*e5436536SAndroid Build Coastguard Worker       retVal = _drcSetFinalSelection_downmixId(
1952*e5436536SAndroid Build Coastguard Worker           hSelProcInput, ppCandidatesPotential, ppCandidatesSelected);
1953*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
1954*e5436536SAndroid Build Coastguard Worker     }
1955*e5436536SAndroid Build Coastguard Worker 
1956*e5436536SAndroid Build Coastguard Worker     if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
1957*e5436536SAndroid Build Coastguard Worker       _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
1958*e5436536SAndroid Build Coastguard Worker       retVal = _drcSetFinalSelection_effectTypes(*ppCandidatesPotential,
1959*e5436536SAndroid Build Coastguard Worker                                                  *ppCandidatesSelected);
1960*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
1961*e5436536SAndroid Build Coastguard Worker     }
1962*e5436536SAndroid Build Coastguard Worker 
1963*e5436536SAndroid Build Coastguard Worker     if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
1964*e5436536SAndroid Build Coastguard Worker       _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
1965*e5436536SAndroid Build Coastguard Worker       retVal = _drcSetFinalSelection_targetLoudness(
1966*e5436536SAndroid Build Coastguard Worker           hSelProcInput->targetLoudness, *ppCandidatesPotential,
1967*e5436536SAndroid Build Coastguard Worker           *ppCandidatesSelected);
1968*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
1969*e5436536SAndroid Build Coastguard Worker     }
1970*e5436536SAndroid Build Coastguard Worker 
1971*e5436536SAndroid Build Coastguard Worker     if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
1972*e5436536SAndroid Build Coastguard Worker       _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
1973*e5436536SAndroid Build Coastguard Worker       retVal = _drcSetFinalSelection_peakValueLargest(*ppCandidatesPotential,
1974*e5436536SAndroid Build Coastguard Worker                                                       *ppCandidatesSelected);
1975*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
1976*e5436536SAndroid Build Coastguard Worker     }
1977*e5436536SAndroid Build Coastguard Worker 
1978*e5436536SAndroid Build Coastguard Worker     if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
1979*e5436536SAndroid Build Coastguard Worker       _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
1980*e5436536SAndroid Build Coastguard Worker       retVal = _drcSetFinalSelection_drcSetId(*ppCandidatesPotential,
1981*e5436536SAndroid Build Coastguard Worker                                               *ppCandidatesSelected);
1982*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
1983*e5436536SAndroid Build Coastguard Worker     }
1984*e5436536SAndroid Build Coastguard Worker   }
1985*e5436536SAndroid Build Coastguard Worker 
1986*e5436536SAndroid Build Coastguard Worker   if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
1987*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NOT_OK;
1988*e5436536SAndroid Build Coastguard Worker   }
1989*e5436536SAndroid Build Coastguard Worker 
1990*e5436536SAndroid Build Coastguard Worker   return retVal;
1991*e5436536SAndroid Build Coastguard Worker }
1992*e5436536SAndroid Build Coastguard Worker 
_generateVirtualDrcSets(HANDLE_SEL_PROC_INPUT hSelProcInput,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,SEL_PROC_CODEC_MODE codecMode)1993*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _generateVirtualDrcSets(
1994*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
1995*e5436536SAndroid Build Coastguard Worker     SEL_PROC_CODEC_MODE codecMode) {
1996*e5436536SAndroid Build Coastguard Worker   int i;
1997*e5436536SAndroid Build Coastguard Worker   int nMixes = hUniDrcConfig->downmixInstructionsCount + 1;
1998*e5436536SAndroid Build Coastguard Worker   int index = hUniDrcConfig->drcInstructionsUniDrcCount;
1999*e5436536SAndroid Build Coastguard Worker   int indexVirtual = -1;
2000*e5436536SAndroid Build Coastguard Worker   DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction =
2001*e5436536SAndroid Build Coastguard Worker       &(hUniDrcConfig->drcInstructionsUniDrc[index]);
2002*e5436536SAndroid Build Coastguard Worker 
2003*e5436536SAndroid Build Coastguard Worker   if (codecMode == SEL_PROC_MPEG_H_3DA) {
2004*e5436536SAndroid Build Coastguard Worker     nMixes = 1;
2005*e5436536SAndroid Build Coastguard Worker   }
2006*e5436536SAndroid Build Coastguard Worker 
2007*e5436536SAndroid Build Coastguard Worker   if ((index + nMixes) > (12 + 1 + 6)) {
2008*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NOT_OK;
2009*e5436536SAndroid Build Coastguard Worker   }
2010*e5436536SAndroid Build Coastguard Worker 
2011*e5436536SAndroid Build Coastguard Worker   FDKmemset(pDrcInstruction, 0, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
2012*e5436536SAndroid Build Coastguard Worker 
2013*e5436536SAndroid Build Coastguard Worker   pDrcInstruction->drcSetId = indexVirtual;
2014*e5436536SAndroid Build Coastguard Worker   index++;
2015*e5436536SAndroid Build Coastguard Worker   indexVirtual--;
2016*e5436536SAndroid Build Coastguard Worker   pDrcInstruction->downmixIdCount = 1;
2017*e5436536SAndroid Build Coastguard Worker 
2018*e5436536SAndroid Build Coastguard Worker   if ((codecMode == SEL_PROC_MPEG_H_3DA) &&
2019*e5436536SAndroid Build Coastguard Worker       (hSelProcInput->numDownmixIdRequests)) {
2020*e5436536SAndroid Build Coastguard Worker     pDrcInstruction->downmixId[0] = hSelProcInput->downmixIdRequested[0];
2021*e5436536SAndroid Build Coastguard Worker   } else {
2022*e5436536SAndroid Build Coastguard Worker     pDrcInstruction->downmixId[0] = DOWNMIX_ID_BASE_LAYOUT;
2023*e5436536SAndroid Build Coastguard Worker   }
2024*e5436536SAndroid Build Coastguard Worker 
2025*e5436536SAndroid Build Coastguard Worker   for (i = 1; i < nMixes; i++) {
2026*e5436536SAndroid Build Coastguard Worker     pDrcInstruction = &(hUniDrcConfig->drcInstructionsUniDrc[index]);
2027*e5436536SAndroid Build Coastguard Worker     FDKmemset(pDrcInstruction, 0, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
2028*e5436536SAndroid Build Coastguard Worker     pDrcInstruction->drcSetId = indexVirtual;
2029*e5436536SAndroid Build Coastguard Worker     pDrcInstruction->downmixId[0] =
2030*e5436536SAndroid Build Coastguard Worker         hUniDrcConfig->downmixInstructions[i - 1].downmixId;
2031*e5436536SAndroid Build Coastguard Worker     pDrcInstruction->downmixIdCount = 1;
2032*e5436536SAndroid Build Coastguard Worker     index++;
2033*e5436536SAndroid Build Coastguard Worker     indexVirtual--;
2034*e5436536SAndroid Build Coastguard Worker   }
2035*e5436536SAndroid Build Coastguard Worker 
2036*e5436536SAndroid Build Coastguard Worker   hUniDrcConfig->drcInstructionsCountInclVirtual =
2037*e5436536SAndroid Build Coastguard Worker       hUniDrcConfig->drcInstructionsUniDrcCount + nMixes;
2038*e5436536SAndroid Build Coastguard Worker 
2039*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
2040*e5436536SAndroid Build Coastguard Worker }
2041*e5436536SAndroid Build Coastguard Worker 
_generateOutputInfo(HANDLE_SEL_PROC_INPUT hSelProcInput,HANDLE_SEL_PROC_OUTPUT hSelProcOutput,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,DRCDEC_SELECTION_DATA * pSelectionData,SEL_PROC_CODEC_MODE codecMode)2042*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
2043*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
2044*e5436536SAndroid Build Coastguard Worker     HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
2045*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
2046*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION_DATA* pSelectionData, SEL_PROC_CODEC_MODE codecMode) {
2047*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
2048*e5436536SAndroid Build Coastguard Worker 
2049*e5436536SAndroid Build Coastguard Worker   int i, j;
2050*e5436536SAndroid Build Coastguard Worker   int hasDependend = 0;
2051*e5436536SAndroid Build Coastguard Worker   int hasFading = 0;
2052*e5436536SAndroid Build Coastguard Worker   int hasDucking = 0;
2053*e5436536SAndroid Build Coastguard Worker   int selectedDrcSetIds;
2054*e5436536SAndroid Build Coastguard Worker   int selectedDownmixIds;
2055*e5436536SAndroid Build Coastguard Worker   FIXP_DBL mixingLevel = 0;
2056*e5436536SAndroid Build Coastguard Worker   int albumMode = hSelProcInput->albumMode;
2057*e5436536SAndroid Build Coastguard Worker   UCHAR* pDownmixIdRequested = hSelProcInput->downmixIdRequested;
2058*e5436536SAndroid Build Coastguard Worker   FIXP_SGL boost = hSelProcInput->boost;
2059*e5436536SAndroid Build Coastguard Worker   FIXP_SGL compress = hSelProcInput->compress;
2060*e5436536SAndroid Build Coastguard Worker 
2061*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->numSelectedDrcSets = 1;
2062*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->selectedDrcSetIds[0] = pSelectionData->pInst->drcSetId;
2063*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->selectedDownmixIds[0] =
2064*e5436536SAndroid Build Coastguard Worker       pSelectionData->pInst->drcApplyToDownmix == 1
2065*e5436536SAndroid Build Coastguard Worker           ? pSelectionData->pInst->downmixId[0]
2066*e5436536SAndroid Build Coastguard Worker           : 0;
2067*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->loudnessNormalizationGainDb =
2068*e5436536SAndroid Build Coastguard Worker       pSelectionData->loudnessNormalizationGainDbAdjusted +
2069*e5436536SAndroid Build Coastguard Worker       hSelProcInput->loudnessNormalizationGainModificationDb;
2070*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->outputPeakLevelDb = pSelectionData->outputPeakLevel;
2071*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->outputLoudness = pSelectionData->outputLoudness;
2072*e5436536SAndroid Build Coastguard Worker 
2073*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->boost = boost;
2074*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->compress = compress;
2075*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->baseChannelCount =
2076*e5436536SAndroid Build Coastguard Worker       hUniDrcConfig->channelLayout.baseChannelCount;
2077*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->targetChannelCount =
2078*e5436536SAndroid Build Coastguard Worker       hUniDrcConfig->channelLayout.baseChannelCount;
2079*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->activeDownmixId =
2080*e5436536SAndroid Build Coastguard Worker       pDownmixIdRequested[pSelectionData->downmixIdRequestIndex];
2081*e5436536SAndroid Build Coastguard Worker 
2082*e5436536SAndroid Build Coastguard Worker   _getMixingLevel(hLoudnessInfoSet, *pDownmixIdRequested,
2083*e5436536SAndroid Build Coastguard Worker                   hSelProcOutput->selectedDrcSetIds[0], albumMode,
2084*e5436536SAndroid Build Coastguard Worker                   &mixingLevel);
2085*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->mixingLevel = mixingLevel;
2086*e5436536SAndroid Build Coastguard Worker 
2087*e5436536SAndroid Build Coastguard Worker   /*dependent*/
2088*e5436536SAndroid Build Coastguard Worker   if (pSelectionData->pInst->dependsOnDrcSetPresent) {
2089*e5436536SAndroid Build Coastguard Worker     int dependsOnDrcSetID = pSelectionData->pInst->dependsOnDrcSet;
2090*e5436536SAndroid Build Coastguard Worker 
2091*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < hUniDrcConfig->drcInstructionsCountInclVirtual; i++) {
2092*e5436536SAndroid Build Coastguard Worker       DRC_INSTRUCTIONS_UNI_DRC* pInst =
2093*e5436536SAndroid Build Coastguard Worker           &(hUniDrcConfig->drcInstructionsUniDrc[i]);
2094*e5436536SAndroid Build Coastguard Worker       if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
2095*e5436536SAndroid Build Coastguard Worker 
2096*e5436536SAndroid Build Coastguard Worker       if (pInst->drcSetId == dependsOnDrcSetID) {
2097*e5436536SAndroid Build Coastguard Worker         hSelProcOutput->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
2098*e5436536SAndroid Build Coastguard Worker             hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
2099*e5436536SAndroid Build Coastguard Worker         hSelProcOutput->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] =
2100*e5436536SAndroid Build Coastguard Worker             hUniDrcConfig->drcInstructionsUniDrc[i].drcApplyToDownmix == 1
2101*e5436536SAndroid Build Coastguard Worker                 ? hUniDrcConfig->drcInstructionsUniDrc[i].downmixId[0]
2102*e5436536SAndroid Build Coastguard Worker                 : 0;
2103*e5436536SAndroid Build Coastguard Worker         hSelProcOutput->numSelectedDrcSets++;
2104*e5436536SAndroid Build Coastguard Worker         hasDependend = 1;
2105*e5436536SAndroid Build Coastguard Worker         break;
2106*e5436536SAndroid Build Coastguard Worker       }
2107*e5436536SAndroid Build Coastguard Worker     }
2108*e5436536SAndroid Build Coastguard Worker   }
2109*e5436536SAndroid Build Coastguard Worker 
2110*e5436536SAndroid Build Coastguard Worker   /* fading */
2111*e5436536SAndroid Build Coastguard Worker   if (hSelProcInput->albumMode == 0) {
2112*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
2113*e5436536SAndroid Build Coastguard Worker       DRC_INSTRUCTIONS_UNI_DRC* pInst =
2114*e5436536SAndroid Build Coastguard Worker           &(hUniDrcConfig->drcInstructionsUniDrc[i]);
2115*e5436536SAndroid Build Coastguard Worker       if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
2116*e5436536SAndroid Build Coastguard Worker 
2117*e5436536SAndroid Build Coastguard Worker       if (pInst->drcSetEffect & EB_FADE) {
2118*e5436536SAndroid Build Coastguard Worker         if (pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) {
2119*e5436536SAndroid Build Coastguard Worker           hSelProcOutput->numSelectedDrcSets = hasDependend + 1;
2120*e5436536SAndroid Build Coastguard Worker           hSelProcOutput
2121*e5436536SAndroid Build Coastguard Worker               ->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
2122*e5436536SAndroid Build Coastguard Worker               hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
2123*e5436536SAndroid Build Coastguard Worker           hSelProcOutput
2124*e5436536SAndroid Build Coastguard Worker               ->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] =
2125*e5436536SAndroid Build Coastguard Worker               hUniDrcConfig->drcInstructionsUniDrc[i].drcApplyToDownmix == 1
2126*e5436536SAndroid Build Coastguard Worker                   ? hUniDrcConfig->drcInstructionsUniDrc[i].downmixId[0]
2127*e5436536SAndroid Build Coastguard Worker                   : 0;
2128*e5436536SAndroid Build Coastguard Worker           hSelProcOutput->numSelectedDrcSets++;
2129*e5436536SAndroid Build Coastguard Worker           hasFading = 1;
2130*e5436536SAndroid Build Coastguard Worker 
2131*e5436536SAndroid Build Coastguard Worker         } else {
2132*e5436536SAndroid Build Coastguard Worker           retVal = DRCDEC_SELECTION_PROCESS_NOT_OK;
2133*e5436536SAndroid Build Coastguard Worker           if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
2134*e5436536SAndroid Build Coastguard Worker         }
2135*e5436536SAndroid Build Coastguard Worker       }
2136*e5436536SAndroid Build Coastguard Worker     }
2137*e5436536SAndroid Build Coastguard Worker   }
2138*e5436536SAndroid Build Coastguard Worker 
2139*e5436536SAndroid Build Coastguard Worker   /* ducking */
2140*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
2141*e5436536SAndroid Build Coastguard Worker     DRC_INSTRUCTIONS_UNI_DRC* pInst =
2142*e5436536SAndroid Build Coastguard Worker         &(hUniDrcConfig->drcInstructionsUniDrc[i]);
2143*e5436536SAndroid Build Coastguard Worker     if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
2144*e5436536SAndroid Build Coastguard Worker 
2145*e5436536SAndroid Build Coastguard Worker     if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
2146*e5436536SAndroid Build Coastguard Worker       for (j = 0; j < pInst->downmixIdCount; j++) {
2147*e5436536SAndroid Build Coastguard Worker         if (pInst->downmixId[j] == hSelProcOutput->activeDownmixId) {
2148*e5436536SAndroid Build Coastguard Worker           hSelProcOutput->numSelectedDrcSets =
2149*e5436536SAndroid Build Coastguard Worker               hasDependend + 1; /* ducking overrides fading */
2150*e5436536SAndroid Build Coastguard Worker 
2151*e5436536SAndroid Build Coastguard Worker           hSelProcOutput
2152*e5436536SAndroid Build Coastguard Worker               ->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
2153*e5436536SAndroid Build Coastguard Worker               hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
2154*e5436536SAndroid Build Coastguard Worker           /* force ducking DRC set to be processed on base layout */
2155*e5436536SAndroid Build Coastguard Worker           hSelProcOutput
2156*e5436536SAndroid Build Coastguard Worker               ->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] = 0;
2157*e5436536SAndroid Build Coastguard Worker           hSelProcOutput->numSelectedDrcSets++;
2158*e5436536SAndroid Build Coastguard Worker           hasDucking = 1;
2159*e5436536SAndroid Build Coastguard Worker         }
2160*e5436536SAndroid Build Coastguard Worker       }
2161*e5436536SAndroid Build Coastguard Worker     }
2162*e5436536SAndroid Build Coastguard Worker   }
2163*e5436536SAndroid Build Coastguard Worker 
2164*e5436536SAndroid Build Coastguard Worker   /* repeat for DOWNMIX_ID_BASE_LAYOUT if no ducking found*/
2165*e5436536SAndroid Build Coastguard Worker 
2166*e5436536SAndroid Build Coastguard Worker   if (!hasDucking) {
2167*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
2168*e5436536SAndroid Build Coastguard Worker       DRC_INSTRUCTIONS_UNI_DRC* pInst =
2169*e5436536SAndroid Build Coastguard Worker           &(hUniDrcConfig->drcInstructionsUniDrc[i]);
2170*e5436536SAndroid Build Coastguard Worker       if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue;
2171*e5436536SAndroid Build Coastguard Worker 
2172*e5436536SAndroid Build Coastguard Worker       if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
2173*e5436536SAndroid Build Coastguard Worker         for (j = 0; j < pInst->downmixIdCount; j++) {
2174*e5436536SAndroid Build Coastguard Worker           if (pInst->downmixId[j] == DOWNMIX_ID_BASE_LAYOUT) {
2175*e5436536SAndroid Build Coastguard Worker             hSelProcOutput->numSelectedDrcSets = hasDependend + hasFading + 1;
2176*e5436536SAndroid Build Coastguard Worker             hSelProcOutput
2177*e5436536SAndroid Build Coastguard Worker                 ->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
2178*e5436536SAndroid Build Coastguard Worker                 hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
2179*e5436536SAndroid Build Coastguard Worker             /* force ducking DRC set to be processed on base layout */
2180*e5436536SAndroid Build Coastguard Worker             hSelProcOutput
2181*e5436536SAndroid Build Coastguard Worker                 ->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] = 0;
2182*e5436536SAndroid Build Coastguard Worker             hSelProcOutput->numSelectedDrcSets++;
2183*e5436536SAndroid Build Coastguard Worker           }
2184*e5436536SAndroid Build Coastguard Worker         }
2185*e5436536SAndroid Build Coastguard Worker       }
2186*e5436536SAndroid Build Coastguard Worker     }
2187*e5436536SAndroid Build Coastguard Worker   }
2188*e5436536SAndroid Build Coastguard Worker 
2189*e5436536SAndroid Build Coastguard Worker   if (hSelProcOutput->numSelectedDrcSets > 3) {
2190*e5436536SAndroid Build Coastguard Worker     /* maximum permitted number of applied DRC sets is 3, see section 6.3.5 of
2191*e5436536SAndroid Build Coastguard Worker      * ISO/IEC 23003-4 */
2192*e5436536SAndroid Build Coastguard Worker     hSelProcOutput->numSelectedDrcSets = 0;
2193*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NOT_OK;
2194*e5436536SAndroid Build Coastguard Worker   }
2195*e5436536SAndroid Build Coastguard Worker 
2196*e5436536SAndroid Build Coastguard Worker   /* sorting: Ducking/Fading -> Dependent -> Selected */
2197*e5436536SAndroid Build Coastguard Worker   if (hSelProcOutput->numSelectedDrcSets == 3) {
2198*e5436536SAndroid Build Coastguard Worker     selectedDrcSetIds = hSelProcOutput->selectedDrcSetIds[0];
2199*e5436536SAndroid Build Coastguard Worker     selectedDownmixIds = hSelProcOutput->selectedDownmixIds[0];
2200*e5436536SAndroid Build Coastguard Worker     hSelProcOutput->selectedDrcSetIds[0] = hSelProcOutput->selectedDrcSetIds[2];
2201*e5436536SAndroid Build Coastguard Worker     hSelProcOutput->selectedDownmixIds[0] =
2202*e5436536SAndroid Build Coastguard Worker         hSelProcOutput->selectedDownmixIds[2];
2203*e5436536SAndroid Build Coastguard Worker     hSelProcOutput->selectedDrcSetIds[2] = selectedDrcSetIds;
2204*e5436536SAndroid Build Coastguard Worker     hSelProcOutput->selectedDownmixIds[2] = selectedDownmixIds;
2205*e5436536SAndroid Build Coastguard Worker   } else if (hSelProcOutput->numSelectedDrcSets == 2) {
2206*e5436536SAndroid Build Coastguard Worker     selectedDrcSetIds = hSelProcOutput->selectedDrcSetIds[0];
2207*e5436536SAndroid Build Coastguard Worker     selectedDownmixIds = hSelProcOutput->selectedDownmixIds[0];
2208*e5436536SAndroid Build Coastguard Worker     hSelProcOutput->selectedDrcSetIds[0] = hSelProcOutput->selectedDrcSetIds[1];
2209*e5436536SAndroid Build Coastguard Worker     hSelProcOutput->selectedDownmixIds[0] =
2210*e5436536SAndroid Build Coastguard Worker         hSelProcOutput->selectedDownmixIds[1];
2211*e5436536SAndroid Build Coastguard Worker     hSelProcOutput->selectedDrcSetIds[1] = selectedDrcSetIds;
2212*e5436536SAndroid Build Coastguard Worker     hSelProcOutput->selectedDownmixIds[1] = selectedDownmixIds;
2213*e5436536SAndroid Build Coastguard Worker   }
2214*e5436536SAndroid Build Coastguard Worker 
2215*e5436536SAndroid Build Coastguard Worker   return retVal;
2216*e5436536SAndroid Build Coastguard Worker }
2217*e5436536SAndroid Build Coastguard Worker 
_selectDownmixMatrix(HANDLE_SEL_PROC_OUTPUT hSelProcOutput,HANDLE_UNI_DRC_CONFIG hUniDrcConfig)2218*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _selectDownmixMatrix(
2219*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
2220*e5436536SAndroid Build Coastguard Worker     HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
2221*e5436536SAndroid Build Coastguard Worker   int i;
2222*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->baseChannelCount =
2223*e5436536SAndroid Build Coastguard Worker       hUniDrcConfig->channelLayout.baseChannelCount;
2224*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->targetChannelCount =
2225*e5436536SAndroid Build Coastguard Worker       hUniDrcConfig->channelLayout.baseChannelCount;
2226*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->targetLayout = -1;
2227*e5436536SAndroid Build Coastguard Worker   hSelProcOutput->downmixMatrixPresent = 0;
2228*e5436536SAndroid Build Coastguard Worker 
2229*e5436536SAndroid Build Coastguard Worker   if (hSelProcOutput->activeDownmixId != 0) {
2230*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
2231*e5436536SAndroid Build Coastguard Worker       DOWNMIX_INSTRUCTIONS* pDown = &(hUniDrcConfig->downmixInstructions[i]);
2232*e5436536SAndroid Build Coastguard Worker       if (pDown->targetChannelCount > 8) {
2233*e5436536SAndroid Build Coastguard Worker         continue;
2234*e5436536SAndroid Build Coastguard Worker       }
2235*e5436536SAndroid Build Coastguard Worker 
2236*e5436536SAndroid Build Coastguard Worker       if (hSelProcOutput->activeDownmixId == pDown->downmixId) {
2237*e5436536SAndroid Build Coastguard Worker         hSelProcOutput->targetChannelCount = pDown->targetChannelCount;
2238*e5436536SAndroid Build Coastguard Worker         hSelProcOutput->targetLayout = pDown->targetLayout;
2239*e5436536SAndroid Build Coastguard Worker 
2240*e5436536SAndroid Build Coastguard Worker         if (pDown->downmixCoefficientsPresent) {
2241*e5436536SAndroid Build Coastguard Worker           int j, k;
2242*e5436536SAndroid Build Coastguard Worker           FIXP_DBL downmixOffset = getDownmixOffset(
2243*e5436536SAndroid Build Coastguard Worker               pDown, hSelProcOutput->baseChannelCount); /* e = 1 */
2244*e5436536SAndroid Build Coastguard Worker 
2245*e5436536SAndroid Build Coastguard Worker           for (j = 0; j < hSelProcOutput->baseChannelCount; j++) {
2246*e5436536SAndroid Build Coastguard Worker             for (k = 0; k < hSelProcOutput->targetChannelCount; k++) {
2247*e5436536SAndroid Build Coastguard Worker               hSelProcOutput->downmixMatrix[j][k] =
2248*e5436536SAndroid Build Coastguard Worker                   fMultDiv2(
2249*e5436536SAndroid Build Coastguard Worker                       downmixOffset,
2250*e5436536SAndroid Build Coastguard Worker                       pDown->downmixCoefficient[j + k * hSelProcOutput
2251*e5436536SAndroid Build Coastguard Worker                                                             ->baseChannelCount])
2252*e5436536SAndroid Build Coastguard Worker                   << 2;
2253*e5436536SAndroid Build Coastguard Worker             }
2254*e5436536SAndroid Build Coastguard Worker           }
2255*e5436536SAndroid Build Coastguard Worker 
2256*e5436536SAndroid Build Coastguard Worker           hSelProcOutput->downmixMatrixPresent = 1;
2257*e5436536SAndroid Build Coastguard Worker         }
2258*e5436536SAndroid Build Coastguard Worker         break;
2259*e5436536SAndroid Build Coastguard Worker       }
2260*e5436536SAndroid Build Coastguard Worker     }
2261*e5436536SAndroid Build Coastguard Worker   }
2262*e5436536SAndroid Build Coastguard Worker 
2263*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
2264*e5436536SAndroid Build Coastguard Worker }
2265*e5436536SAndroid Build Coastguard Worker 
_drcSetPreSelection(SEL_PROC_INPUT * hSelProcInput,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,DRCDEC_SELECTION ** ppCandidatesPotential,DRCDEC_SELECTION ** ppCandidatesSelected,SEL_PROC_CODEC_MODE codecMode)2266*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelection(
2267*e5436536SAndroid Build Coastguard Worker     SEL_PROC_INPUT* hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
2268*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
2269*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesPotential,
2270*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesSelected, SEL_PROC_CODEC_MODE codecMode) {
2271*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
2272*e5436536SAndroid Build Coastguard Worker   int i, j;
2273*e5436536SAndroid Build Coastguard Worker 
2274*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < hSelProcInput->numDownmixIdRequests; i++) {
2275*e5436536SAndroid Build Coastguard Worker     for (j = 0; j < hUniDrcConfig->drcInstructionsCountInclVirtual; j++) {
2276*e5436536SAndroid Build Coastguard Worker       DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction =
2277*e5436536SAndroid Build Coastguard Worker           &(hUniDrcConfig->drcInstructionsUniDrc[j]);
2278*e5436536SAndroid Build Coastguard Worker       /* check if ID is unique */
2279*e5436536SAndroid Build Coastguard Worker       if (selectDrcInstructions(hUniDrcConfig, pDrcInstruction->drcSetId) !=
2280*e5436536SAndroid Build Coastguard Worker           pDrcInstruction)
2281*e5436536SAndroid Build Coastguard Worker         continue;
2282*e5436536SAndroid Build Coastguard Worker 
2283*e5436536SAndroid Build Coastguard Worker       retVal = _drcSetPreSelectionSingleInstruction(
2284*e5436536SAndroid Build Coastguard Worker           hSelProcInput, i, hUniDrcConfig, hLoudnessInfoSet, pDrcInstruction,
2285*e5436536SAndroid Build Coastguard Worker           *ppCandidatesPotential, *ppCandidatesSelected, codecMode);
2286*e5436536SAndroid Build Coastguard Worker       if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
2287*e5436536SAndroid Build Coastguard Worker     }
2288*e5436536SAndroid Build Coastguard Worker   }
2289*e5436536SAndroid Build Coastguard Worker 
2290*e5436536SAndroid Build Coastguard Worker   retVal = _preSelectionRequirement9(hSelProcInput, *ppCandidatesPotential,
2291*e5436536SAndroid Build Coastguard Worker                                      *ppCandidatesSelected);
2292*e5436536SAndroid Build Coastguard Worker   if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
2293*e5436536SAndroid Build Coastguard Worker 
2294*e5436536SAndroid Build Coastguard Worker   if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
2295*e5436536SAndroid Build Coastguard Worker     retVal = _drcSetSelectionAddCandidates(
2296*e5436536SAndroid Build Coastguard Worker         hSelProcInput, *ppCandidatesPotential, *ppCandidatesSelected);
2297*e5436536SAndroid Build Coastguard Worker     if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
2298*e5436536SAndroid Build Coastguard Worker   }
2299*e5436536SAndroid Build Coastguard Worker 
2300*e5436536SAndroid Build Coastguard Worker   return retVal;
2301*e5436536SAndroid Build Coastguard Worker }
2302*e5436536SAndroid Build Coastguard Worker 
_drcSetRequestSelection(SEL_PROC_INPUT * hSelProcInput,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,DRCDEC_SELECTION ** ppCandidatesPotential,DRCDEC_SELECTION ** ppCandidatesSelected)2303*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _drcSetRequestSelection(
2304*e5436536SAndroid Build Coastguard Worker     SEL_PROC_INPUT* hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
2305*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
2306*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesPotential,
2307*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION** ppCandidatesSelected) {
2308*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal;
2309*e5436536SAndroid Build Coastguard Worker   int i;
2310*e5436536SAndroid Build Coastguard Worker 
2311*e5436536SAndroid Build Coastguard Worker   if (_drcdec_selection_getNumber(*ppCandidatesPotential) == 0) {
2312*e5436536SAndroid Build Coastguard Worker     retVal = DRCDEC_SELECTION_PROCESS_NOT_OK;
2313*e5436536SAndroid Build Coastguard Worker     if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
2314*e5436536SAndroid Build Coastguard Worker   }
2315*e5436536SAndroid Build Coastguard Worker 
2316*e5436536SAndroid Build Coastguard Worker   if (hSelProcInput->dynamicRangeControlOn) {
2317*e5436536SAndroid Build Coastguard Worker     if (hSelProcInput->numDrcFeatureRequests == 0) {
2318*e5436536SAndroid Build Coastguard Worker       retVal = _selectDrcSetEffectNone(hUniDrcConfig, *ppCandidatesPotential,
2319*e5436536SAndroid Build Coastguard Worker                                        *ppCandidatesSelected);
2320*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
2321*e5436536SAndroid Build Coastguard Worker 
2322*e5436536SAndroid Build Coastguard Worker       if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
2323*e5436536SAndroid Build Coastguard Worker         DRC_FEATURE_REQUEST fallbackRequest;
2324*e5436536SAndroid Build Coastguard Worker         fallbackRequest.drcEffectType.numRequests = 5;
2325*e5436536SAndroid Build Coastguard Worker         fallbackRequest.drcEffectType.numRequestsDesired = 5;
2326*e5436536SAndroid Build Coastguard Worker         fallbackRequest.drcEffectType.request[0] = DETR_GENERAL_COMPR;
2327*e5436536SAndroid Build Coastguard Worker         fallbackRequest.drcEffectType.request[1] = DETR_NIGHT;
2328*e5436536SAndroid Build Coastguard Worker         fallbackRequest.drcEffectType.request[2] = DETR_NOISY;
2329*e5436536SAndroid Build Coastguard Worker         fallbackRequest.drcEffectType.request[3] = DETR_LIMITED;
2330*e5436536SAndroid Build Coastguard Worker         fallbackRequest.drcEffectType.request[4] = DETR_LOWLEVEL;
2331*e5436536SAndroid Build Coastguard Worker 
2332*e5436536SAndroid Build Coastguard Worker         retVal = _selectEffectTypeFeature(hUniDrcConfig, fallbackRequest,
2333*e5436536SAndroid Build Coastguard Worker                                           ppCandidatesPotential,
2334*e5436536SAndroid Build Coastguard Worker                                           ppCandidatesSelected);
2335*e5436536SAndroid Build Coastguard Worker         if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
2336*e5436536SAndroid Build Coastguard Worker       }
2337*e5436536SAndroid Build Coastguard Worker 
2338*e5436536SAndroid Build Coastguard Worker       _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
2339*e5436536SAndroid Build Coastguard Worker     } else {
2340*e5436536SAndroid Build Coastguard Worker       for (i = 0; i < hSelProcInput->numDrcFeatureRequests; i++) {
2341*e5436536SAndroid Build Coastguard Worker         if (hSelProcInput->drcFeatureRequestType[i] == DFRT_EFFECT_TYPE) {
2342*e5436536SAndroid Build Coastguard Worker           retVal = _selectEffectTypeFeature(
2343*e5436536SAndroid Build Coastguard Worker               hUniDrcConfig, hSelProcInput->drcFeatureRequest[i],
2344*e5436536SAndroid Build Coastguard Worker               ppCandidatesPotential, ppCandidatesSelected);
2345*e5436536SAndroid Build Coastguard Worker 
2346*e5436536SAndroid Build Coastguard Worker           _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
2347*e5436536SAndroid Build Coastguard Worker           if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
2348*e5436536SAndroid Build Coastguard Worker         }
2349*e5436536SAndroid Build Coastguard Worker 
2350*e5436536SAndroid Build Coastguard Worker         else if (hSelProcInput->drcFeatureRequestType[i] ==
2351*e5436536SAndroid Build Coastguard Worker                  DFRT_DYNAMIC_RANGE) {
2352*e5436536SAndroid Build Coastguard Worker           retVal = _selectDynamicRange(
2353*e5436536SAndroid Build Coastguard Worker               hUniDrcConfig, hLoudnessInfoSet,
2354*e5436536SAndroid Build Coastguard Worker               hSelProcInput->drcFeatureRequest[i],
2355*e5436536SAndroid Build Coastguard Worker               hSelProcInput->downmixIdRequested, hSelProcInput->albumMode,
2356*e5436536SAndroid Build Coastguard Worker               *ppCandidatesPotential, *ppCandidatesSelected);
2357*e5436536SAndroid Build Coastguard Worker 
2358*e5436536SAndroid Build Coastguard Worker           if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 0) {
2359*e5436536SAndroid Build Coastguard Worker             _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
2360*e5436536SAndroid Build Coastguard Worker           }
2361*e5436536SAndroid Build Coastguard Worker           if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
2362*e5436536SAndroid Build Coastguard Worker         } else if (hSelProcInput->drcFeatureRequestType[i] ==
2363*e5436536SAndroid Build Coastguard Worker                    DFRT_DRC_CHARACTERISTIC) {
2364*e5436536SAndroid Build Coastguard Worker           retVal = _selectDrcCharacteristic(
2365*e5436536SAndroid Build Coastguard Worker               hUniDrcConfig,
2366*e5436536SAndroid Build Coastguard Worker               hSelProcInput->drcFeatureRequest[i].drcCharacteristic,
2367*e5436536SAndroid Build Coastguard Worker               ppCandidatesPotential, ppCandidatesSelected);
2368*e5436536SAndroid Build Coastguard Worker 
2369*e5436536SAndroid Build Coastguard Worker           if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 0) {
2370*e5436536SAndroid Build Coastguard Worker             _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
2371*e5436536SAndroid Build Coastguard Worker           }
2372*e5436536SAndroid Build Coastguard Worker           if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
2373*e5436536SAndroid Build Coastguard Worker         }
2374*e5436536SAndroid Build Coastguard Worker       }
2375*e5436536SAndroid Build Coastguard Worker     }
2376*e5436536SAndroid Build Coastguard Worker   }
2377*e5436536SAndroid Build Coastguard Worker 
2378*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
2379*e5436536SAndroid Build Coastguard Worker }
2380*e5436536SAndroid Build Coastguard Worker 
2381*e5436536SAndroid Build Coastguard Worker /*******************************************/
_dynamicRangeMeasurement(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,DRC_INSTRUCTIONS_UNI_DRC * pInst,UCHAR downmixIdRequested,DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,int albumMode,int * pPeakToAveragePresent,FIXP_DBL * pPeakToAverage)2382*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _dynamicRangeMeasurement(
2383*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, DRC_INSTRUCTIONS_UNI_DRC* pInst,
2384*e5436536SAndroid Build Coastguard Worker     UCHAR downmixIdRequested,
2385*e5436536SAndroid Build Coastguard Worker     DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,
2386*e5436536SAndroid Build Coastguard Worker     int albumMode, int* pPeakToAveragePresent, FIXP_DBL* pPeakToAverage) {
2387*e5436536SAndroid Build Coastguard Worker   int i;
2388*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
2389*e5436536SAndroid Build Coastguard Worker   int drcSetId = fMax(0, pInst->drcSetId);
2390*e5436536SAndroid Build Coastguard Worker 
2391*e5436536SAndroid Build Coastguard Worker   *pPeakToAveragePresent = 0;
2392*e5436536SAndroid Build Coastguard Worker 
2393*e5436536SAndroid Build Coastguard Worker   if (albumMode) {
2394*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < hLoudnessInfoSet->loudnessInfoAlbumCount; i++) {
2395*e5436536SAndroid Build Coastguard Worker       LOUDNESS_INFO* pLoudnessInfo = &(hLoudnessInfoSet->loudnessInfoAlbum[i]);
2396*e5436536SAndroid Build Coastguard Worker 
2397*e5436536SAndroid Build Coastguard Worker       if (drcSetId == pLoudnessInfo->drcSetId) {
2398*e5436536SAndroid Build Coastguard Worker         if (downmixIdRequested == pLoudnessInfo->downmixId) {
2399*e5436536SAndroid Build Coastguard Worker           retVal = _extractLoudnessPeakToAverageValue(
2400*e5436536SAndroid Build Coastguard Worker               pLoudnessInfo, dynamicRangeMeasurementType, pPeakToAveragePresent,
2401*e5436536SAndroid Build Coastguard Worker               pPeakToAverage);
2402*e5436536SAndroid Build Coastguard Worker           if (retVal) return (retVal);
2403*e5436536SAndroid Build Coastguard Worker         }
2404*e5436536SAndroid Build Coastguard Worker       }
2405*e5436536SAndroid Build Coastguard Worker     }
2406*e5436536SAndroid Build Coastguard Worker   }
2407*e5436536SAndroid Build Coastguard Worker 
2408*e5436536SAndroid Build Coastguard Worker   if (*pPeakToAveragePresent == 0) {
2409*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < hLoudnessInfoSet->loudnessInfoCount; i++) {
2410*e5436536SAndroid Build Coastguard Worker       LOUDNESS_INFO* pLoudnessInfo = &(hLoudnessInfoSet->loudnessInfo[i]);
2411*e5436536SAndroid Build Coastguard Worker 
2412*e5436536SAndroid Build Coastguard Worker       if (drcSetId == pLoudnessInfo->drcSetId) {
2413*e5436536SAndroid Build Coastguard Worker         if (downmixIdRequested == pLoudnessInfo->downmixId) {
2414*e5436536SAndroid Build Coastguard Worker           retVal = _extractLoudnessPeakToAverageValue(
2415*e5436536SAndroid Build Coastguard Worker               pLoudnessInfo, dynamicRangeMeasurementType, pPeakToAveragePresent,
2416*e5436536SAndroid Build Coastguard Worker               pPeakToAverage);
2417*e5436536SAndroid Build Coastguard Worker           if (retVal) return (retVal);
2418*e5436536SAndroid Build Coastguard Worker         }
2419*e5436536SAndroid Build Coastguard Worker       }
2420*e5436536SAndroid Build Coastguard Worker     }
2421*e5436536SAndroid Build Coastguard Worker   }
2422*e5436536SAndroid Build Coastguard Worker 
2423*e5436536SAndroid Build Coastguard Worker   return retVal;
2424*e5436536SAndroid Build Coastguard Worker }
2425*e5436536SAndroid Build Coastguard Worker /*******************************************/
2426*e5436536SAndroid Build Coastguard Worker 
_drcdec_selection_addNew(DRCDEC_SELECTION * pSelection)2427*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_DATA* _drcdec_selection_addNew(
2428*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pSelection) {
2429*e5436536SAndroid Build Coastguard Worker   if (pSelection->numData < (12 + 1 + 6)) {
2430*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION_DATA* pData = &(pSelection->data[pSelection->numData]);
2431*e5436536SAndroid Build Coastguard Worker     FDKmemset(pData, 0, sizeof(DRCDEC_SELECTION_DATA));
2432*e5436536SAndroid Build Coastguard Worker     pSelection->numData++;
2433*e5436536SAndroid Build Coastguard Worker 
2434*e5436536SAndroid Build Coastguard Worker     return pData;
2435*e5436536SAndroid Build Coastguard Worker   } else {
2436*e5436536SAndroid Build Coastguard Worker     return NULL;
2437*e5436536SAndroid Build Coastguard Worker   }
2438*e5436536SAndroid Build Coastguard Worker }
2439*e5436536SAndroid Build Coastguard Worker 
_drcdec_selection_add(DRCDEC_SELECTION * pSelection,DRCDEC_SELECTION_DATA * pDataIn)2440*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_DATA* _drcdec_selection_add(
2441*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pSelection, DRCDEC_SELECTION_DATA* pDataIn) {
2442*e5436536SAndroid Build Coastguard Worker   if (pSelection->numData < (12 + 1 + 6)) {
2443*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION_DATA* pData = &(pSelection->data[pSelection->numData]);
2444*e5436536SAndroid Build Coastguard Worker     FDKmemcpy(pData, pDataIn, sizeof(DRCDEC_SELECTION_DATA));
2445*e5436536SAndroid Build Coastguard Worker     pSelection->numData++;
2446*e5436536SAndroid Build Coastguard Worker     return pData;
2447*e5436536SAndroid Build Coastguard Worker   } else {
2448*e5436536SAndroid Build Coastguard Worker     return NULL;
2449*e5436536SAndroid Build Coastguard Worker   }
2450*e5436536SAndroid Build Coastguard Worker }
2451*e5436536SAndroid Build Coastguard Worker 
_drcdec_selection_clear(DRCDEC_SELECTION * pSelection)2452*e5436536SAndroid Build Coastguard Worker static int _drcdec_selection_clear(DRCDEC_SELECTION* pSelection) {
2453*e5436536SAndroid Build Coastguard Worker   return pSelection->numData = 0;
2454*e5436536SAndroid Build Coastguard Worker }
2455*e5436536SAndroid Build Coastguard Worker 
_drcdec_selection_getNumber(DRCDEC_SELECTION * pSelection)2456*e5436536SAndroid Build Coastguard Worker static int _drcdec_selection_getNumber(DRCDEC_SELECTION* pSelection) {
2457*e5436536SAndroid Build Coastguard Worker   return pSelection->numData;
2458*e5436536SAndroid Build Coastguard Worker }
2459*e5436536SAndroid Build Coastguard Worker 
_drcdec_selection_setNumber(DRCDEC_SELECTION * pSelection,int num)2460*e5436536SAndroid Build Coastguard Worker static int _drcdec_selection_setNumber(DRCDEC_SELECTION* pSelection, int num) {
2461*e5436536SAndroid Build Coastguard Worker   if (num >= 0 && num < pSelection->numData) {
2462*e5436536SAndroid Build Coastguard Worker     return pSelection->numData = num;
2463*e5436536SAndroid Build Coastguard Worker   } else {
2464*e5436536SAndroid Build Coastguard Worker     return pSelection->numData;
2465*e5436536SAndroid Build Coastguard Worker   }
2466*e5436536SAndroid Build Coastguard Worker }
2467*e5436536SAndroid Build Coastguard Worker 
_drcdec_selection_getAt(DRCDEC_SELECTION * pSelection,int at)2468*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_DATA* _drcdec_selection_getAt(
2469*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pSelection, int at) {
2470*e5436536SAndroid Build Coastguard Worker   if (at >= 0 && at < (12 + 1 + 6)) {
2471*e5436536SAndroid Build Coastguard Worker     return &(pSelection->data[at]);
2472*e5436536SAndroid Build Coastguard Worker   } else {
2473*e5436536SAndroid Build Coastguard Worker     return NULL;
2474*e5436536SAndroid Build Coastguard Worker   }
2475*e5436536SAndroid Build Coastguard Worker }
2476*e5436536SAndroid Build Coastguard Worker 
_swapSelectionAndClear(DRCDEC_SELECTION ** ppCandidatesPotential,DRCDEC_SELECTION ** ppCandidatesSelected)2477*e5436536SAndroid Build Coastguard Worker static int _swapSelectionAndClear(DRCDEC_SELECTION** ppCandidatesPotential,
2478*e5436536SAndroid Build Coastguard Worker                                   DRCDEC_SELECTION** ppCandidatesSelected) {
2479*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION* pTmp = *ppCandidatesPotential;
2480*e5436536SAndroid Build Coastguard Worker   *ppCandidatesPotential = *ppCandidatesSelected;
2481*e5436536SAndroid Build Coastguard Worker   *ppCandidatesSelected = pTmp;
2482*e5436536SAndroid Build Coastguard Worker   _drcdec_selection_clear(*ppCandidatesSelected);
2483*e5436536SAndroid Build Coastguard Worker   return 0;
2484*e5436536SAndroid Build Coastguard Worker }
2485*e5436536SAndroid Build Coastguard Worker 
_swapSelection(DRCDEC_SELECTION ** ppCandidatesPotential,DRCDEC_SELECTION ** ppCandidatesSelected)2486*e5436536SAndroid Build Coastguard Worker static int _swapSelection(DRCDEC_SELECTION** ppCandidatesPotential,
2487*e5436536SAndroid Build Coastguard Worker                           DRCDEC_SELECTION** ppCandidatesSelected) {
2488*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION* pTmp = *ppCandidatesPotential;
2489*e5436536SAndroid Build Coastguard Worker   *ppCandidatesPotential = *ppCandidatesSelected;
2490*e5436536SAndroid Build Coastguard Worker   *ppCandidatesSelected = pTmp;
2491*e5436536SAndroid Build Coastguard Worker   return 0;
2492*e5436536SAndroid Build Coastguard Worker }
2493*e5436536SAndroid Build Coastguard Worker 
2494*e5436536SAndroid Build Coastguard Worker /*******************************************/
2495*e5436536SAndroid Build Coastguard Worker 
_getLoudnessInfoStructure(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,int drcSetId,int downmixId,int albumMode)2496*e5436536SAndroid Build Coastguard Worker static LOUDNESS_INFO* _getLoudnessInfoStructure(
2497*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int drcSetId, int downmixId,
2498*e5436536SAndroid Build Coastguard Worker     int albumMode) {
2499*e5436536SAndroid Build Coastguard Worker   int i, j;
2500*e5436536SAndroid Build Coastguard Worker   int count;
2501*e5436536SAndroid Build Coastguard Worker 
2502*e5436536SAndroid Build Coastguard Worker   LOUDNESS_INFO* pLoudnessInfo = NULL;
2503*e5436536SAndroid Build Coastguard Worker 
2504*e5436536SAndroid Build Coastguard Worker   if (albumMode) {
2505*e5436536SAndroid Build Coastguard Worker     count = hLoudnessInfoSet->loudnessInfoAlbumCount;
2506*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
2507*e5436536SAndroid Build Coastguard Worker   } else {
2508*e5436536SAndroid Build Coastguard Worker     count = hLoudnessInfoSet->loudnessInfoCount;
2509*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
2510*e5436536SAndroid Build Coastguard Worker   }
2511*e5436536SAndroid Build Coastguard Worker 
2512*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < count; i++) {
2513*e5436536SAndroid Build Coastguard Worker     if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
2514*e5436536SAndroid Build Coastguard Worker         (pLoudnessInfo[i].downmixId == downmixId)) {
2515*e5436536SAndroid Build Coastguard Worker       for (j = 0; j < pLoudnessInfo[i].measurementCount; j++) {
2516*e5436536SAndroid Build Coastguard Worker         if ((pLoudnessInfo[i].loudnessMeasurement[j].methodDefinition == 1) ||
2517*e5436536SAndroid Build Coastguard Worker             (pLoudnessInfo[i].loudnessMeasurement[j].methodDefinition == 2)) {
2518*e5436536SAndroid Build Coastguard Worker           return &pLoudnessInfo[i];
2519*e5436536SAndroid Build Coastguard Worker         }
2520*e5436536SAndroid Build Coastguard Worker       }
2521*e5436536SAndroid Build Coastguard Worker     }
2522*e5436536SAndroid Build Coastguard Worker   }
2523*e5436536SAndroid Build Coastguard Worker 
2524*e5436536SAndroid Build Coastguard Worker   return NULL;
2525*e5436536SAndroid Build Coastguard Worker }
2526*e5436536SAndroid Build Coastguard Worker 
_getApplicableLoudnessInfoStructure(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,int drcSetId,int downmixIdRequested,int albumMode)2527*e5436536SAndroid Build Coastguard Worker static LOUDNESS_INFO* _getApplicableLoudnessInfoStructure(
2528*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int drcSetId,
2529*e5436536SAndroid Build Coastguard Worker     int downmixIdRequested, int albumMode) {
2530*e5436536SAndroid Build Coastguard Worker   LOUDNESS_INFO* pLoudnessInfo = NULL;
2531*e5436536SAndroid Build Coastguard Worker 
2532*e5436536SAndroid Build Coastguard Worker   /* default value */
2533*e5436536SAndroid Build Coastguard Worker   pLoudnessInfo = _getLoudnessInfoStructure(hLoudnessInfoSet, drcSetId,
2534*e5436536SAndroid Build Coastguard Worker                                             downmixIdRequested, albumMode);
2535*e5436536SAndroid Build Coastguard Worker 
2536*e5436536SAndroid Build Coastguard Worker   /* fallback values */
2537*e5436536SAndroid Build Coastguard Worker   if (pLoudnessInfo == NULL) {
2538*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo =
2539*e5436536SAndroid Build Coastguard Worker         _getLoudnessInfoStructure(hLoudnessInfoSet, drcSetId, 0x7F, albumMode);
2540*e5436536SAndroid Build Coastguard Worker   }
2541*e5436536SAndroid Build Coastguard Worker 
2542*e5436536SAndroid Build Coastguard Worker   if (pLoudnessInfo == NULL) {
2543*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = _getLoudnessInfoStructure(hLoudnessInfoSet, 0x3F,
2544*e5436536SAndroid Build Coastguard Worker                                               downmixIdRequested, albumMode);
2545*e5436536SAndroid Build Coastguard Worker   }
2546*e5436536SAndroid Build Coastguard Worker 
2547*e5436536SAndroid Build Coastguard Worker   if (pLoudnessInfo == NULL) {
2548*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = _getLoudnessInfoStructure(hLoudnessInfoSet, 0,
2549*e5436536SAndroid Build Coastguard Worker                                               downmixIdRequested, albumMode);
2550*e5436536SAndroid Build Coastguard Worker   }
2551*e5436536SAndroid Build Coastguard Worker 
2552*e5436536SAndroid Build Coastguard Worker   if (pLoudnessInfo == NULL) {
2553*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo =
2554*e5436536SAndroid Build Coastguard Worker         _getLoudnessInfoStructure(hLoudnessInfoSet, 0x3F, 0x7F, albumMode);
2555*e5436536SAndroid Build Coastguard Worker   }
2556*e5436536SAndroid Build Coastguard Worker 
2557*e5436536SAndroid Build Coastguard Worker   if (pLoudnessInfo == NULL) {
2558*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo =
2559*e5436536SAndroid Build Coastguard Worker         _getLoudnessInfoStructure(hLoudnessInfoSet, 0, 0x7F, albumMode);
2560*e5436536SAndroid Build Coastguard Worker   }
2561*e5436536SAndroid Build Coastguard Worker 
2562*e5436536SAndroid Build Coastguard Worker   if (pLoudnessInfo == NULL) {
2563*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo =
2564*e5436536SAndroid Build Coastguard Worker         _getLoudnessInfoStructure(hLoudnessInfoSet, drcSetId, 0, albumMode);
2565*e5436536SAndroid Build Coastguard Worker   }
2566*e5436536SAndroid Build Coastguard Worker 
2567*e5436536SAndroid Build Coastguard Worker   if (pLoudnessInfo == NULL) {
2568*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo =
2569*e5436536SAndroid Build Coastguard Worker         _getLoudnessInfoStructure(hLoudnessInfoSet, 0x3F, 0, albumMode);
2570*e5436536SAndroid Build Coastguard Worker   }
2571*e5436536SAndroid Build Coastguard Worker 
2572*e5436536SAndroid Build Coastguard Worker   if (pLoudnessInfo == NULL) {
2573*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo =
2574*e5436536SAndroid Build Coastguard Worker         _getLoudnessInfoStructure(hLoudnessInfoSet, 0, 0, albumMode);
2575*e5436536SAndroid Build Coastguard Worker   }
2576*e5436536SAndroid Build Coastguard Worker 
2577*e5436536SAndroid Build Coastguard Worker   return pLoudnessInfo;
2578*e5436536SAndroid Build Coastguard Worker }
2579*e5436536SAndroid Build Coastguard Worker 
2580*e5436536SAndroid Build Coastguard Worker /*******************************************/
2581*e5436536SAndroid Build Coastguard Worker 
2582*e5436536SAndroid Build Coastguard Worker typedef struct {
2583*e5436536SAndroid Build Coastguard Worker   FIXP_DBL value;
2584*e5436536SAndroid Build Coastguard Worker   int order;
2585*e5436536SAndroid Build Coastguard Worker } VALUE_ORDER;
2586*e5436536SAndroid Build Coastguard Worker 
_initValueOrder(VALUE_ORDER * pValue)2587*e5436536SAndroid Build Coastguard Worker void _initValueOrder(VALUE_ORDER* pValue) {
2588*e5436536SAndroid Build Coastguard Worker   pValue->value = (FIXP_DBL)0;
2589*e5436536SAndroid Build Coastguard Worker   pValue->order = -1;
2590*e5436536SAndroid Build Coastguard Worker }
2591*e5436536SAndroid Build Coastguard Worker 
2592*e5436536SAndroid Build Coastguard Worker enum {
2593*e5436536SAndroid Build Coastguard Worker   MS_BONUS0 = 0,
2594*e5436536SAndroid Build Coastguard Worker   MS_BONUS1770,
2595*e5436536SAndroid Build Coastguard Worker   MS_BONUSUSER,
2596*e5436536SAndroid Build Coastguard Worker   MS_BONUSEXPERT,
2597*e5436536SAndroid Build Coastguard Worker   MS_RESA,
2598*e5436536SAndroid Build Coastguard Worker   MS_RESB,
2599*e5436536SAndroid Build Coastguard Worker   MS_RESC,
2600*e5436536SAndroid Build Coastguard Worker   MS_RESD,
2601*e5436536SAndroid Build Coastguard Worker   MS_RESE,
2602*e5436536SAndroid Build Coastguard Worker   MS_PROGRAMLOUDNESS,
2603*e5436536SAndroid Build Coastguard Worker   MS_PEAKLOUDNESS
2604*e5436536SAndroid Build Coastguard Worker };
2605*e5436536SAndroid Build Coastguard Worker 
_getMethodValue(VALUE_ORDER * pValueOrder,FIXP_DBL value,int measurementSystem,int measurementSystemRequested)2606*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _getMethodValue(
2607*e5436536SAndroid Build Coastguard Worker     VALUE_ORDER* pValueOrder, FIXP_DBL value, int measurementSystem,
2608*e5436536SAndroid Build Coastguard Worker     int measurementSystemRequested) {
2609*e5436536SAndroid Build Coastguard Worker   const int rows = 11;
2610*e5436536SAndroid Build Coastguard Worker   const int columns = 12;
2611*e5436536SAndroid Build Coastguard Worker   const int pOrdering[rows][columns] = {
2612*e5436536SAndroid Build Coastguard Worker       {0, 0, 8, 0, 1, 3, 0, 5, 6, 7, 4, 2}, /* default = bonus1770 */
2613*e5436536SAndroid Build Coastguard Worker       {0, 0, 8, 0, 1, 3, 0, 5, 6, 7, 4, 2}, /* bonus1770 */
2614*e5436536SAndroid Build Coastguard Worker       {0, 0, 1, 0, 8, 5, 0, 2, 3, 4, 6, 7}, /* bonusUser */
2615*e5436536SAndroid Build Coastguard Worker       {0, 0, 3, 0, 1, 8, 0, 4, 5, 6, 7, 2}, /* bonusExpert */
2616*e5436536SAndroid Build Coastguard Worker       {0, 0, 5, 0, 1, 3, 0, 8, 6, 7, 4, 2}, /* ResA */
2617*e5436536SAndroid Build Coastguard Worker       {0, 0, 5, 0, 1, 3, 0, 6, 8, 7, 4, 2}, /* ResB */
2618*e5436536SAndroid Build Coastguard Worker       {0, 0, 5, 0, 1, 3, 0, 6, 7, 8, 4, 2}, /* ResC */
2619*e5436536SAndroid Build Coastguard Worker       {0, 0, 3, 0, 1, 7, 0, 4, 5, 6, 8, 2}, /* ResD */
2620*e5436536SAndroid Build Coastguard Worker       {0, 0, 1, 0, 7, 5, 0, 2, 3, 4, 6, 8}, /* ResE */
2621*e5436536SAndroid Build Coastguard Worker       {0, 0, 1, 0, 0, 0, 0, 2, 3, 4, 0, 0}, /* ProgramLoudness */
2622*e5436536SAndroid Build Coastguard Worker       {0, 7, 0, 0, 0, 0, 6, 5, 4, 3, 2, 1}  /* PeakLoudness */
2623*e5436536SAndroid Build Coastguard Worker   };
2624*e5436536SAndroid Build Coastguard Worker 
2625*e5436536SAndroid Build Coastguard Worker   if (measurementSystemRequested < 0 || measurementSystemRequested >= rows ||
2626*e5436536SAndroid Build Coastguard Worker       measurementSystem < 0 || measurementSystem >= columns) {
2627*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NOT_OK;
2628*e5436536SAndroid Build Coastguard Worker   }
2629*e5436536SAndroid Build Coastguard Worker 
2630*e5436536SAndroid Build Coastguard Worker   if (pOrdering[measurementSystemRequested][measurementSystem] >
2631*e5436536SAndroid Build Coastguard Worker       pValueOrder->order) {
2632*e5436536SAndroid Build Coastguard Worker     pValueOrder->order =
2633*e5436536SAndroid Build Coastguard Worker         pOrdering[measurementSystemRequested][measurementSystem];
2634*e5436536SAndroid Build Coastguard Worker     pValueOrder->value = value;
2635*e5436536SAndroid Build Coastguard Worker   }
2636*e5436536SAndroid Build Coastguard Worker 
2637*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
2638*e5436536SAndroid Build Coastguard Worker }
2639*e5436536SAndroid Build Coastguard Worker 
2640*e5436536SAndroid Build Coastguard Worker /*******************************************/
2641*e5436536SAndroid Build Coastguard Worker 
_getLoudness(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,int albumMode,METHOD_DEFINITION_REQUEST measurementMethodRequested,MEASUREMENT_SYSTEM_REQUEST measurementSystemRequested,FIXP_DBL targetLoudness,int drcSetId,int downmixIdRequested,FIXP_DBL * pLoudnessNormalizationGain,FIXP_DBL * pLoudness)2642*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _getLoudness(
2643*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int albumMode,
2644*e5436536SAndroid Build Coastguard Worker     METHOD_DEFINITION_REQUEST measurementMethodRequested,
2645*e5436536SAndroid Build Coastguard Worker     MEASUREMENT_SYSTEM_REQUEST measurementSystemRequested,
2646*e5436536SAndroid Build Coastguard Worker     FIXP_DBL targetLoudness, /* e = 7 */
2647*e5436536SAndroid Build Coastguard Worker     int drcSetId, int downmixIdRequested,
2648*e5436536SAndroid Build Coastguard Worker     FIXP_DBL* pLoudnessNormalizationGain, /* e = 7 */
2649*e5436536SAndroid Build Coastguard Worker     FIXP_DBL* pLoudness)                  /* e = 7 */
2650*e5436536SAndroid Build Coastguard Worker {
2651*e5436536SAndroid Build Coastguard Worker   int index;
2652*e5436536SAndroid Build Coastguard Worker 
2653*e5436536SAndroid Build Coastguard Worker   LOUDNESS_INFO* pLoudnessInfo = NULL;
2654*e5436536SAndroid Build Coastguard Worker   VALUE_ORDER valueOrder;
2655*e5436536SAndroid Build Coastguard Worker 
2656*e5436536SAndroid Build Coastguard Worker   /* map MDR_DEFAULT to MDR_PROGRAM_LOUDNESS */
2657*e5436536SAndroid Build Coastguard Worker   METHOD_DEFINITION_REQUEST requestedMethodDefinition =
2658*e5436536SAndroid Build Coastguard Worker       measurementMethodRequested < MDR_ANCHOR_LOUDNESS ? MDR_PROGRAM_LOUDNESS
2659*e5436536SAndroid Build Coastguard Worker                                                        : MDR_ANCHOR_LOUDNESS;
2660*e5436536SAndroid Build Coastguard Worker 
2661*e5436536SAndroid Build Coastguard Worker   if (measurementMethodRequested > MDR_ANCHOR_LOUDNESS) {
2662*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NOT_OK;
2663*e5436536SAndroid Build Coastguard Worker   }
2664*e5436536SAndroid Build Coastguard Worker 
2665*e5436536SAndroid Build Coastguard Worker   _initValueOrder(&valueOrder);
2666*e5436536SAndroid Build Coastguard Worker 
2667*e5436536SAndroid Build Coastguard Worker   *pLoudness = UNDEFINED_LOUDNESS_VALUE;
2668*e5436536SAndroid Build Coastguard Worker   *pLoudnessNormalizationGain = (FIXP_DBL)0;
2669*e5436536SAndroid Build Coastguard Worker 
2670*e5436536SAndroid Build Coastguard Worker   if (drcSetId < 0) {
2671*e5436536SAndroid Build Coastguard Worker     drcSetId = 0;
2672*e5436536SAndroid Build Coastguard Worker   }
2673*e5436536SAndroid Build Coastguard Worker 
2674*e5436536SAndroid Build Coastguard Worker   pLoudnessInfo = _getApplicableLoudnessInfoStructure(
2675*e5436536SAndroid Build Coastguard Worker       hLoudnessInfoSet, drcSetId, downmixIdRequested, albumMode);
2676*e5436536SAndroid Build Coastguard Worker 
2677*e5436536SAndroid Build Coastguard Worker   if (albumMode && (pLoudnessInfo == NULL)) {
2678*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = _getApplicableLoudnessInfoStructure(
2679*e5436536SAndroid Build Coastguard Worker         hLoudnessInfoSet, drcSetId, downmixIdRequested, 0);
2680*e5436536SAndroid Build Coastguard Worker   }
2681*e5436536SAndroid Build Coastguard Worker 
2682*e5436536SAndroid Build Coastguard Worker   if (pLoudnessInfo == NULL) {
2683*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NO_ERROR;
2684*e5436536SAndroid Build Coastguard Worker   }
2685*e5436536SAndroid Build Coastguard Worker 
2686*e5436536SAndroid Build Coastguard Worker   index = -1;
2687*e5436536SAndroid Build Coastguard Worker 
2688*e5436536SAndroid Build Coastguard Worker   do {
2689*e5436536SAndroid Build Coastguard Worker     index = _findMethodDefinition(pLoudnessInfo, requestedMethodDefinition,
2690*e5436536SAndroid Build Coastguard Worker                                   index + 1);
2691*e5436536SAndroid Build Coastguard Worker 
2692*e5436536SAndroid Build Coastguard Worker     if (index >= 0) {
2693*e5436536SAndroid Build Coastguard Worker       _getMethodValue(
2694*e5436536SAndroid Build Coastguard Worker           &valueOrder, pLoudnessInfo->loudnessMeasurement[index].methodValue,
2695*e5436536SAndroid Build Coastguard Worker           pLoudnessInfo->loudnessMeasurement[index].measurementSystem,
2696*e5436536SAndroid Build Coastguard Worker           measurementSystemRequested);
2697*e5436536SAndroid Build Coastguard Worker     }
2698*e5436536SAndroid Build Coastguard Worker   } while (index >= 0);
2699*e5436536SAndroid Build Coastguard Worker 
2700*e5436536SAndroid Build Coastguard Worker   /* repeat with other method definition */
2701*e5436536SAndroid Build Coastguard Worker   if (valueOrder.order == -1) {
2702*e5436536SAndroid Build Coastguard Worker     index = -1;
2703*e5436536SAndroid Build Coastguard Worker 
2704*e5436536SAndroid Build Coastguard Worker     do {
2705*e5436536SAndroid Build Coastguard Worker       index = _findMethodDefinition(
2706*e5436536SAndroid Build Coastguard Worker           pLoudnessInfo,
2707*e5436536SAndroid Build Coastguard Worker           requestedMethodDefinition == MDR_PROGRAM_LOUDNESS
2708*e5436536SAndroid Build Coastguard Worker               ? MDR_ANCHOR_LOUDNESS
2709*e5436536SAndroid Build Coastguard Worker               : MDR_PROGRAM_LOUDNESS,
2710*e5436536SAndroid Build Coastguard Worker           index + 1);
2711*e5436536SAndroid Build Coastguard Worker 
2712*e5436536SAndroid Build Coastguard Worker       if (index >= 0) {
2713*e5436536SAndroid Build Coastguard Worker         _getMethodValue(
2714*e5436536SAndroid Build Coastguard Worker             &valueOrder, pLoudnessInfo->loudnessMeasurement[index].methodValue,
2715*e5436536SAndroid Build Coastguard Worker             pLoudnessInfo->loudnessMeasurement[index].measurementSystem,
2716*e5436536SAndroid Build Coastguard Worker             measurementSystemRequested);
2717*e5436536SAndroid Build Coastguard Worker       }
2718*e5436536SAndroid Build Coastguard Worker     } while (index >= 0);
2719*e5436536SAndroid Build Coastguard Worker   }
2720*e5436536SAndroid Build Coastguard Worker 
2721*e5436536SAndroid Build Coastguard Worker   if (valueOrder.order == -1) {
2722*e5436536SAndroid Build Coastguard Worker     return DRCDEC_SELECTION_PROCESS_NOT_OK;
2723*e5436536SAndroid Build Coastguard Worker   } else {
2724*e5436536SAndroid Build Coastguard Worker     *pLoudnessNormalizationGain = targetLoudness - valueOrder.value;
2725*e5436536SAndroid Build Coastguard Worker     *pLoudness = valueOrder.value;
2726*e5436536SAndroid Build Coastguard Worker   }
2727*e5436536SAndroid Build Coastguard Worker 
2728*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
2729*e5436536SAndroid Build Coastguard Worker }
2730*e5436536SAndroid Build Coastguard Worker 
2731*e5436536SAndroid Build Coastguard Worker /*******************************************/
2732*e5436536SAndroid Build Coastguard Worker 
_truePeakLevelIsPresent(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,int drcSetId,int downmixId,int albumMode)2733*e5436536SAndroid Build Coastguard Worker static int _truePeakLevelIsPresent(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
2734*e5436536SAndroid Build Coastguard Worker                                    int drcSetId, int downmixId, int albumMode) {
2735*e5436536SAndroid Build Coastguard Worker   int i;
2736*e5436536SAndroid Build Coastguard Worker   int count;
2737*e5436536SAndroid Build Coastguard Worker   LOUDNESS_INFO* pLoudnessInfo = NULL;
2738*e5436536SAndroid Build Coastguard Worker 
2739*e5436536SAndroid Build Coastguard Worker   if (albumMode) {
2740*e5436536SAndroid Build Coastguard Worker     count = hLoudnessInfoSet->loudnessInfoAlbumCount;
2741*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
2742*e5436536SAndroid Build Coastguard Worker   } else {
2743*e5436536SAndroid Build Coastguard Worker     count = hLoudnessInfoSet->loudnessInfoCount;
2744*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
2745*e5436536SAndroid Build Coastguard Worker   }
2746*e5436536SAndroid Build Coastguard Worker 
2747*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < count; i++) {
2748*e5436536SAndroid Build Coastguard Worker     if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
2749*e5436536SAndroid Build Coastguard Worker         (pLoudnessInfo[i].downmixId == downmixId)) {
2750*e5436536SAndroid Build Coastguard Worker       if (pLoudnessInfo[i].truePeakLevelPresent) return 1;
2751*e5436536SAndroid Build Coastguard Worker     }
2752*e5436536SAndroid Build Coastguard Worker   }
2753*e5436536SAndroid Build Coastguard Worker 
2754*e5436536SAndroid Build Coastguard Worker   return 0;
2755*e5436536SAndroid Build Coastguard Worker }
2756*e5436536SAndroid Build Coastguard Worker 
_getTruePeakLevel(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,int drcSetId,int downmixId,int albumMode,FIXP_DBL * pTruePeakLevel)2757*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _getTruePeakLevel(
2758*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int drcSetId, int downmixId,
2759*e5436536SAndroid Build Coastguard Worker     int albumMode, FIXP_DBL* pTruePeakLevel) {
2760*e5436536SAndroid Build Coastguard Worker   int i;
2761*e5436536SAndroid Build Coastguard Worker   int count;
2762*e5436536SAndroid Build Coastguard Worker   LOUDNESS_INFO* pLoudnessInfo = NULL;
2763*e5436536SAndroid Build Coastguard Worker 
2764*e5436536SAndroid Build Coastguard Worker   if (albumMode) {
2765*e5436536SAndroid Build Coastguard Worker     count = hLoudnessInfoSet->loudnessInfoAlbumCount;
2766*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
2767*e5436536SAndroid Build Coastguard Worker   } else {
2768*e5436536SAndroid Build Coastguard Worker     count = hLoudnessInfoSet->loudnessInfoCount;
2769*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
2770*e5436536SAndroid Build Coastguard Worker   }
2771*e5436536SAndroid Build Coastguard Worker 
2772*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < count; i++) {
2773*e5436536SAndroid Build Coastguard Worker     if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
2774*e5436536SAndroid Build Coastguard Worker         (pLoudnessInfo[i].downmixId == downmixId)) {
2775*e5436536SAndroid Build Coastguard Worker       if (pLoudnessInfo[i].truePeakLevelPresent) {
2776*e5436536SAndroid Build Coastguard Worker         *pTruePeakLevel = pLoudnessInfo[i].truePeakLevel;
2777*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_NO_ERROR;
2778*e5436536SAndroid Build Coastguard Worker       }
2779*e5436536SAndroid Build Coastguard Worker     }
2780*e5436536SAndroid Build Coastguard Worker   }
2781*e5436536SAndroid Build Coastguard Worker 
2782*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NOT_OK;
2783*e5436536SAndroid Build Coastguard Worker }
2784*e5436536SAndroid Build Coastguard Worker 
_samplePeakLevelIsPresent(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,int drcSetId,int downmixId,int albumMode)2785*e5436536SAndroid Build Coastguard Worker static int _samplePeakLevelIsPresent(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
2786*e5436536SAndroid Build Coastguard Worker                                      int drcSetId, int downmixId,
2787*e5436536SAndroid Build Coastguard Worker                                      int albumMode) {
2788*e5436536SAndroid Build Coastguard Worker   int i;
2789*e5436536SAndroid Build Coastguard Worker   int count;
2790*e5436536SAndroid Build Coastguard Worker   LOUDNESS_INFO* pLoudnessInfo = NULL;
2791*e5436536SAndroid Build Coastguard Worker 
2792*e5436536SAndroid Build Coastguard Worker   if (albumMode) {
2793*e5436536SAndroid Build Coastguard Worker     count = hLoudnessInfoSet->loudnessInfoAlbumCount;
2794*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
2795*e5436536SAndroid Build Coastguard Worker   } else {
2796*e5436536SAndroid Build Coastguard Worker     count = hLoudnessInfoSet->loudnessInfoCount;
2797*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
2798*e5436536SAndroid Build Coastguard Worker   }
2799*e5436536SAndroid Build Coastguard Worker 
2800*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < count; i++) {
2801*e5436536SAndroid Build Coastguard Worker     if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
2802*e5436536SAndroid Build Coastguard Worker         (pLoudnessInfo[i].downmixId == downmixId)) {
2803*e5436536SAndroid Build Coastguard Worker       if (pLoudnessInfo[i].samplePeakLevelPresent) return 1;
2804*e5436536SAndroid Build Coastguard Worker     }
2805*e5436536SAndroid Build Coastguard Worker   }
2806*e5436536SAndroid Build Coastguard Worker 
2807*e5436536SAndroid Build Coastguard Worker   return 0;
2808*e5436536SAndroid Build Coastguard Worker }
2809*e5436536SAndroid Build Coastguard Worker 
_getSamplePeakLevel(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,int drcSetId,int downmixId,int albumMode,FIXP_DBL * pSamplePeakLevel)2810*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _getSamplePeakLevel(
2811*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int drcSetId, int downmixId,
2812*e5436536SAndroid Build Coastguard Worker     int albumMode, FIXP_DBL* pSamplePeakLevel /* e = 7 */
2813*e5436536SAndroid Build Coastguard Worker ) {
2814*e5436536SAndroid Build Coastguard Worker   int i;
2815*e5436536SAndroid Build Coastguard Worker   int count;
2816*e5436536SAndroid Build Coastguard Worker   LOUDNESS_INFO* pLoudnessInfo = NULL;
2817*e5436536SAndroid Build Coastguard Worker 
2818*e5436536SAndroid Build Coastguard Worker   if (albumMode) {
2819*e5436536SAndroid Build Coastguard Worker     count = hLoudnessInfoSet->loudnessInfoAlbumCount;
2820*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
2821*e5436536SAndroid Build Coastguard Worker   } else {
2822*e5436536SAndroid Build Coastguard Worker     count = hLoudnessInfoSet->loudnessInfoCount;
2823*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
2824*e5436536SAndroid Build Coastguard Worker   }
2825*e5436536SAndroid Build Coastguard Worker 
2826*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < count; i++) {
2827*e5436536SAndroid Build Coastguard Worker     if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
2828*e5436536SAndroid Build Coastguard Worker         (pLoudnessInfo[i].downmixId == downmixId)) {
2829*e5436536SAndroid Build Coastguard Worker       if (pLoudnessInfo[i].samplePeakLevelPresent) {
2830*e5436536SAndroid Build Coastguard Worker         *pSamplePeakLevel = pLoudnessInfo[i].samplePeakLevel;
2831*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_NO_ERROR;
2832*e5436536SAndroid Build Coastguard Worker       }
2833*e5436536SAndroid Build Coastguard Worker     }
2834*e5436536SAndroid Build Coastguard Worker   }
2835*e5436536SAndroid Build Coastguard Worker 
2836*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NOT_OK;
2837*e5436536SAndroid Build Coastguard Worker }
2838*e5436536SAndroid Build Coastguard Worker 
_limiterPeakTargetIsPresent(DRC_INSTRUCTIONS_UNI_DRC * pDrcInstruction,int drcSetId,int downmixId)2839*e5436536SAndroid Build Coastguard Worker static int _limiterPeakTargetIsPresent(
2840*e5436536SAndroid Build Coastguard Worker     DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction, int drcSetId, int downmixId) {
2841*e5436536SAndroid Build Coastguard Worker   int i;
2842*e5436536SAndroid Build Coastguard Worker 
2843*e5436536SAndroid Build Coastguard Worker   if (pDrcInstruction->limiterPeakTargetPresent) {
2844*e5436536SAndroid Build Coastguard Worker     if ((pDrcInstruction->downmixId[0] == downmixId) ||
2845*e5436536SAndroid Build Coastguard Worker         (pDrcInstruction->downmixId[0] == 0x7F)) {
2846*e5436536SAndroid Build Coastguard Worker       return 1;
2847*e5436536SAndroid Build Coastguard Worker     }
2848*e5436536SAndroid Build Coastguard Worker 
2849*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < pDrcInstruction->downmixIdCount; i++) {
2850*e5436536SAndroid Build Coastguard Worker       if (pDrcInstruction->downmixId[i] == downmixId) {
2851*e5436536SAndroid Build Coastguard Worker         return 1;
2852*e5436536SAndroid Build Coastguard Worker       }
2853*e5436536SAndroid Build Coastguard Worker     }
2854*e5436536SAndroid Build Coastguard Worker   }
2855*e5436536SAndroid Build Coastguard Worker 
2856*e5436536SAndroid Build Coastguard Worker   return 0;
2857*e5436536SAndroid Build Coastguard Worker }
2858*e5436536SAndroid Build Coastguard Worker 
_getLimiterPeakTarget(DRC_INSTRUCTIONS_UNI_DRC * pDrcInstruction,int drcSetId,int downmixId,FIXP_DBL * pLimiterPeakTarget)2859*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _getLimiterPeakTarget(
2860*e5436536SAndroid Build Coastguard Worker     DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction, int drcSetId, int downmixId,
2861*e5436536SAndroid Build Coastguard Worker     FIXP_DBL* pLimiterPeakTarget) {
2862*e5436536SAndroid Build Coastguard Worker   int i;
2863*e5436536SAndroid Build Coastguard Worker 
2864*e5436536SAndroid Build Coastguard Worker   if (pDrcInstruction->limiterPeakTargetPresent) {
2865*e5436536SAndroid Build Coastguard Worker     if ((pDrcInstruction->downmixId[0] == downmixId) ||
2866*e5436536SAndroid Build Coastguard Worker         (pDrcInstruction->downmixId[0] == 0x7F)) {
2867*e5436536SAndroid Build Coastguard Worker       *pLimiterPeakTarget =
2868*e5436536SAndroid Build Coastguard Worker           ((FX_SGL2FX_DBL(pDrcInstruction->limiterPeakTarget) >> 2));
2869*e5436536SAndroid Build Coastguard Worker       return DRCDEC_SELECTION_PROCESS_NO_ERROR;
2870*e5436536SAndroid Build Coastguard Worker     }
2871*e5436536SAndroid Build Coastguard Worker 
2872*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < pDrcInstruction->downmixIdCount; i++) {
2873*e5436536SAndroid Build Coastguard Worker       if (pDrcInstruction->downmixId[i] == downmixId) {
2874*e5436536SAndroid Build Coastguard Worker         *pLimiterPeakTarget =
2875*e5436536SAndroid Build Coastguard Worker             ((FX_SGL2FX_DBL(pDrcInstruction->limiterPeakTarget) >> 2));
2876*e5436536SAndroid Build Coastguard Worker         return DRCDEC_SELECTION_PROCESS_NO_ERROR;
2877*e5436536SAndroid Build Coastguard Worker       }
2878*e5436536SAndroid Build Coastguard Worker     }
2879*e5436536SAndroid Build Coastguard Worker   }
2880*e5436536SAndroid Build Coastguard Worker 
2881*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NOT_OK;
2882*e5436536SAndroid Build Coastguard Worker }
2883*e5436536SAndroid Build Coastguard Worker 
_downmixCoefficientsArePresent(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,int downmixId,int * pIndex)2884*e5436536SAndroid Build Coastguard Worker static int _downmixCoefficientsArePresent(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
2885*e5436536SAndroid Build Coastguard Worker                                           int downmixId, int* pIndex) {
2886*e5436536SAndroid Build Coastguard Worker   int i;
2887*e5436536SAndroid Build Coastguard Worker   *pIndex = -1;
2888*e5436536SAndroid Build Coastguard Worker 
2889*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
2890*e5436536SAndroid Build Coastguard Worker     if (hUniDrcConfig->downmixInstructions[i].downmixId == downmixId) {
2891*e5436536SAndroid Build Coastguard Worker       if (hUniDrcConfig->downmixInstructions[i].downmixCoefficientsPresent) {
2892*e5436536SAndroid Build Coastguard Worker         if (hUniDrcConfig->downmixInstructions[i].targetChannelCount > 8)
2893*e5436536SAndroid Build Coastguard Worker           return 0;
2894*e5436536SAndroid Build Coastguard Worker         *pIndex = i;
2895*e5436536SAndroid Build Coastguard Worker         return 1;
2896*e5436536SAndroid Build Coastguard Worker       }
2897*e5436536SAndroid Build Coastguard Worker     }
2898*e5436536SAndroid Build Coastguard Worker   }
2899*e5436536SAndroid Build Coastguard Worker 
2900*e5436536SAndroid Build Coastguard Worker   return 0;
2901*e5436536SAndroid Build Coastguard Worker }
2902*e5436536SAndroid Build Coastguard Worker 
_getSignalPeakLevel(HANDLE_SEL_PROC_INPUT hSelProcInput,HANDLE_UNI_DRC_CONFIG hUniDrcConfig,HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,DRC_INSTRUCTIONS_UNI_DRC * pInst,int downmixIdRequested,int * explicitPeakInformationPresent,FIXP_DBL * signalPeakLevelOut,SEL_PROC_CODEC_MODE codecMode)2903*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _getSignalPeakLevel(
2904*e5436536SAndroid Build Coastguard Worker     HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
2905*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, DRC_INSTRUCTIONS_UNI_DRC* pInst,
2906*e5436536SAndroid Build Coastguard Worker     int downmixIdRequested, int* explicitPeakInformationPresent,
2907*e5436536SAndroid Build Coastguard Worker     FIXP_DBL* signalPeakLevelOut, /* e = 7 */
2908*e5436536SAndroid Build Coastguard Worker     SEL_PROC_CODEC_MODE codecMode
2909*e5436536SAndroid Build Coastguard Worker 
2910*e5436536SAndroid Build Coastguard Worker ) {
2911*e5436536SAndroid Build Coastguard Worker   DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
2912*e5436536SAndroid Build Coastguard Worker 
2913*e5436536SAndroid Build Coastguard Worker   int albumMode = hSelProcInput->albumMode;
2914*e5436536SAndroid Build Coastguard Worker 
2915*e5436536SAndroid Build Coastguard Worker   FIXP_DBL signalPeakLevelTmp = (FIXP_DBL)0;
2916*e5436536SAndroid Build Coastguard Worker   FIXP_DBL signalPeakLevel = FIXP_DBL(0);
2917*e5436536SAndroid Build Coastguard Worker 
2918*e5436536SAndroid Build Coastguard Worker   int dmxId = downmixIdRequested;
2919*e5436536SAndroid Build Coastguard Worker 
2920*e5436536SAndroid Build Coastguard Worker   int drcSetId = pInst->drcSetId;
2921*e5436536SAndroid Build Coastguard Worker 
2922*e5436536SAndroid Build Coastguard Worker   if (drcSetId < 0) {
2923*e5436536SAndroid Build Coastguard Worker     drcSetId = 0;
2924*e5436536SAndroid Build Coastguard Worker   }
2925*e5436536SAndroid Build Coastguard Worker 
2926*e5436536SAndroid Build Coastguard Worker   *explicitPeakInformationPresent = 1;
2927*e5436536SAndroid Build Coastguard Worker 
2928*e5436536SAndroid Build Coastguard Worker   if (_truePeakLevelIsPresent(hLoudnessInfoSet, drcSetId, dmxId, albumMode)) {
2929*e5436536SAndroid Build Coastguard Worker     retVal = _getTruePeakLevel(hLoudnessInfoSet, drcSetId, dmxId, albumMode,
2930*e5436536SAndroid Build Coastguard Worker                                &signalPeakLevel);
2931*e5436536SAndroid Build Coastguard Worker     if (retVal) return (retVal);
2932*e5436536SAndroid Build Coastguard Worker   } else if (_samplePeakLevelIsPresent(hLoudnessInfoSet, drcSetId, dmxId,
2933*e5436536SAndroid Build Coastguard Worker                                        albumMode)) {
2934*e5436536SAndroid Build Coastguard Worker     retVal = _getSamplePeakLevel(hLoudnessInfoSet, drcSetId, dmxId, albumMode,
2935*e5436536SAndroid Build Coastguard Worker                                  &signalPeakLevel);
2936*e5436536SAndroid Build Coastguard Worker     if (retVal) return (retVal);
2937*e5436536SAndroid Build Coastguard Worker   } else if (_truePeakLevelIsPresent(hLoudnessInfoSet, 0x3F, dmxId,
2938*e5436536SAndroid Build Coastguard Worker                                      albumMode)) {
2939*e5436536SAndroid Build Coastguard Worker     retVal = _getTruePeakLevel(hLoudnessInfoSet, 0x3F, dmxId, albumMode,
2940*e5436536SAndroid Build Coastguard Worker                                &signalPeakLevel);
2941*e5436536SAndroid Build Coastguard Worker     if (retVal) return (retVal);
2942*e5436536SAndroid Build Coastguard Worker   } else if (_samplePeakLevelIsPresent(hLoudnessInfoSet, 0x3F, dmxId,
2943*e5436536SAndroid Build Coastguard Worker                                        albumMode)) {
2944*e5436536SAndroid Build Coastguard Worker     retVal = _getSamplePeakLevel(hLoudnessInfoSet, 0x3F, dmxId, albumMode,
2945*e5436536SAndroid Build Coastguard Worker                                  &signalPeakLevel);
2946*e5436536SAndroid Build Coastguard Worker     if (retVal) return (retVal);
2947*e5436536SAndroid Build Coastguard Worker   } else if (_limiterPeakTargetIsPresent(pInst, drcSetId, dmxId)) {
2948*e5436536SAndroid Build Coastguard Worker     retVal = _getLimiterPeakTarget(pInst, drcSetId, dmxId, &signalPeakLevel);
2949*e5436536SAndroid Build Coastguard Worker     if (retVal) return (retVal);
2950*e5436536SAndroid Build Coastguard Worker   } else if (dmxId != 0) {
2951*e5436536SAndroid Build Coastguard Worker     int downmixInstructionIndex = 0;
2952*e5436536SAndroid Build Coastguard Worker     FIXP_DBL downmixPeakLevelDB = 0;
2953*e5436536SAndroid Build Coastguard Worker 
2954*e5436536SAndroid Build Coastguard Worker     *explicitPeakInformationPresent = 0;
2955*e5436536SAndroid Build Coastguard Worker 
2956*e5436536SAndroid Build Coastguard Worker     signalPeakLevelTmp = FIXP_DBL(0);
2957*e5436536SAndroid Build Coastguard Worker 
2958*e5436536SAndroid Build Coastguard Worker     if (_downmixCoefficientsArePresent(hUniDrcConfig, dmxId,
2959*e5436536SAndroid Build Coastguard Worker                                        &downmixInstructionIndex)) {
2960*e5436536SAndroid Build Coastguard Worker       FIXP_DBL dB_m;
2961*e5436536SAndroid Build Coastguard Worker       int dB_e;
2962*e5436536SAndroid Build Coastguard Worker       FIXP_DBL coeff;
2963*e5436536SAndroid Build Coastguard Worker       FIXP_DBL sum, maxSum; /* e = 7, so it is possible to sum up up to 32
2964*e5436536SAndroid Build Coastguard Worker                                downmix coefficients (with e = 2) */
2965*e5436536SAndroid Build Coastguard Worker       int i, j;
2966*e5436536SAndroid Build Coastguard Worker       DOWNMIX_INSTRUCTIONS* pDown =
2967*e5436536SAndroid Build Coastguard Worker           &(hUniDrcConfig->downmixInstructions[downmixInstructionIndex]);
2968*e5436536SAndroid Build Coastguard Worker       FIXP_DBL downmixOffset = getDownmixOffset(
2969*e5436536SAndroid Build Coastguard Worker           pDown, hUniDrcConfig->channelLayout.baseChannelCount); /* e = 1 */
2970*e5436536SAndroid Build Coastguard Worker       maxSum = (FIXP_DBL)0;
2971*e5436536SAndroid Build Coastguard Worker 
2972*e5436536SAndroid Build Coastguard Worker       for (i = 0; i < pDown->targetChannelCount; i++) {
2973*e5436536SAndroid Build Coastguard Worker         sum = (FIXP_DBL)0;
2974*e5436536SAndroid Build Coastguard Worker         for (j = 0; j < hUniDrcConfig->channelLayout.baseChannelCount; j++) {
2975*e5436536SAndroid Build Coastguard Worker           coeff = pDown->downmixCoefficient[j + i * hUniDrcConfig->channelLayout
2976*e5436536SAndroid Build Coastguard Worker                                                         .baseChannelCount];
2977*e5436536SAndroid Build Coastguard Worker           sum += coeff >> 5;
2978*e5436536SAndroid Build Coastguard Worker         }
2979*e5436536SAndroid Build Coastguard Worker         if (maxSum < sum) maxSum = sum;
2980*e5436536SAndroid Build Coastguard Worker       }
2981*e5436536SAndroid Build Coastguard Worker 
2982*e5436536SAndroid Build Coastguard Worker       maxSum = fMultDiv2(maxSum, downmixOffset) << 2;
2983*e5436536SAndroid Build Coastguard Worker 
2984*e5436536SAndroid Build Coastguard Worker       if (maxSum == FL2FXCONST_DBL(1.0f / (float)(1 << 7))) {
2985*e5436536SAndroid Build Coastguard Worker         downmixPeakLevelDB = (FIXP_DBL)0;
2986*e5436536SAndroid Build Coastguard Worker       } else {
2987*e5436536SAndroid Build Coastguard Worker         dB_m = lin2dB(maxSum, 7, &dB_e); /* e_maxSum = 7 */
2988*e5436536SAndroid Build Coastguard Worker         downmixPeakLevelDB =
2989*e5436536SAndroid Build Coastguard Worker             scaleValue(dB_m, dB_e - 7); /* e_downmixPeakLevelDB = 7 */
2990*e5436536SAndroid Build Coastguard Worker       }
2991*e5436536SAndroid Build Coastguard Worker     }
2992*e5436536SAndroid Build Coastguard Worker 
2993*e5436536SAndroid Build Coastguard Worker     if (_truePeakLevelIsPresent(hLoudnessInfoSet, drcSetId, 0, albumMode)) {
2994*e5436536SAndroid Build Coastguard Worker       retVal = _getTruePeakLevel(hLoudnessInfoSet, drcSetId, 0, albumMode,
2995*e5436536SAndroid Build Coastguard Worker                                  &signalPeakLevelTmp);
2996*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
2997*e5436536SAndroid Build Coastguard Worker     } else if (_samplePeakLevelIsPresent(hLoudnessInfoSet, drcSetId, 0,
2998*e5436536SAndroid Build Coastguard Worker                                          albumMode)) {
2999*e5436536SAndroid Build Coastguard Worker       retVal = _getSamplePeakLevel(hLoudnessInfoSet, drcSetId, 0, albumMode,
3000*e5436536SAndroid Build Coastguard Worker                                    &signalPeakLevelTmp);
3001*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
3002*e5436536SAndroid Build Coastguard Worker     } else if (_truePeakLevelIsPresent(hLoudnessInfoSet, 0x3F, 0, albumMode)) {
3003*e5436536SAndroid Build Coastguard Worker       retVal = _getTruePeakLevel(hLoudnessInfoSet, 0x3F, 0, albumMode,
3004*e5436536SAndroid Build Coastguard Worker                                  &signalPeakLevelTmp);
3005*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
3006*e5436536SAndroid Build Coastguard Worker     } else if (_samplePeakLevelIsPresent(hLoudnessInfoSet, 0x3F, 0,
3007*e5436536SAndroid Build Coastguard Worker                                          albumMode)) {
3008*e5436536SAndroid Build Coastguard Worker       retVal = _getSamplePeakLevel(hLoudnessInfoSet, 0x3F, 0, albumMode,
3009*e5436536SAndroid Build Coastguard Worker                                    &signalPeakLevelTmp);
3010*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
3011*e5436536SAndroid Build Coastguard Worker     } else if (_limiterPeakTargetIsPresent(pInst, drcSetId, 0)) {
3012*e5436536SAndroid Build Coastguard Worker       retVal = _getLimiterPeakTarget(pInst, drcSetId, 0, &signalPeakLevelTmp);
3013*e5436536SAndroid Build Coastguard Worker       if (retVal) return (retVal);
3014*e5436536SAndroid Build Coastguard Worker     }
3015*e5436536SAndroid Build Coastguard Worker 
3016*e5436536SAndroid Build Coastguard Worker     signalPeakLevel = signalPeakLevelTmp + downmixPeakLevelDB;
3017*e5436536SAndroid Build Coastguard Worker   } else {
3018*e5436536SAndroid Build Coastguard Worker     signalPeakLevel = FIXP_DBL(0); /* worst case estimate */
3019*e5436536SAndroid Build Coastguard Worker     *explicitPeakInformationPresent = FIXP_DBL(0);
3020*e5436536SAndroid Build Coastguard Worker   }
3021*e5436536SAndroid Build Coastguard Worker 
3022*e5436536SAndroid Build Coastguard Worker   *signalPeakLevelOut = signalPeakLevel;
3023*e5436536SAndroid Build Coastguard Worker 
3024*e5436536SAndroid Build Coastguard Worker   return retVal;
3025*e5436536SAndroid Build Coastguard Worker }
3026*e5436536SAndroid Build Coastguard Worker 
_extractLoudnessPeakToAverageValue(LOUDNESS_INFO * loudnessInfo,DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,int * pLoudnessPeakToAverageValuePresent,FIXP_DBL * pLoudnessPeakToAverageValue)3027*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _extractLoudnessPeakToAverageValue(
3028*e5436536SAndroid Build Coastguard Worker     LOUDNESS_INFO* loudnessInfo,
3029*e5436536SAndroid Build Coastguard Worker     DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,
3030*e5436536SAndroid Build Coastguard Worker     int* pLoudnessPeakToAverageValuePresent,
3031*e5436536SAndroid Build Coastguard Worker     FIXP_DBL* pLoudnessPeakToAverageValue) {
3032*e5436536SAndroid Build Coastguard Worker   int i;
3033*e5436536SAndroid Build Coastguard Worker 
3034*e5436536SAndroid Build Coastguard Worker   VALUE_ORDER valueOrderLoudness;
3035*e5436536SAndroid Build Coastguard Worker   VALUE_ORDER valueOrderPeakLoudness;
3036*e5436536SAndroid Build Coastguard Worker 
3037*e5436536SAndroid Build Coastguard Worker   _initValueOrder(&valueOrderLoudness);
3038*e5436536SAndroid Build Coastguard Worker   _initValueOrder(&valueOrderPeakLoudness);
3039*e5436536SAndroid Build Coastguard Worker 
3040*e5436536SAndroid Build Coastguard Worker   LOUDNESS_MEASUREMENT* pLoudnessMeasure = NULL;
3041*e5436536SAndroid Build Coastguard Worker 
3042*e5436536SAndroid Build Coastguard Worker   *pLoudnessPeakToAverageValuePresent = 0;
3043*e5436536SAndroid Build Coastguard Worker 
3044*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < loudnessInfo->measurementCount; i++) {
3045*e5436536SAndroid Build Coastguard Worker     pLoudnessMeasure = &(loudnessInfo->loudnessMeasurement[i]);
3046*e5436536SAndroid Build Coastguard Worker 
3047*e5436536SAndroid Build Coastguard Worker     if (pLoudnessMeasure->methodDefinition == MD_PROGRAM_LOUDNESS) {
3048*e5436536SAndroid Build Coastguard Worker       _getMethodValue(&valueOrderLoudness, pLoudnessMeasure->methodValue,
3049*e5436536SAndroid Build Coastguard Worker                       pLoudnessMeasure->measurementSystem, MS_PROGRAMLOUDNESS);
3050*e5436536SAndroid Build Coastguard Worker     }
3051*e5436536SAndroid Build Coastguard Worker 
3052*e5436536SAndroid Build Coastguard Worker     if ((dynamicRangeMeasurementType == DRMRT_SHORT_TERM_LOUDNESS_TO_AVG) &&
3053*e5436536SAndroid Build Coastguard Worker         (pLoudnessMeasure->methodDefinition == MD_SHORT_TERM_LOUDNESS_MAX)) {
3054*e5436536SAndroid Build Coastguard Worker       _getMethodValue(&valueOrderPeakLoudness, pLoudnessMeasure->methodValue,
3055*e5436536SAndroid Build Coastguard Worker                       pLoudnessMeasure->measurementSystem, MS_PEAKLOUDNESS);
3056*e5436536SAndroid Build Coastguard Worker     }
3057*e5436536SAndroid Build Coastguard Worker 
3058*e5436536SAndroid Build Coastguard Worker     if ((dynamicRangeMeasurementType == DRMRT_MOMENTARY_LOUDNESS_TO_AVG) &&
3059*e5436536SAndroid Build Coastguard Worker         (pLoudnessMeasure->methodDefinition == MD_MOMENTARY_LOUDNESS_MAX)) {
3060*e5436536SAndroid Build Coastguard Worker       _getMethodValue(&valueOrderPeakLoudness, pLoudnessMeasure->methodValue,
3061*e5436536SAndroid Build Coastguard Worker                       pLoudnessMeasure->measurementSystem, MS_PEAKLOUDNESS);
3062*e5436536SAndroid Build Coastguard Worker     }
3063*e5436536SAndroid Build Coastguard Worker 
3064*e5436536SAndroid Build Coastguard Worker     if ((dynamicRangeMeasurementType == DRMRT_TOP_OF_LOUDNESS_RANGE_TO_AVG) &&
3065*e5436536SAndroid Build Coastguard Worker         (pLoudnessMeasure->methodDefinition == MD_MAX_OF_LOUDNESS_RANGE)) {
3066*e5436536SAndroid Build Coastguard Worker       _getMethodValue(&valueOrderPeakLoudness, pLoudnessMeasure->methodValue,
3067*e5436536SAndroid Build Coastguard Worker                       pLoudnessMeasure->measurementSystem, MS_PEAKLOUDNESS);
3068*e5436536SAndroid Build Coastguard Worker     }
3069*e5436536SAndroid Build Coastguard Worker   }
3070*e5436536SAndroid Build Coastguard Worker 
3071*e5436536SAndroid Build Coastguard Worker   if ((valueOrderLoudness.order > -1) && (valueOrderPeakLoudness.order > -1)) {
3072*e5436536SAndroid Build Coastguard Worker     *pLoudnessPeakToAverageValue =
3073*e5436536SAndroid Build Coastguard Worker         valueOrderPeakLoudness.value - valueOrderLoudness.value;
3074*e5436536SAndroid Build Coastguard Worker     *pLoudnessPeakToAverageValuePresent = 1;
3075*e5436536SAndroid Build Coastguard Worker   }
3076*e5436536SAndroid Build Coastguard Worker 
3077*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
3078*e5436536SAndroid Build Coastguard Worker }
3079*e5436536SAndroid Build Coastguard Worker 
3080*e5436536SAndroid Build Coastguard Worker /*******************************************/
3081*e5436536SAndroid Build Coastguard Worker 
_selectAlbumLoudness(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,DRCDEC_SELECTION * pCandidatesPotential,DRCDEC_SELECTION * pCandidatesSelected)3082*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _selectAlbumLoudness(
3083*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
3084*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesPotential,
3085*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION* pCandidatesSelected) {
3086*e5436536SAndroid Build Coastguard Worker   int i, j;
3087*e5436536SAndroid Build Coastguard Worker 
3088*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
3089*e5436536SAndroid Build Coastguard Worker     DRCDEC_SELECTION_DATA* pCandidate =
3090*e5436536SAndroid Build Coastguard Worker         _drcdec_selection_getAt(pCandidatesPotential, i);
3091*e5436536SAndroid Build Coastguard Worker     if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
3092*e5436536SAndroid Build Coastguard Worker 
3093*e5436536SAndroid Build Coastguard Worker     for (j = 0; j < hLoudnessInfoSet->loudnessInfoAlbumCount; j++) {
3094*e5436536SAndroid Build Coastguard Worker       if (pCandidate->pInst->drcSetId ==
3095*e5436536SAndroid Build Coastguard Worker           hLoudnessInfoSet->loudnessInfoAlbum[j].drcSetId) {
3096*e5436536SAndroid Build Coastguard Worker         if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
3097*e5436536SAndroid Build Coastguard Worker           return DRCDEC_SELECTION_PROCESS_NOT_OK;
3098*e5436536SAndroid Build Coastguard Worker       }
3099*e5436536SAndroid Build Coastguard Worker     }
3100*e5436536SAndroid Build Coastguard Worker   }
3101*e5436536SAndroid Build Coastguard Worker 
3102*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
3103*e5436536SAndroid Build Coastguard Worker }
3104*e5436536SAndroid Build Coastguard Worker 
3105*e5436536SAndroid Build Coastguard Worker /*******************************************/
3106*e5436536SAndroid Build Coastguard Worker 
_findMethodDefinition(LOUDNESS_INFO * pLoudnessInfo,int methodDefinition,int startIndex)3107*e5436536SAndroid Build Coastguard Worker static int _findMethodDefinition(LOUDNESS_INFO* pLoudnessInfo,
3108*e5436536SAndroid Build Coastguard Worker                                  int methodDefinition, int startIndex) {
3109*e5436536SAndroid Build Coastguard Worker   int i;
3110*e5436536SAndroid Build Coastguard Worker   int index = -1;
3111*e5436536SAndroid Build Coastguard Worker 
3112*e5436536SAndroid Build Coastguard Worker   for (i = startIndex; i < pLoudnessInfo->measurementCount; i++) {
3113*e5436536SAndroid Build Coastguard Worker     if (pLoudnessInfo->loudnessMeasurement[i].methodDefinition ==
3114*e5436536SAndroid Build Coastguard Worker         methodDefinition) {
3115*e5436536SAndroid Build Coastguard Worker       index = i;
3116*e5436536SAndroid Build Coastguard Worker       break;
3117*e5436536SAndroid Build Coastguard Worker     }
3118*e5436536SAndroid Build Coastguard Worker   }
3119*e5436536SAndroid Build Coastguard Worker 
3120*e5436536SAndroid Build Coastguard Worker   return index;
3121*e5436536SAndroid Build Coastguard Worker }
3122*e5436536SAndroid Build Coastguard Worker 
3123*e5436536SAndroid Build Coastguard Worker /*******************************************/
3124*e5436536SAndroid Build Coastguard Worker 
_getMixingLevel(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,int downmixIdRequested,int drcSetIdRequested,int albumMode,FIXP_DBL * pMixingLevel)3125*e5436536SAndroid Build Coastguard Worker static DRCDEC_SELECTION_PROCESS_RETURN _getMixingLevel(
3126*e5436536SAndroid Build Coastguard Worker     HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int downmixIdRequested,
3127*e5436536SAndroid Build Coastguard Worker     int drcSetIdRequested, int albumMode, FIXP_DBL* pMixingLevel) {
3128*e5436536SAndroid Build Coastguard Worker   const FIXP_DBL mixingLevelDefault = FL2FXCONST_DBL(85.0f / (float)(1 << 7));
3129*e5436536SAndroid Build Coastguard Worker 
3130*e5436536SAndroid Build Coastguard Worker   int i;
3131*e5436536SAndroid Build Coastguard Worker   int count;
3132*e5436536SAndroid Build Coastguard Worker 
3133*e5436536SAndroid Build Coastguard Worker   LOUDNESS_INFO* pLoudnessInfo = NULL;
3134*e5436536SAndroid Build Coastguard Worker 
3135*e5436536SAndroid Build Coastguard Worker   *pMixingLevel = mixingLevelDefault;
3136*e5436536SAndroid Build Coastguard Worker 
3137*e5436536SAndroid Build Coastguard Worker   if (drcSetIdRequested < 0) {
3138*e5436536SAndroid Build Coastguard Worker     drcSetIdRequested = 0;
3139*e5436536SAndroid Build Coastguard Worker   }
3140*e5436536SAndroid Build Coastguard Worker 
3141*e5436536SAndroid Build Coastguard Worker   if (albumMode) {
3142*e5436536SAndroid Build Coastguard Worker     count = hLoudnessInfoSet->loudnessInfoAlbumCount;
3143*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
3144*e5436536SAndroid Build Coastguard Worker   } else {
3145*e5436536SAndroid Build Coastguard Worker     count = hLoudnessInfoSet->loudnessInfoCount;
3146*e5436536SAndroid Build Coastguard Worker     pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
3147*e5436536SAndroid Build Coastguard Worker   }
3148*e5436536SAndroid Build Coastguard Worker 
3149*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < count; i++) {
3150*e5436536SAndroid Build Coastguard Worker     if ((drcSetIdRequested == pLoudnessInfo[i].drcSetId) &&
3151*e5436536SAndroid Build Coastguard Worker         ((downmixIdRequested == pLoudnessInfo[i].downmixId) ||
3152*e5436536SAndroid Build Coastguard Worker          (DOWNMIX_ID_ANY_DOWNMIX == pLoudnessInfo[i].downmixId))) {
3153*e5436536SAndroid Build Coastguard Worker       int index = _findMethodDefinition(&pLoudnessInfo[i], MD_MIXING_LEVEL, 0);
3154*e5436536SAndroid Build Coastguard Worker 
3155*e5436536SAndroid Build Coastguard Worker       if (index >= 0) {
3156*e5436536SAndroid Build Coastguard Worker         *pMixingLevel = pLoudnessInfo[i].loudnessMeasurement[index].methodValue;
3157*e5436536SAndroid Build Coastguard Worker         break;
3158*e5436536SAndroid Build Coastguard Worker       }
3159*e5436536SAndroid Build Coastguard Worker     }
3160*e5436536SAndroid Build Coastguard Worker   }
3161*e5436536SAndroid Build Coastguard Worker 
3162*e5436536SAndroid Build Coastguard Worker   return DRCDEC_SELECTION_PROCESS_NO_ERROR;
3163*e5436536SAndroid Build Coastguard Worker }
3164*e5436536SAndroid Build Coastguard Worker 
3165*e5436536SAndroid Build Coastguard Worker /*******************************************/
3166