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