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