xref: /aosp_15_r20/external/libxaac/decoder/drc_src/impd_drc_selection_process_drcset_selection.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1 /******************************************************************************
2  *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include <stdio.h>
21 #include <string.h>
22 #include <math.h>
23 #include "impd_type_def.h"
24 #include "impd_drc_extr_delta_coded_info.h"
25 #include "impd_drc_common.h"
26 #include "impd_drc_struct.h"
27 #include "impd_drc_interface.h"
28 #include "impd_drc_selection_process.h"
29 #include "impd_drc_sel_proc_drc_set_sel.h"
30 #include "impd_drc_loudness_control.h"
31 #include "impd_drc_filter_bank.h"
32 #include "impd_drc_rom.h"
33 
34 static const WORD32 effect_types_request_table[] = {
35     EFFECT_BIT_NIGHT,    EFFECT_BIT_NOISY,   EFFECT_BIT_LIMITED,
36     EFFECT_BIT_LOWLEVEL, EFFECT_BIT_DIALOG,  EFFECT_BIT_GENERAL_COMPR,
37     EFFECT_BIT_EXPAND,   EFFECT_BIT_ARTISTIC};
38 
impd_validate_requested_drc_feature(ia_drc_sel_proc_params_struct * pstr_drc_sel_proc_params_struct)39 WORD32 impd_validate_requested_drc_feature(
40     ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct) {
41   WORD32 i, j;
42 
43   for (i = 0; i < pstr_drc_sel_proc_params_struct->num_drc_feature_requests;
44        i++) {
45     switch (pstr_drc_sel_proc_params_struct->drc_feature_req_type[i]) {
46       case MATCH_EFFECT_TYPE:
47         for (j = 0; j < pstr_drc_sel_proc_params_struct
48                             ->desired_num_drc_effects_of_requested[i];
49              j++) {
50           if (pstr_drc_sel_proc_params_struct
51                   ->requested_drc_effect_type[i][j] ==
52               EFFECT_TYPE_REQUESTED_NONE) {
53             if (pstr_drc_sel_proc_params_struct
54                     ->desired_num_drc_effects_of_requested[i] > 1) {
55               return (UNEXPECTED_ERROR);
56             }
57           }
58         }
59         break;
60       case MATCH_DYNAMIC_RANGE:
61         break;
62       case MATCH_DRC_CHARACTERISTIC:
63         break;
64       default:
65         return (UNEXPECTED_ERROR);
66         break;
67     }
68   }
69   return (0);
70 }
71 
impd_find_drc_instructions_uni_drc(ia_drc_config * drc_config,WORD32 drc_set_id_requested,ia_drc_instructions_struct ** str_drc_instruction_str)72 WORD32 impd_find_drc_instructions_uni_drc(
73     ia_drc_config* drc_config, WORD32 drc_set_id_requested,
74     ia_drc_instructions_struct** str_drc_instruction_str) {
75   WORD32 i;
76   for (i = 0; i < drc_config->drc_instructions_uni_drc_count; i++) {
77     if (drc_set_id_requested ==
78         drc_config->str_drc_instruction_str[i].drc_set_id)
79       break;
80   }
81   if (i == drc_config->drc_instructions_uni_drc_count) {
82     return (UNEXPECTED_ERROR);
83   }
84   *str_drc_instruction_str = &drc_config->str_drc_instruction_str[i];
85   return (0);
86 }
87 
impd_map_requested_effect_bit_idx(WORD32 requested_effect_type,WORD32 * effect_bit_idx)88 WORD32 impd_map_requested_effect_bit_idx(WORD32 requested_effect_type,
89                                          WORD32* effect_bit_idx) {
90   switch (requested_effect_type) {
91     case EFFECT_TYPE_REQUESTED_NONE:
92       *effect_bit_idx = EFFECT_BIT_NONE;
93       break;
94     case EFFECT_TYPE_REQUESTED_NIGHT:
95       *effect_bit_idx = EFFECT_BIT_NIGHT;
96       break;
97     case EFFECT_TYPE_REQUESTED_NOISY:
98       *effect_bit_idx = EFFECT_BIT_NOISY;
99       break;
100     case EFFECT_TYPE_REQUESTED_LIMITED:
101       *effect_bit_idx = EFFECT_BIT_LIMITED;
102       break;
103     case EFFECT_TYPE_REQUESTED_LOWLEVEL:
104       *effect_bit_idx = EFFECT_BIT_LOWLEVEL;
105       break;
106     case EFFECT_TYPE_REQUESTED_DIALOG:
107       *effect_bit_idx = EFFECT_BIT_DIALOG;
108       break;
109     case EFFECT_TYPE_REQUESTED_GENERAL_COMPR:
110       *effect_bit_idx = EFFECT_BIT_GENERAL_COMPR;
111       break;
112     case EFFECT_TYPE_REQUESTED_EXPAND:
113       *effect_bit_idx = EFFECT_BIT_EXPAND;
114       break;
115     case EFFECT_TYPE_REQUESTED_ARTISTIC:
116       *effect_bit_idx = EFFECT_BIT_ARTISTIC;
117       break;
118 
119     default:
120       return (UNEXPECTED_ERROR);
121 
122       break;
123   }
124   return (0);
125 }
126 
impd_get_fading_drc_set(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc)127 WORD32 impd_get_fading_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
128   pstr_drc_uni_sel_proc->drc_instructions_index[2] = -1;
129   if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.album_mode == 0) {
130     WORD32 n;
131     ia_drc_instructions_struct* str_drc_instruction_str = NULL;
132     for (n = 0;
133          n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_uni_drc_count;
134          n++) {
135       str_drc_instruction_str =
136           &(pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]);
137 
138       if (str_drc_instruction_str->drc_set_effect & EFFECT_BIT_FADE) {
139         if (str_drc_instruction_str->downmix_id[0] == ID_FOR_ANY_DOWNMIX) {
140           pstr_drc_uni_sel_proc->drc_instructions_index[2] = n;
141 
142         } else {
143           return (UNEXPECTED_ERROR);
144         }
145       }
146     }
147   }
148   return (0);
149 }
150 
impd_get_ducking_drc_set(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc)151 WORD32 impd_get_ducking_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
152   WORD32 drc_instructions_index;
153   WORD32 n, k;
154   ia_drc_instructions_struct* str_drc_instruction_str;
155 
156   WORD32 requested_dwnmix_id =
157       pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.active_downmix_id;
158 
159   pstr_drc_uni_sel_proc->drc_instructions_index[3] = -1;
160   drc_instructions_index = -1;
161   str_drc_instruction_str = NULL;
162 
163   for (n = 0;
164        n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_uni_drc_count;
165        n++) {
166     str_drc_instruction_str =
167         &(pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]);
168 
169     if (str_drc_instruction_str->drc_set_effect &
170         (EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) {
171       for (k = 0; k < str_drc_instruction_str->dwnmix_id_count; k++) {
172         if (str_drc_instruction_str->downmix_id[k] == requested_dwnmix_id) {
173           drc_instructions_index = n;
174         }
175       }
176     }
177   }
178   if (drc_instructions_index == -1) {
179     for (n = 0;
180          n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_uni_drc_count;
181          n++) {
182       str_drc_instruction_str =
183           &(pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]);
184 
185       if (str_drc_instruction_str->drc_set_effect &
186           (EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) {
187         for (k = 0; k < str_drc_instruction_str->dwnmix_id_count; k++) {
188           if (str_drc_instruction_str->downmix_id[k] == ID_FOR_BASE_LAYOUT) {
189             drc_instructions_index = n;
190           }
191         }
192       }
193     }
194   }
195   if (drc_instructions_index > -1) {
196     pstr_drc_uni_sel_proc->drc_instructions_index[2] = -1;
197     pstr_drc_uni_sel_proc->drc_instructions_index[3] = drc_instructions_index;
198   }
199   return (0);
200 }
201 
impd_get_selected_drc_set(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc,WORD32 drc_set_id_selected)202 WORD32 impd_get_selected_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
203                                  WORD32 drc_set_id_selected) {
204   WORD32 n;
205 
206   for (n = 0; n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_count_plus;
207        n++) {
208     if (pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]
209             .drc_set_id == drc_set_id_selected)
210       break;
211   }
212   if (n == pstr_drc_uni_sel_proc->drc_config.drc_instructions_count_plus) {
213     return (EXTERNAL_ERROR);
214   }
215   pstr_drc_uni_sel_proc->drc_inst_index_sel = n;
216 
217   pstr_drc_uni_sel_proc->drc_instructions_index[0] =
218       pstr_drc_uni_sel_proc->drc_inst_index_sel;
219   return (0);
220 }
221 
impd_get_dependent_drc_set(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc)222 WORD32 impd_get_dependent_drc_set(
223     ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
224   ia_drc_instructions_struct* str_drc_instruction_str = NULL;
225   str_drc_instruction_str = &(
226       pstr_drc_uni_sel_proc->drc_config
227           .str_drc_instruction_str[pstr_drc_uni_sel_proc->drc_inst_index_sel]);
228 
229   if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
230     WORD32 n;
231     WORD32 drc_dependent_set_id = str_drc_instruction_str->depends_on_drc_set;
232 
233     for (n = 0;
234          n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_count_plus;
235          n++) {
236       if (pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]
237               .drc_set_id == drc_dependent_set_id)
238         break;
239     }
240     if (n == pstr_drc_uni_sel_proc->drc_config.drc_instructions_count_plus) {
241       return (UNEXPECTED_ERROR);
242     }
243     pstr_drc_uni_sel_proc->drc_instructions_index[1] = n;
244   } else {
245     pstr_drc_uni_sel_proc->drc_instructions_index[1] = -1;
246   }
247   return (0);
248 }
249 
impd_get_dependent_drc_instructions(const ia_drc_config * drc_config,const ia_drc_instructions_struct * str_drc_instruction_str,ia_drc_instructions_struct ** drc_instructions_dependent)250 WORD32 impd_get_dependent_drc_instructions(
251     const ia_drc_config* drc_config,
252     const ia_drc_instructions_struct* str_drc_instruction_str,
253     ia_drc_instructions_struct** drc_instructions_dependent) {
254   WORD32 j;
255   ia_drc_instructions_struct* dependent_drc = NULL;
256   for (j = 0; j < drc_config->drc_instructions_uni_drc_count; j++) {
257     dependent_drc =
258         (ia_drc_instructions_struct*)&(drc_config->str_drc_instruction_str[j]);
259     if (dependent_drc->drc_set_id ==
260         str_drc_instruction_str->depends_on_drc_set) {
261       break;
262     }
263   }
264   if (j == drc_config->drc_instructions_uni_drc_count) {
265     return (UNEXPECTED_ERROR);
266   }
267   if (dependent_drc->depends_on_drc_set_present == 1) {
268     return (UNEXPECTED_ERROR);
269   }
270   *drc_instructions_dependent = dependent_drc;
271   return (0);
272 }
273 
impd_select_drcs_without_compr_effects(ia_drc_config * pstr_drc_config,WORD32 * match_found_flag,WORD32 * selection_candidate_count,ia_selection_candidate_info_struct * selection_candidate_info)274 WORD32 impd_select_drcs_without_compr_effects(
275     ia_drc_config* pstr_drc_config, WORD32* match_found_flag,
276     WORD32* selection_candidate_count,
277     ia_selection_candidate_info_struct* selection_candidate_info) {
278   WORD32 i, k, n;
279   WORD32 selection_candidate_step_2_count = 0;
280   ia_selection_candidate_info_struct
281       selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
282   WORD32 effect_types_request_table_size;
283   WORD32 match;
284   ia_drc_instructions_struct* str_drc_instruction_str;
285 
286   effect_types_request_table_size =
287       sizeof(effect_types_request_table) / sizeof(WORD32);
288 
289   k = 0;
290   for (i = 0; i < *selection_candidate_count; i++) {
291     str_drc_instruction_str = &(
292         pstr_drc_config->str_drc_instruction_str[selection_candidate_info[i]
293                                                      .drc_instructions_index]);
294 
295     match = 1;
296     for (n = 0; n < effect_types_request_table_size; n++) {
297       if ((str_drc_instruction_str->drc_set_effect &
298            effect_types_request_table[n]) != 0x0) {
299         match = 0;
300       }
301     }
302     if (match == 1) {
303       if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
304       memcpy(&selection_candidate_info_step_2[k], &selection_candidate_info[i],
305              sizeof(ia_selection_candidate_info_struct));
306       k++;
307     }
308   }
309   selection_candidate_step_2_count = k;
310 
311   if (selection_candidate_step_2_count > 0) {
312     *match_found_flag = 1;
313     for (i = 0; i < selection_candidate_step_2_count; i++) {
314       memcpy(&selection_candidate_info[i], &selection_candidate_info_step_2[i],
315              sizeof(ia_selection_candidate_info_struct));
316       *selection_candidate_count = selection_candidate_step_2_count;
317     }
318   } else {
319     *match_found_flag = 0;
320   }
321 
322   return (0);
323 }
324 
impd_match_effect_type_attempt(ia_drc_config * pstr_drc_config,WORD32 requested_effect_type,WORD32 state_requested,WORD32 * match_found_flag,WORD32 * selection_candidate_count,ia_selection_candidate_info_struct * selection_candidate_info)325 WORD32 impd_match_effect_type_attempt(
326     ia_drc_config* pstr_drc_config, WORD32 requested_effect_type,
327     WORD32 state_requested, WORD32* match_found_flag,
328     WORD32* selection_candidate_count,
329     ia_selection_candidate_info_struct* selection_candidate_info) {
330   WORD32 i, k, err;
331   WORD32 selection_candidate_step_2_count = 0;
332   ia_selection_candidate_info_struct
333       selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
334   ia_drc_instructions_struct* str_drc_instruction_str;
335   ia_drc_instructions_struct* drc_instructions_dependent;
336   WORD32 effect_bit_idx;
337 
338   err =
339       impd_map_requested_effect_bit_idx(requested_effect_type, &effect_bit_idx);
340   if (err) return (err);
341 
342   if (effect_bit_idx == EFFECT_BIT_NONE) {
343     err = impd_select_drcs_without_compr_effects(
344         pstr_drc_config, match_found_flag, selection_candidate_count,
345         selection_candidate_info);
346     if (err) return (err);
347   } else {
348     k = 0;
349     for (i = 0; i < *selection_candidate_count; i++) {
350       str_drc_instruction_str =
351           &(pstr_drc_config->str_drc_instruction_str
352                 [selection_candidate_info[i].drc_instructions_index]);
353       if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
354         err = impd_get_dependent_drc_instructions(pstr_drc_config,
355                                                   str_drc_instruction_str,
356                                                   &drc_instructions_dependent);
357         if (err) return (err);
358 
359         if (state_requested == 1) {
360           if (((str_drc_instruction_str->drc_set_effect & effect_bit_idx) !=
361                0x0) ||
362               ((drc_instructions_dependent->drc_set_effect & effect_bit_idx) !=
363                0x0)) {
364             if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
365             memcpy(&selection_candidate_info_step_2[k],
366                    &selection_candidate_info[i],
367                    sizeof(ia_selection_candidate_info_struct));
368             k++;
369           }
370         } else {
371           if (((str_drc_instruction_str->drc_set_effect & effect_bit_idx) ==
372                0x0) &&
373               ((drc_instructions_dependent->drc_set_effect & effect_bit_idx) ==
374                0x0)) {
375             if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
376             memcpy(&selection_candidate_info_step_2[k],
377                    &selection_candidate_info[i],
378                    sizeof(ia_selection_candidate_info_struct));
379             k++;
380           }
381         }
382       } else {
383         if (state_requested == 1) {
384           if ((str_drc_instruction_str->drc_set_effect & effect_bit_idx) !=
385               0x0) {
386             if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
387             memcpy(&selection_candidate_info_step_2[k],
388                    &selection_candidate_info[i],
389                    sizeof(ia_selection_candidate_info_struct));
390             k++;
391           }
392         } else {
393           if ((str_drc_instruction_str->drc_set_effect & effect_bit_idx) ==
394               0x0) {
395             if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
396             memcpy(&selection_candidate_info_step_2[k],
397                    &selection_candidate_info[i],
398                    sizeof(ia_selection_candidate_info_struct));
399             k++;
400           }
401         }
402       }
403     }
404     selection_candidate_step_2_count = k;
405 
406     if (selection_candidate_step_2_count > 0) {
407       *match_found_flag = 1;
408       for (i = 0; i < selection_candidate_step_2_count; i++) {
409         *selection_candidate_count = selection_candidate_step_2_count;
410         memcpy(&selection_candidate_info[i],
411                &selection_candidate_info_step_2[i],
412                sizeof(ia_selection_candidate_info_struct));
413       }
414     } else {
415       *match_found_flag = 0;
416     }
417   }
418   return (0);
419 }
420 
impd_match_effect_types(ia_drc_config * pstr_drc_config,WORD32 effect_type_requested_total_count,WORD32 effect_type_requested_desired_count,WORD32 * requested_effect_type,WORD32 * selection_candidate_count,ia_selection_candidate_info_struct * selection_candidate_info)421 WORD32 impd_match_effect_types(
422     ia_drc_config* pstr_drc_config, WORD32 effect_type_requested_total_count,
423     WORD32 effect_type_requested_desired_count, WORD32* requested_effect_type,
424     WORD32* selection_candidate_count,
425     ia_selection_candidate_info_struct* selection_candidate_info) {
426   WORD32 k, err;
427   WORD32 match_found_flag = 0;
428   WORD32 state_requested;
429   WORD32 desired_effect_type_found;
430 
431   desired_effect_type_found = 0;
432   k = 0;
433   while (k < effect_type_requested_desired_count) {
434     state_requested = 1;
435     err = impd_match_effect_type_attempt(
436         pstr_drc_config, requested_effect_type[k], state_requested,
437         &match_found_flag, selection_candidate_count, selection_candidate_info);
438     if (err) return (err);
439     if (match_found_flag) desired_effect_type_found = 1;
440     k++;
441   }
442   if (desired_effect_type_found == 0) {
443     while ((k < effect_type_requested_total_count) && (match_found_flag == 0)) {
444       state_requested = 1;
445       err = impd_match_effect_type_attempt(
446           pstr_drc_config, requested_effect_type[k], state_requested,
447           &match_found_flag, selection_candidate_count,
448           selection_candidate_info);
449       if (err) return (err);
450       k++;
451     }
452   }
453 
454   return (0);
455 }
456 
impd_match_dynamic_range(ia_drc_config * pstr_drc_config,ia_drc_loudness_info_set_struct * pstr_loudness_info,ia_drc_sel_proc_params_struct * pstr_drc_sel_proc_params_struct,WORD32 num_drc_requests,WORD32 * selection_candidate_count,ia_selection_candidate_info_struct * selection_candidate_info)457 WORD32 impd_match_dynamic_range(
458     ia_drc_config* pstr_drc_config,
459     ia_drc_loudness_info_set_struct* pstr_loudness_info,
460     ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
461     WORD32 num_drc_requests, WORD32* selection_candidate_count,
462     ia_selection_candidate_info_struct* selection_candidate_info) {
463   ia_drc_instructions_struct* str_drc_instruction_str;
464   WORD32 err, i, k;
465   WORD32 lp_avg_present_val;
466   FLOAT32 lp_avg_val;
467   FLOAT32 deviation_min = 1000.0f;
468   WORD32 selected[DRC_INSTRUCTIONS_COUNT_MAX];
469   WORD32 dynamic_range_measurement_type =
470       pstr_drc_sel_proc_params_struct
471           ->requested_dyn_range_measur_type[num_drc_requests];
472 
473   WORD32 requested_dyn_range_range_flag =
474       pstr_drc_sel_proc_params_struct
475           ->requested_dyn_range_range_flag[num_drc_requests];
476 
477   FLOAT32 dynamic_range_requested =
478       pstr_drc_sel_proc_params_struct
479           ->requested_dyn_range_value[num_drc_requests];
480 
481   FLOAT32 dynamic_range_min_requested =
482       pstr_drc_sel_proc_params_struct
483           ->requested_dyn_range_min_val[num_drc_requests];
484 
485   FLOAT32 dynamic_range_max_requested =
486       pstr_drc_sel_proc_params_struct
487           ->requested_dyn_range_max_val[num_drc_requests];
488 
489   WORD32* requested_dwnmix_id =
490       pstr_drc_sel_proc_params_struct->requested_dwnmix_id;
491 
492   WORD32 album_mode = pstr_drc_sel_proc_params_struct->album_mode;
493 
494   k = 0;
495   for (i = 0; i < *selection_candidate_count; i++) {
496     str_drc_instruction_str = &(
497         pstr_drc_config->str_drc_instruction_str[selection_candidate_info[i]
498                                                      .drc_instructions_index]);
499 
500     err = impd_loudness_peak_to_average_info(
501         pstr_loudness_info, str_drc_instruction_str,
502         requested_dwnmix_id[selection_candidate_info[i]
503                                 .downmix_id_request_index],
504         dynamic_range_measurement_type, album_mode, &lp_avg_present_val,
505         &lp_avg_val);
506     if (err) return (err);
507 
508     if (lp_avg_present_val == 1) {
509       if (requested_dyn_range_range_flag == 1) {
510         if ((lp_avg_val >= dynamic_range_min_requested) &&
511             (lp_avg_val <= dynamic_range_max_requested)) {
512           if (k >= DRC_INSTRUCTIONS_COUNT_MAX) return UNEXPECTED_ERROR;
513           selected[k] = i;
514           k++;
515         }
516       } else {
517         FLOAT32 deviation =
518             (FLOAT32)fabs((FLOAT64)(dynamic_range_requested - lp_avg_val));
519         if (deviation_min >= deviation) {
520           if (deviation_min > deviation) {
521             deviation_min = deviation;
522             k = 0;
523           }
524           if (k >= DRC_INSTRUCTIONS_COUNT_MAX) return UNEXPECTED_ERROR;
525           selected[k] = i;
526           k++;
527         }
528       }
529     }
530   }
531   if (k > 0) {
532     for (i = 0; i < k; i++) {
533       memcpy(&selection_candidate_info[i],
534              &selection_candidate_info[selected[i]],
535              sizeof(ia_selection_candidate_info_struct));
536     }
537     *selection_candidate_count = k;
538   }
539 
540   return (0);
541 }
542 
impd_match_drc_characteristic_attempt(ia_drc_config * pstr_drc_config,WORD32 requested_drc_characteristic,WORD32 * match_found_flag,WORD32 * selection_candidate_count,ia_selection_candidate_info_struct * selection_candidate_info)543 WORD32 impd_match_drc_characteristic_attempt(
544     ia_drc_config* pstr_drc_config, WORD32 requested_drc_characteristic,
545     WORD32* match_found_flag, WORD32* selection_candidate_count,
546     ia_selection_candidate_info_struct* selection_candidate_info) {
547   WORD32 i, k, n, b, m;
548   WORD32 ref_count;
549   WORD32 drc_characteristic;
550   FLOAT32 match_count;
551   WORD32 drc_characteristic_request_1;
552   WORD32 drc_characteristic_request_2;
553   WORD32 drc_characteristic_request_3;
554 
555   ia_drc_instructions_struct* str_drc_instruction_str = NULL;
556   ia_uni_drc_coeffs_struct* str_p_loc_drc_coefficients_uni_drc = NULL;
557   ia_gain_set_params_struct* gain_set_params = NULL;
558   *match_found_flag = 0;
559 
560   if (requested_drc_characteristic < 1) {
561     return (UNEXPECTED_ERROR);
562   }
563   if (requested_drc_characteristic < 12) {
564     drc_characteristic_request_1 =
565         drc_characteristic_order_default[requested_drc_characteristic - 1][0];
566     drc_characteristic_request_2 =
567         drc_characteristic_order_default[requested_drc_characteristic - 1][1];
568     drc_characteristic_request_3 =
569         drc_characteristic_order_default[requested_drc_characteristic - 1][2];
570   } else {
571     drc_characteristic_request_1 = requested_drc_characteristic;
572     drc_characteristic_request_2 = -1;
573     drc_characteristic_request_3 = -1;
574   }
575 
576   if (pstr_drc_config->drc_coefficients_drc_count) {
577     for (i = 0; i < pstr_drc_config->drc_coefficients_drc_count; i++) {
578       str_p_loc_drc_coefficients_uni_drc =
579           &(pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[i]);
580       if (str_p_loc_drc_coefficients_uni_drc->drc_location == LOCATION_SELECTED)
581         break;
582     }
583 
584     if (i == pstr_drc_config->drc_coefficients_drc_count) {
585       return (UNEXPECTED_ERROR);
586     }
587   }
588 
589   n = 0;
590   for (i = 0; i < *selection_candidate_count; i++) {
591     ref_count = 0;
592     match_count = 0;
593 
594     str_drc_instruction_str = &(
595         pstr_drc_config->str_drc_instruction_str[selection_candidate_info[i]
596                                                      .drc_instructions_index]);
597     for (k = 0; k < str_drc_instruction_str->num_drc_ch_groups; k++) {
598       gain_set_params =
599           &(str_p_loc_drc_coefficients_uni_drc->gain_set_params
600                 [str_drc_instruction_str->gain_set_index_for_channel_group[k]]);
601       for (b = 0; b < gain_set_params->band_count; b++) {
602         ref_count++;
603         drc_characteristic = gain_set_params->gain_params[b].drc_characteristic;
604         if (drc_characteristic == drc_characteristic_request_1)
605           match_count += 1.0f;
606         else if (drc_characteristic == drc_characteristic_request_2)
607           match_count += 0.75f;
608         else if (drc_characteristic == drc_characteristic_request_3)
609           match_count += 0.5f;
610       }
611     }
612     if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
613       WORD32 depends_on_drc_set = str_drc_instruction_str->depends_on_drc_set;
614       for (m = 0; m < pstr_drc_config->drc_instructions_uni_drc_count; m++) {
615         if (pstr_drc_config->str_drc_instruction_str[m].drc_set_id ==
616             depends_on_drc_set)
617           break;
618       }
619       if (m == pstr_drc_config->drc_instructions_uni_drc_count) {
620         return (UNEXPECTED_ERROR);
621       }
622       str_drc_instruction_str = &(pstr_drc_config->str_drc_instruction_str[m]);
623       if ((str_drc_instruction_str->drc_set_effect &
624            (EFFECT_BIT_FADE | EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) ==
625           0) {
626         if (str_drc_instruction_str->drc_set_effect != EFFECT_BIT_CLIPPING) {
627           for (k = 0; k < str_drc_instruction_str->num_drc_ch_groups; k++) {
628             gain_set_params =
629                 &(str_p_loc_drc_coefficients_uni_drc->gain_set_params
630                       [str_drc_instruction_str
631                            ->gain_set_index_for_channel_group[k]]);
632             for (b = 0; b < gain_set_params->band_count; b++) {
633               ref_count++;
634               drc_characteristic =
635                   gain_set_params->gain_params[b].drc_characteristic;
636               if (drc_characteristic == drc_characteristic_request_1)
637                 match_count += 1.0f;
638               else if (drc_characteristic == drc_characteristic_request_2)
639                 match_count += 0.75f;
640               else if (drc_characteristic == drc_characteristic_request_3)
641                 match_count += 0.5;
642             }
643           }
644         }
645       }
646     }
647     if ((ref_count > 0) && (((FLOAT32)match_count) > 0.5f * ref_count)) {
648       if (n >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
649       memcpy(&selection_candidate_info[n], &selection_candidate_info[i],
650              sizeof(ia_selection_candidate_info_struct));
651       n++;
652     }
653   }
654   if (n > 0) {
655     *selection_candidate_count = n;
656     *match_found_flag = 1;
657   }
658 
659   return (0);
660 }
661 
impd_match_drc_characteristic(ia_drc_config * pstr_drc_config,WORD32 requested_drc_characteristic,WORD32 * selection_candidate_count,ia_selection_candidate_info_struct * selection_candidate_info)662 WORD32 impd_match_drc_characteristic(
663     ia_drc_config* pstr_drc_config, WORD32 requested_drc_characteristic,
664     WORD32* selection_candidate_count,
665     ia_selection_candidate_info_struct* selection_candidate_info) {
666   WORD32 k, err;
667   WORD32 match_found_flag = 0;
668 
669   const WORD32* drc_characteristic_order =
670       drc_characteristic_order_default[requested_drc_characteristic - 1];
671   const WORD32 drc_characteristic_order_count =
672       sizeof(drc_characteristic_order_default[requested_drc_characteristic]) /
673       sizeof(WORD32);
674   k = 0;
675   while ((k < drc_characteristic_order_count) && (match_found_flag == 0) &&
676          (drc_characteristic_order[k] > 0)) {
677     err = impd_match_drc_characteristic_attempt(
678         pstr_drc_config, drc_characteristic_order[k], &match_found_flag,
679         selection_candidate_count, selection_candidate_info);
680     if (err) return (err);
681     k++;
682   }
683   return (0);
684 }
685 
impd_drc_set_preselection(ia_drc_sel_proc_params_struct * pstr_drc_sel_proc_params_struct,ia_drc_config * pstr_drc_config,ia_drc_loudness_info_set_struct * pstr_loudness_info,WORD32 restrict_to_drc_with_album_loudness,ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc,WORD32 * selection_candidate_count,ia_selection_candidate_info_struct * selection_candidate_info)686 WORD32 impd_drc_set_preselection(
687     ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
688     ia_drc_config* pstr_drc_config,
689     ia_drc_loudness_info_set_struct* pstr_loudness_info,
690     WORD32 restrict_to_drc_with_album_loudness,
691     ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
692     WORD32* selection_candidate_count,
693     ia_selection_candidate_info_struct* selection_candidate_info) {
694   WORD32 i, j, k, l, d, n, err;
695   WORD32 downmix_id_match = 0;
696 
697   WORD32 selection_candidate_step_2_count;
698   ia_selection_candidate_info_struct
699       selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
700 
701   WORD32 num_downmix_id_requests =
702       pstr_drc_sel_proc_params_struct->num_downmix_id_requests;
703   WORD32* requested_dwnmix_id =
704       pstr_drc_sel_proc_params_struct->requested_dwnmix_id;
705   FLOAT32 output_peak_level_max =
706       pstr_drc_sel_proc_params_struct->output_peak_level_max;
707   WORD32 loudness_deviation_max =
708       pstr_drc_sel_proc_params_struct->loudness_deviation_max;
709   WORD32* drc_set_id_valid_flag = pstr_drc_uni_sel_proc->drc_set_id_valid_flag;
710   WORD32* eq_set_id_valid_flag = pstr_drc_uni_sel_proc->eq_set_id_valid_flag;
711 
712   FLOAT32 output_peak_level_min = 1000.0f;
713   FLOAT32 adjustment;
714   WORD32 loudness_drc_set_id_requested;
715 
716   WORD32 num_compression_eq_count = 0;
717   WORD32 num_compression_eq_id[16];
718 
719   WORD32 loudness_info_count = 0;
720   WORD32 eq_set_id_loudness[16];
721   FLOAT32 loudness_normalization_gain_db[16];
722   FLOAT32 loudness[16];
723   WORD32 peak_info_count;
724   WORD32 eq_set_id_Peak[16];
725   FLOAT32 signal_peak_level[16];
726   WORD32 explicit_peak_information_present[16] = { 0 };
727 
728   ia_uni_drc_coeffs_struct* str_p_loc_drc_coefficients_uni_drc = NULL;
729   ia_drc_instructions_struct* str_drc_instruction_str = NULL;
730 
731   impd_select_drc_coeff3(pstr_drc_config, &str_p_loc_drc_coefficients_uni_drc);
732   if (str_p_loc_drc_coefficients_uni_drc == NULL) return UNEXPECTED_ERROR;
733   k = 0;
734   for (d = 0; d < num_downmix_id_requests; d++) {
735     err = impd_find_eq_set_no_compression(
736         pstr_drc_config, requested_dwnmix_id[d], &num_compression_eq_count,
737         num_compression_eq_id);
738     if (err) return (err);
739     for (i = 0; i < pstr_drc_config->drc_instructions_count_plus; i++) {
740       downmix_id_match = 0;
741       str_drc_instruction_str = &(pstr_drc_config->str_drc_instruction_str[i]);
742 
743       for (j = 0; j < str_drc_instruction_str->dwnmix_id_count; j++) {
744         if ((str_drc_instruction_str->downmix_id[j] ==
745              requested_dwnmix_id[d]) ||
746             ((str_drc_instruction_str->downmix_id[j] == ID_FOR_BASE_LAYOUT) &&
747              (str_drc_instruction_str->drc_set_id > 0)) ||
748             (str_drc_instruction_str->downmix_id[j] == ID_FOR_ANY_DOWNMIX)) {
749           downmix_id_match = 1;
750         }
751       }
752       if (downmix_id_match == 1) {
753         if (pstr_drc_sel_proc_params_struct->dynamic_range_control_on == 1) {
754           if ((str_drc_instruction_str->drc_set_effect != EFFECT_BIT_FADE) &&
755               (str_drc_instruction_str->drc_set_effect !=
756                EFFECT_BIT_DUCK_OTHER) &&
757               (str_drc_instruction_str->drc_set_effect !=
758                EFFECT_BIT_DUCK_SELF) &&
759               (str_drc_instruction_str->drc_set_effect != 0 ||
760                str_drc_instruction_str->drc_set_id < 0) &&
761               (((str_drc_instruction_str->depends_on_drc_set_present == 0) &&
762                 (str_drc_instruction_str->no_independent_use == 0)) ||
763                (str_drc_instruction_str->depends_on_drc_set_present == 1))) {
764             WORD32 drc_is_permitted = 1;
765             if (str_drc_instruction_str->drc_set_id > 0) {
766               drc_is_permitted =
767                   drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id];
768             }
769             if (drc_is_permitted == 1) {
770               err = impd_init_loudness_control(
771                   pstr_drc_sel_proc_params_struct, pstr_loudness_info,
772                   requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
773 
774                   num_compression_eq_count, num_compression_eq_id,
775                   &loudness_info_count, eq_set_id_loudness,
776                   loudness_normalization_gain_db, loudness);
777               if (err) return (err);
778 
779               if (loudness_info_count > MAX_LOUDNESS_INFO_COUNT)
780                 return UNEXPECTED_ERROR;
781 
782               impd_signal_peak_level_info(
783                   pstr_drc_config, pstr_loudness_info, str_drc_instruction_str,
784                   requested_dwnmix_id[d],
785                   pstr_drc_sel_proc_params_struct->album_mode,
786                   num_compression_eq_count, num_compression_eq_id,
787                   &peak_info_count, eq_set_id_Peak, signal_peak_level,
788                   explicit_peak_information_present);
789 
790               for (l = 0; l < loudness_info_count; l++) {
791                 WORD32 match_found_flag = 0;
792                 WORD32 p;
793                 if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
794                 selection_candidate_info[k].loudness_norm_db_gain_adjusted =
795                     loudness_normalization_gain_db[l];
796 
797                 selection_candidate_info[k]
798                     .loudness_norm_db_gain_adjusted = min(
799                     selection_candidate_info[k].loudness_norm_db_gain_adjusted,
800                     pstr_drc_sel_proc_params_struct->loudness_norm_gain_db_max);
801 
802                 if (loudness[l] != UNDEFINED_LOUDNESS_VALUE) {
803                   selection_candidate_info[k].output_loudness =
804                       loudness[l] +
805                       selection_candidate_info[k]
806                           .loudness_norm_db_gain_adjusted;
807                 } else {
808                   selection_candidate_info[k].output_loudness =
809                       UNDEFINED_LOUDNESS_VALUE;
810                 }
811 
812                 for (p = 0; p < peak_info_count; p++) {
813                   if (eq_set_id_Peak[p] == eq_set_id_loudness[l]) {
814                     if (eq_set_id_valid_flag[eq_set_id_Peak[p]] == 1)
815 
816                     {
817                       match_found_flag = 1;
818                       break;
819                     }
820                   }
821                 }
822                 if (match_found_flag == 1) {
823                   selection_candidate_info[k].output_peak_level =
824                       signal_peak_level[p] +
825                       selection_candidate_info[k]
826                           .loudness_norm_db_gain_adjusted;
827                 } else {
828                   selection_candidate_info[k].output_peak_level =
829                       selection_candidate_info[k]
830                           .loudness_norm_db_gain_adjusted;
831                 }
832                 if ((str_drc_instruction_str->requires_eq == 1) &&
833                     (eq_set_id_valid_flag[eq_set_id_loudness[l]] == 0))
834                   continue;
835                 selection_candidate_info[k].drc_instructions_index = i;
836                 selection_candidate_info[k].downmix_id_request_index = d;
837                 selection_candidate_info[k].eq_set_id = eq_set_id_loudness[l];
838                 if (explicit_peak_information_present[p] == 1) {
839                   selection_candidate_info[k].selection_flags =
840                       SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT;
841                 } else {
842                   selection_candidate_info[k].selection_flags = 0;
843                 }
844                 impd_mixing_level_info(
845                     pstr_drc_sel_proc_params_struct, pstr_loudness_info,
846                     requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
847                     eq_set_id_loudness[l],
848                     &selection_candidate_info[k].mixing_level);
849                 if (str_drc_instruction_str->drc_set_target_loudness_present &&
850                     ((pstr_drc_sel_proc_params_struct
851                           ->loudness_normalization_on &&
852                       str_drc_instruction_str
853                               ->drc_set_target_loudness_value_upper >=
854                           pstr_drc_sel_proc_params_struct->target_loudness &&
855                       str_drc_instruction_str
856                               ->drc_set_target_loudness_value_lower <
857                           pstr_drc_sel_proc_params_struct->target_loudness) ||
858                      !pstr_drc_sel_proc_params_struct
859                           ->loudness_normalization_on)) {
860                   selection_candidate_info[k].selection_flags |=
861                       SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH;
862                   if (!explicit_peak_information_present[p]) {
863                     if (pstr_drc_sel_proc_params_struct
864                             ->loudness_normalization_on) {
865                       selection_candidate_info[k].output_peak_level =
866                           pstr_drc_sel_proc_params_struct->target_loudness -
867                           str_drc_instruction_str
868                               ->drc_set_target_loudness_value_upper;
869                     } else {
870                       selection_candidate_info[k].output_peak_level = 0.0f;
871                     }
872                   }
873                 }
874                 if ((selection_candidate_info[k].selection_flags &
875                          (SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH |
876                           SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT) ||
877                      !str_drc_instruction_str
878                           ->drc_set_target_loudness_present)) {
879                   k++;
880                 }
881               }
882             }
883           }
884         } else {
885           if (str_drc_instruction_str->drc_set_id < 0) {
886             err = impd_init_loudness_control(
887                 pstr_drc_sel_proc_params_struct, pstr_loudness_info,
888                 requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
889                 num_compression_eq_count, num_compression_eq_id,
890                 &loudness_info_count, eq_set_id_loudness,
891                 loudness_normalization_gain_db, loudness);
892             if (err) return (err);
893 
894             impd_signal_peak_level_info(
895                 pstr_drc_config, pstr_loudness_info, str_drc_instruction_str,
896                 requested_dwnmix_id[d],
897                 pstr_drc_sel_proc_params_struct->album_mode,
898                 num_compression_eq_count, num_compression_eq_id,
899                 &peak_info_count, eq_set_id_Peak, signal_peak_level,
900                 explicit_peak_information_present);
901             for (l = 0; l < loudness_info_count; l++) {
902               WORD32 match_found_flag = 0;
903               WORD32 p;
904               if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
905               for (p = 0; p < peak_info_count; p++) {
906                 if (eq_set_id_Peak[p] == eq_set_id_loudness[l]) {
907                   if (eq_set_id_valid_flag[eq_set_id_Peak[p]] == 1) {
908                     match_found_flag = 1;
909                     break;
910                   }
911                 }
912               }
913               if (match_found_flag == 1) {
914                 adjustment = max(
915                     0.0f,
916                     signal_peak_level[p] + loudness_normalization_gain_db[l] -
917                         pstr_drc_sel_proc_params_struct->output_peak_level_max);
918                 adjustment = min(adjustment, max(0.0f, loudness_deviation_max));
919                 selection_candidate_info[k].loudness_norm_db_gain_adjusted =
920                     loudness_normalization_gain_db[l] - adjustment;
921 
922                 selection_candidate_info[k]
923                     .loudness_norm_db_gain_adjusted = min(
924                     selection_candidate_info[k].loudness_norm_db_gain_adjusted,
925                     pstr_drc_sel_proc_params_struct->loudness_norm_gain_db_max);
926 
927                 selection_candidate_info[k].output_peak_level =
928                     signal_peak_level[p] +
929                     selection_candidate_info[k].loudness_norm_db_gain_adjusted;
930                 if (loudness[l] != UNDEFINED_LOUDNESS_VALUE) {
931                   selection_candidate_info[k].output_loudness =
932                       loudness[l] +
933                       selection_candidate_info[k]
934                           .loudness_norm_db_gain_adjusted;
935                 } else {
936                   selection_candidate_info[k].output_loudness =
937                       UNDEFINED_LOUDNESS_VALUE;
938                 }
939                 selection_candidate_info[k].drc_instructions_index = i;
940                 selection_candidate_info[k].downmix_id_request_index = d;
941                 selection_candidate_info[k].eq_set_id = eq_set_id_loudness[l];
942                 if (explicit_peak_information_present[p] == 1) {
943                   selection_candidate_info[k].selection_flags =
944                       SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT;
945                 } else {
946                   selection_candidate_info[k].selection_flags = 0;
947                 }
948                 impd_mixing_level_info(
949                     pstr_drc_sel_proc_params_struct, pstr_loudness_info,
950                     requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
951                     eq_set_id_loudness[l],
952                     &selection_candidate_info[k].mixing_level);
953                 k++;
954               }
955             }
956           }
957         }
958       }
959     }
960   }
961   if (k > SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
962   *selection_candidate_count = k;
963   if (pstr_drc_sel_proc_params_struct->dynamic_range_control_on == 1) {
964     n = 0;
965     for (k = 0; k < *selection_candidate_count; k++) {
966       str_drc_instruction_str =
967           &(pstr_drc_config->str_drc_instruction_str
968                 [selection_candidate_info[k].drc_instructions_index]);
969 
970       if (pstr_drc_sel_proc_params_struct->eq_set_purpose_request !=
971           EQ_PURPOSE_EQ_OFF) {
972         WORD32 matching_eq_set_count = 0;
973         WORD32 matching_eq_instrucions_index[64];
974         err = impd_match_eq_set(
975             pstr_drc_config, requested_dwnmix_id[selection_candidate_info[k]
976                                                      .downmix_id_request_index],
977             str_drc_instruction_str->drc_set_id, eq_set_id_valid_flag,
978             &matching_eq_set_count, matching_eq_instrucions_index);
979         if (err) return (err);
980         for (j = 0; j < matching_eq_set_count; j++) {
981           if (n >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
982           memcpy(&selection_candidate_info_step_2[n],
983                  &selection_candidate_info[k],
984                  sizeof(ia_selection_candidate_info_struct));
985           selection_candidate_info_step_2[n].eq_set_id =
986               pstr_drc_config->str_drc_config_ext
987                   .str_eq_instructions[matching_eq_instrucions_index[j]]
988                   .eq_set_id;
989           n++;
990         }
991       }
992       if (str_drc_instruction_str->requires_eq == 0) {
993         if (n >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
994         memcpy(&selection_candidate_info_step_2[n],
995                &selection_candidate_info[k],
996                sizeof(ia_selection_candidate_info_struct));
997         selection_candidate_info_step_2[n].eq_set_id = 0;
998         n++;
999       }
1000     }
1001     if (n > SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
1002     memcpy(selection_candidate_info, selection_candidate_info_step_2,
1003            n * sizeof(ia_selection_candidate_info_struct));
1004     *selection_candidate_count = n;
1005     n = 0;
1006     for (k = 0; k < *selection_candidate_count; k++) {
1007       if ((selection_candidate_info[k].selection_flags &
1008            SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH) &&
1009           !(selection_candidate_info[k].selection_flags &
1010             SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT)) {
1011         memcpy(&selection_candidate_info_step_2[n],
1012                &selection_candidate_info[k],
1013                sizeof(ia_selection_candidate_info_struct));
1014         n++;
1015       } else {
1016         if (selection_candidate_info[k].output_peak_level <=
1017             output_peak_level_max) {
1018           memcpy(&selection_candidate_info_step_2[n],
1019                  &selection_candidate_info[k],
1020                  sizeof(ia_selection_candidate_info_struct));
1021           n++;
1022         }
1023         if (selection_candidate_info[k].output_peak_level <
1024             output_peak_level_min) {
1025           output_peak_level_min = selection_candidate_info[k].output_peak_level;
1026         }
1027       }
1028     }
1029     selection_candidate_step_2_count = n;
1030     if (selection_candidate_step_2_count == 0) {
1031       n = 0;
1032       for (k = 0; k < *selection_candidate_count; k++) {
1033         if ((selection_candidate_info[k].selection_flags &
1034              SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH) &&
1035             (selection_candidate_info[k].selection_flags &
1036              SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT)) {
1037           memcpy(&selection_candidate_info_step_2[n],
1038                  &selection_candidate_info[k],
1039                  sizeof(ia_selection_candidate_info_struct));
1040           n++;
1041         }
1042       }
1043       selection_candidate_step_2_count = n;
1044     }
1045     if (selection_candidate_step_2_count == 0) {
1046       n = 0;
1047       for (k = 0; k < *selection_candidate_count; k++) {
1048         if (selection_candidate_info_step_2[k].output_peak_level <
1049             output_peak_level_min + 1.0f) {
1050           memcpy(&selection_candidate_info_step_2[n],
1051                  &selection_candidate_info[k],
1052                  sizeof(ia_selection_candidate_info_struct));
1053           adjustment =
1054               max(0.0f, selection_candidate_info_step_2[n].output_peak_level -
1055                             output_peak_level_max);
1056           adjustment = min(adjustment, max(0.0f, loudness_deviation_max));
1057           selection_candidate_info_step_2[n].loudness_norm_db_gain_adjusted -=
1058               adjustment;
1059           selection_candidate_info_step_2[n].output_peak_level -= adjustment;
1060           selection_candidate_info_step_2[n].output_loudness -= adjustment;
1061           n++;
1062         }
1063       }
1064       selection_candidate_step_2_count = n;
1065     }
1066 
1067     for (n = 0; n < selection_candidate_step_2_count; n++) {
1068       memcpy(&selection_candidate_info[n], &selection_candidate_info_step_2[n],
1069              sizeof(ia_selection_candidate_info_struct));
1070     }
1071     *selection_candidate_count = selection_candidate_step_2_count;
1072   }
1073 
1074   if (restrict_to_drc_with_album_loudness == 1) {
1075     j = 0;
1076     for (k = 0; k < *selection_candidate_count; k++) {
1077       loudness_drc_set_id_requested =
1078           max(0, pstr_drc_config
1079                      ->str_drc_instruction_str[selection_candidate_info[k]
1080                                                    .drc_instructions_index]
1081                      .drc_set_id);
1082       for (n = 0; n < pstr_loudness_info->loudness_info_album_count; n++) {
1083         if (loudness_drc_set_id_requested ==
1084             pstr_loudness_info->str_loudness_info_album[n].drc_set_id) {
1085           if (j >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
1086           memcpy(&selection_candidate_info[j], &selection_candidate_info[k],
1087                  sizeof(ia_selection_candidate_info_struct));
1088           j++;
1089           break;
1090         }
1091       }
1092     }
1093     *selection_candidate_count = j;
1094   }
1095   return (0);
1096 }
1097 
impd_drc_set_final_selection(ia_drc_config * pstr_drc_config,ia_drc_sel_proc_params_struct * pstr_drc_sel_proc_params_struct,WORD32 * selection_candidate_count,ia_selection_candidate_info_struct * selection_candidate_info,WORD32 * eq_set_id_valid_flag)1098 WORD32 impd_drc_set_final_selection(
1099     ia_drc_config* pstr_drc_config,
1100     ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
1101     WORD32* selection_candidate_count,
1102     ia_selection_candidate_info_struct* selection_candidate_info,
1103     WORD32* eq_set_id_valid_flag) {
1104   WORD32 k, i, n, err;
1105   WORD32 selection_candidate_step_2_count;
1106   ia_selection_candidate_info_struct
1107       selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
1108   WORD32 drc_set_id_max;
1109   FLOAT32 output_level_max;
1110   FLOAT32 output_level_min;
1111   WORD32 effect_count, effect_count_min;
1112   WORD32 effect_types_request_table_size;
1113   WORD32 drc_set_target_loudness_val_upper_min;
1114   ia_drc_instructions_struct* str_drc_instruction_str;
1115   ia_drc_instructions_struct* drc_instructions_dependent;
1116 
1117   if (pstr_drc_sel_proc_params_struct->eq_set_purpose_request > 0) {
1118     WORD32 eq_purpose_requested =
1119         pstr_drc_sel_proc_params_struct->eq_set_purpose_request;
1120 
1121     err = impd_match_eq_set_purpose(
1122         pstr_drc_config, eq_purpose_requested, eq_set_id_valid_flag,
1123         selection_candidate_count, selection_candidate_info,
1124         selection_candidate_info_step_2);
1125     if (err) return (err);
1126   }
1127 
1128   output_level_min = 10000.0f;
1129   k = 0;
1130   for (i = 0; i < *selection_candidate_count; i++) {
1131     if (output_level_min >= selection_candidate_info[i].output_peak_level) {
1132       if (output_level_min > selection_candidate_info[i].output_peak_level) {
1133         output_level_min = selection_candidate_info[i].output_peak_level;
1134         k = 0;
1135       }
1136       memcpy(&selection_candidate_info_step_2[k], &selection_candidate_info[i],
1137              sizeof(ia_selection_candidate_info_struct));
1138       k++;
1139     }
1140   }
1141   selection_candidate_step_2_count = k;
1142 
1143   if (output_level_min <= 0.0f) {
1144     selection_candidate_step_2_count = *selection_candidate_count;
1145     k = 0;
1146     for (i = 0; i < selection_candidate_step_2_count; i++) {
1147       if (selection_candidate_info[i].output_peak_level <= 0.0f) {
1148         memcpy(&selection_candidate_info_step_2[k],
1149                &selection_candidate_info[i],
1150                sizeof(ia_selection_candidate_info_struct));
1151         k++;
1152       }
1153     }
1154     selection_candidate_step_2_count = k;
1155 
1156     k = 0;
1157     for (i = 0; i < selection_candidate_step_2_count; i++) {
1158       str_drc_instruction_str =
1159           &(pstr_drc_config->str_drc_instruction_str
1160                 [selection_candidate_info_step_2[i].drc_instructions_index]);
1161       for (n = 0; n < str_drc_instruction_str->dwnmix_id_count; n++) {
1162         if (pstr_drc_sel_proc_params_struct->requested_dwnmix_id
1163                 [selection_candidate_info_step_2[i].downmix_id_request_index] ==
1164             str_drc_instruction_str->downmix_id[n]) {
1165           if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
1166           memcpy(&selection_candidate_info_step_2[k],
1167                  &selection_candidate_info_step_2[i],
1168                  sizeof(ia_selection_candidate_info_struct));
1169           k++;
1170         }
1171       }
1172     }
1173     if (k > 0) {
1174       selection_candidate_step_2_count = k;
1175     }
1176 
1177     effect_types_request_table_size =
1178         sizeof(effect_types_request_table) / sizeof(WORD32);
1179     effect_count_min = 100;
1180     k = 0;
1181     for (i = 0; i < selection_candidate_step_2_count; i++) {
1182       str_drc_instruction_str =
1183           &(pstr_drc_config->str_drc_instruction_str
1184                 [selection_candidate_info_step_2[i].drc_instructions_index]);
1185       effect_count = 0;
1186       if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
1187         err = impd_get_dependent_drc_instructions(pstr_drc_config,
1188                                                   str_drc_instruction_str,
1189                                                   &drc_instructions_dependent);
1190         if (err) return (err);
1191 
1192         for (n = 0; n < effect_types_request_table_size; n++) {
1193           if (effect_types_request_table[n] != EFFECT_BIT_GENERAL_COMPR) {
1194             if (((str_drc_instruction_str->drc_set_effect &
1195                   effect_types_request_table[n]) != 0x0) ||
1196                 ((drc_instructions_dependent->drc_set_effect &
1197                   effect_types_request_table[n]) != 0x0)) {
1198               effect_count++;
1199             }
1200           }
1201         }
1202       } else {
1203         for (n = 0; n < effect_types_request_table_size; n++) {
1204           if (effect_types_request_table[n] != EFFECT_BIT_GENERAL_COMPR) {
1205             if ((str_drc_instruction_str->drc_set_effect &
1206                  effect_types_request_table[n]) != 0x0) {
1207               effect_count++;
1208             }
1209           }
1210         }
1211       }
1212       if (effect_count_min >= effect_count) {
1213         if (effect_count_min > effect_count) {
1214           effect_count_min = effect_count;
1215           k = 0;
1216         }
1217         memcpy(&selection_candidate_info_step_2[k],
1218                &selection_candidate_info_step_2[i],
1219                sizeof(ia_selection_candidate_info_struct));
1220         k++;
1221       }
1222     }
1223     selection_candidate_step_2_count = k;
1224 
1225     drc_set_target_loudness_val_upper_min = 100;
1226     k = 0;
1227     for (i = 0; i < selection_candidate_step_2_count; i++) {
1228       if (selection_candidate_info_step_2[i].selection_flags &
1229           SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH) {
1230         k++;
1231       }
1232     }
1233     if (k != 0 && k != selection_candidate_step_2_count) {
1234       k = 0;
1235       for (i = 0; i < selection_candidate_step_2_count; i++) {
1236         if (!(selection_candidate_info_step_2[i].selection_flags &
1237               SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH)) {
1238           memcpy(&selection_candidate_info_step_2[k],
1239                  &selection_candidate_info_step_2[i],
1240                  sizeof(ia_selection_candidate_info_struct));
1241           k++;
1242         }
1243       }
1244       selection_candidate_step_2_count = k;
1245     } else if (k == selection_candidate_step_2_count) {
1246       k = 0;
1247       for (i = 0; i < selection_candidate_step_2_count; i++) {
1248         str_drc_instruction_str =
1249             &(pstr_drc_config->str_drc_instruction_str
1250                   [selection_candidate_info_step_2[i].drc_instructions_index]);
1251         if (str_drc_instruction_str->drc_set_target_loudness_present != 1) {
1252           return UNEXPECTED_ERROR;
1253         }
1254         if (drc_set_target_loudness_val_upper_min >=
1255             str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1256           if (drc_set_target_loudness_val_upper_min >
1257               str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1258             drc_set_target_loudness_val_upper_min =
1259                 str_drc_instruction_str->drc_set_target_loudness_value_upper;
1260             k = 0;
1261           }
1262           memcpy(&selection_candidate_info_step_2[k],
1263                  &selection_candidate_info_step_2[i],
1264                  sizeof(ia_selection_candidate_info_struct));
1265           k++;
1266         }
1267       }
1268       selection_candidate_step_2_count = k;
1269     }
1270 
1271     k = 0;
1272     for (i = 0; i < selection_candidate_step_2_count; i++) {
1273       str_drc_instruction_str =
1274           &(pstr_drc_config->str_drc_instruction_str
1275                 [selection_candidate_info_step_2[i].drc_instructions_index]);
1276       if (str_drc_instruction_str->drc_set_target_loudness_present &&
1277           pstr_drc_sel_proc_params_struct->loudness_normalization_on &&
1278           str_drc_instruction_str->drc_set_target_loudness_value_upper >=
1279               pstr_drc_sel_proc_params_struct->target_loudness &&
1280           str_drc_instruction_str->drc_set_target_loudness_value_lower <
1281               pstr_drc_sel_proc_params_struct->target_loudness) {
1282         k++;
1283       }
1284     }
1285     if (k != 0 && k != selection_candidate_step_2_count) {
1286       k = 0;
1287       for (i = 0; i < selection_candidate_step_2_count; i++) {
1288         str_drc_instruction_str =
1289             &(pstr_drc_config->str_drc_instruction_str
1290                   [selection_candidate_info_step_2[i].drc_instructions_index]);
1291         if (str_drc_instruction_str->drc_set_target_loudness_present &&
1292             pstr_drc_sel_proc_params_struct->loudness_normalization_on &&
1293             str_drc_instruction_str->drc_set_target_loudness_value_upper >=
1294                 pstr_drc_sel_proc_params_struct->target_loudness &&
1295             str_drc_instruction_str->drc_set_target_loudness_value_lower <
1296                 pstr_drc_sel_proc_params_struct->target_loudness) {
1297           memcpy(&selection_candidate_info_step_2[k],
1298                  &selection_candidate_info_step_2[i],
1299                  sizeof(ia_selection_candidate_info_struct));
1300           k++;
1301         }
1302       }
1303       selection_candidate_step_2_count = k;
1304       drc_set_target_loudness_val_upper_min = 100;
1305       k = 0;
1306       for (i = 0; i < selection_candidate_step_2_count; i++) {
1307         str_drc_instruction_str =
1308             &(pstr_drc_config->str_drc_instruction_str
1309                   [selection_candidate_info_step_2[i].drc_instructions_index]);
1310         if (str_drc_instruction_str->drc_set_target_loudness_present != 1) {
1311           return UNEXPECTED_ERROR;
1312         }
1313         if (drc_set_target_loudness_val_upper_min >=
1314             str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1315           if (drc_set_target_loudness_val_upper_min >
1316               str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1317             drc_set_target_loudness_val_upper_min =
1318                 str_drc_instruction_str->drc_set_target_loudness_value_upper;
1319             k = 0;
1320           }
1321           memcpy(&selection_candidate_info_step_2[k],
1322                  &selection_candidate_info_step_2[i],
1323                  sizeof(ia_selection_candidate_info_struct));
1324           k++;
1325         }
1326       }
1327       selection_candidate_step_2_count = k;
1328     } else if (k == selection_candidate_step_2_count) {
1329       drc_set_target_loudness_val_upper_min = 100;
1330       k = 0;
1331       for (i = 0; i < selection_candidate_step_2_count; i++) {
1332         str_drc_instruction_str =
1333             &(pstr_drc_config->str_drc_instruction_str
1334                   [selection_candidate_info_step_2[i].drc_instructions_index]);
1335         if (str_drc_instruction_str->drc_set_target_loudness_present != 1) {
1336           return UNEXPECTED_ERROR;
1337         }
1338         if (drc_set_target_loudness_val_upper_min >=
1339             str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1340           if (drc_set_target_loudness_val_upper_min >
1341               str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1342             drc_set_target_loudness_val_upper_min =
1343                 str_drc_instruction_str->drc_set_target_loudness_value_upper;
1344             k = 0;
1345           }
1346           memcpy(&selection_candidate_info_step_2[k],
1347                  &selection_candidate_info_step_2[i],
1348                  sizeof(ia_selection_candidate_info_struct));
1349           k++;
1350         }
1351       }
1352       selection_candidate_step_2_count = k;
1353     }
1354     k = 0;
1355     output_level_max = -1000.0f;
1356     for (i = 0; i < selection_candidate_step_2_count; i++) {
1357       if ((selection_candidate_info_step_2[i].output_peak_level <= 0.0f) &&
1358           (output_level_max <=
1359            selection_candidate_info_step_2[i].output_peak_level)) {
1360         if (output_level_max <
1361             selection_candidate_info_step_2[i].output_peak_level) {
1362           output_level_max =
1363               selection_candidate_info_step_2[i].output_peak_level;
1364           k = 0;
1365         }
1366         memcpy(&selection_candidate_info_step_2[k],
1367                &selection_candidate_info_step_2[i],
1368                sizeof(ia_selection_candidate_info_struct));
1369         k++;
1370         output_level_max = selection_candidate_info_step_2[i].output_peak_level;
1371       }
1372     }
1373     selection_candidate_step_2_count = k;
1374   }
1375 
1376   drc_set_id_max = -1000;
1377   for (i = 0; i < selection_candidate_step_2_count; i++) {
1378     str_drc_instruction_str =
1379         &(pstr_drc_config->str_drc_instruction_str
1380               [selection_candidate_info_step_2[i].drc_instructions_index]);
1381     if (drc_set_id_max < str_drc_instruction_str->drc_set_id) {
1382       drc_set_id_max = str_drc_instruction_str->drc_set_id;
1383       memcpy(&selection_candidate_info_step_2[0],
1384              &selection_candidate_info_step_2[i],
1385              sizeof(ia_selection_candidate_info_struct));
1386     }
1387   }
1388   memcpy(&selection_candidate_info[0], &selection_candidate_info_step_2[0],
1389          sizeof(ia_selection_candidate_info_struct));
1390   *selection_candidate_count = 1;
1391 
1392   return 0;
1393 }
1394 
impd_select_drc_set(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc,WORD32 * drc_set_id_selected,WORD32 * eq_set_id_selected,WORD32 * loud_eq_id_sel)1395 WORD32 impd_select_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
1396                            WORD32* drc_set_id_selected,
1397                            WORD32* eq_set_id_selected, WORD32* loud_eq_id_sel) {
1398   WORD32 i, err;
1399 
1400   ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct =
1401       &pstr_drc_uni_sel_proc->uni_drc_sel_proc_params;
1402   ia_drc_config* pstr_drc_config = &pstr_drc_uni_sel_proc->drc_config;
1403   ia_drc_loudness_info_set_struct* pstr_loudness_info =
1404       &pstr_drc_uni_sel_proc->loudness_info_set;
1405 
1406   WORD32 selection_candidate_count = 0;
1407   WORD32 restrict_to_drc_with_album_loudness = 0;
1408   ia_selection_candidate_info_struct
1409       selection_candidate_info[SELECTION_CANDIDATE_COUNT_MAX];
1410 
1411   //    WORD32 selected_eq_set_count = 0;
1412 
1413   if (pstr_drc_sel_proc_params_struct->album_mode == 1) {
1414     restrict_to_drc_with_album_loudness = 1;
1415   }
1416 
1417   while (!selection_candidate_count) {
1418     err = impd_drc_set_preselection(
1419         pstr_drc_sel_proc_params_struct, pstr_drc_config, pstr_loudness_info,
1420         restrict_to_drc_with_album_loudness, pstr_drc_uni_sel_proc,
1421         &selection_candidate_count, selection_candidate_info);
1422     if (err) return err;
1423 
1424     if (selection_candidate_count == 0) {
1425       if (restrict_to_drc_with_album_loudness == 1) {
1426         restrict_to_drc_with_album_loudness = 0;
1427         continue;
1428       } else {
1429         return (UNEXPECTED_ERROR);
1430       }
1431     }
1432 
1433     err = impd_validate_requested_drc_feature(pstr_drc_sel_proc_params_struct);
1434     if (err) return (err);
1435 
1436     if (pstr_drc_sel_proc_params_struct->dynamic_range_control_on == 1) {
1437       if (pstr_drc_sel_proc_params_struct->num_drc_feature_requests > 0) {
1438         for (i = 0;
1439              i < pstr_drc_sel_proc_params_struct->num_drc_feature_requests;
1440              i++) {
1441           switch (pstr_drc_sel_proc_params_struct->drc_feature_req_type[i]) {
1442             case MATCH_EFFECT_TYPE:
1443               err = impd_match_effect_types(
1444                   pstr_drc_config,
1445                   pstr_drc_sel_proc_params_struct->requested_num_drc_effects[i],
1446                   pstr_drc_sel_proc_params_struct
1447                       ->desired_num_drc_effects_of_requested[i],
1448                   pstr_drc_sel_proc_params_struct->requested_drc_effect_type[i],
1449                   &selection_candidate_count, selection_candidate_info);
1450               if (err) return (err);
1451               break;
1452             case MATCH_DYNAMIC_RANGE:
1453               err = impd_match_dynamic_range(
1454                   pstr_drc_config, pstr_loudness_info,
1455                   pstr_drc_sel_proc_params_struct, i,
1456                   &selection_candidate_count, selection_candidate_info);
1457               if (err) return (err);
1458               break;
1459             case MATCH_DRC_CHARACTERISTIC:
1460               err = impd_match_drc_characteristic(
1461                   pstr_drc_config, pstr_drc_sel_proc_params_struct
1462                                        ->requested_drc_characteristic[i],
1463                   &selection_candidate_count, selection_candidate_info);
1464               if (err) return (err);
1465               break;
1466 
1467             default:
1468               return (UNEXPECTED_ERROR);
1469               break;
1470           }
1471         }
1472       } else {
1473         WORD32 match_found_flag = 0;
1474 
1475         err = impd_select_drcs_without_compr_effects(
1476             pstr_drc_config, &match_found_flag, &selection_candidate_count,
1477             selection_candidate_info);
1478         if (err) return (err);
1479 
1480         if (match_found_flag == 0) {
1481           WORD32 requested_num_drc_effects = 5;
1482           WORD32 desired_num_drc_effects_of_requested = 1;
1483           WORD32 requested_drc_effect_type[5] = {
1484               EFFECT_TYPE_REQUESTED_GENERAL_COMPR, EFFECT_TYPE_REQUESTED_NIGHT,
1485               EFFECT_TYPE_REQUESTED_NOISY, EFFECT_TYPE_REQUESTED_LIMITED,
1486               EFFECT_TYPE_REQUESTED_LOWLEVEL};
1487 
1488           err = impd_match_effect_types(
1489               pstr_drc_config, requested_num_drc_effects,
1490               desired_num_drc_effects_of_requested, requested_drc_effect_type,
1491               &selection_candidate_count, selection_candidate_info);
1492           if (err) return (err);
1493         }
1494       }
1495 
1496       if (selection_candidate_count > 0) {
1497         err = impd_drc_set_final_selection(
1498             pstr_drc_config, pstr_drc_sel_proc_params_struct,
1499             &selection_candidate_count, selection_candidate_info,
1500             pstr_drc_uni_sel_proc->eq_set_id_valid_flag);
1501         if (err) return (err);
1502       } else {
1503         selection_candidate_count = 0;
1504         return (UNEXPECTED_ERROR);
1505       }
1506     }
1507 
1508     if (selection_candidate_count == 0) {
1509       if (restrict_to_drc_with_album_loudness == 1) {
1510         restrict_to_drc_with_album_loudness = 0;
1511       } else {
1512         return (UNEXPECTED_ERROR);
1513       }
1514     }
1515   }
1516   *drc_set_id_selected =
1517       pstr_drc_config
1518           ->str_drc_instruction_str[selection_candidate_info[0]
1519                                         .drc_instructions_index]
1520           .drc_set_id;
1521   *eq_set_id_selected = selection_candidate_info[0].eq_set_id;
1522 
1523   err = impd_select_loud_eq(
1524       pstr_drc_config,
1525       pstr_drc_sel_proc_params_struct->requested_dwnmix_id
1526           [selection_candidate_info[0].downmix_id_request_index],
1527       *drc_set_id_selected, *eq_set_id_selected, loud_eq_id_sel);
1528   if (err) return (err);
1529   if (selection_candidate_count > 0) {
1530     pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
1531         .loudness_normalization_gain_db =
1532         selection_candidate_info[0].loudness_norm_db_gain_adjusted;
1533     pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.output_peak_level_db =
1534         selection_candidate_info[0].output_peak_level;
1535     pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.output_loudness =
1536         selection_candidate_info[0].output_loudness;
1537     pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.active_downmix_id =
1538         pstr_drc_sel_proc_params_struct->requested_dwnmix_id
1539             [selection_candidate_info[0].downmix_id_request_index];
1540     pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.mixing_level =
1541         selection_candidate_info[0].mixing_level;
1542   }
1543   return (0);
1544 }
1545