• 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 <stdlib.h>
22 #include <math.h>
23 #include <string.h>
24 #include "impd_type_def.h"
25 #include "impd_drc_extr_delta_coded_info.h"
26 #include "impd_drc_common.h"
27 #include "impd_drc_struct.h"
28 #include "impd_drc_interface.h"
29 #include "impd_drc_selection_process.h"
30 #include "impd_drc_sel_proc_drc_set_sel.h"
31 
impd_drc_uni_selction_proc_init(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc,ia_drc_sel_proc_params_struct * pstr_drc_sel_proc_params_struct,ia_drc_interface_struct * pstr_drc_interface,WORD32 subband_domain_mode)32 WORD32 impd_drc_uni_selction_proc_init(
33     ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
34     ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
35     ia_drc_interface_struct* pstr_drc_interface, WORD32 subband_domain_mode) {
36   WORD32 err = 0;
37 
38   if (pstr_drc_uni_sel_proc == NULL) {
39     return 1;
40   }
41 
42   if (pstr_drc_uni_sel_proc->first_frame == 1) {
43     err = impd_drc_sel_proc_init_dflt(pstr_drc_uni_sel_proc);
44     if (err) return (err);
45   }
46 
47   err = impd_drc_sel_proc_init_sel_proc_params(pstr_drc_uni_sel_proc,
48                                                pstr_drc_sel_proc_params_struct);
49   if (err) return (err);
50   {
51     WORD32 i;
52     pstr_drc_uni_sel_proc->drc_set_id_valid_flag[0] = 1;
53     for (i = 1; i < DRC_INSTRUCTIONS_COUNT_MAX; i++) {
54       pstr_drc_uni_sel_proc->drc_set_id_valid_flag[i] = 0;
55     }
56 
57     pstr_drc_uni_sel_proc->eq_set_id_valid_flag[0] = 1;
58     for (i = 1; i < EQ_INSTRUCTIONS_COUNT_MAX; i++) {
59       pstr_drc_uni_sel_proc->eq_set_id_valid_flag[i] = 0;
60     }
61   }
62   err = impd_drc_sel_proc_init_interface_params(pstr_drc_uni_sel_proc,
63                                                 pstr_drc_interface);
64   if (err) return (err);
65 
66   pstr_drc_uni_sel_proc->subband_domain_mode = subband_domain_mode;
67 
68   return 0;
69 }
70 
71 WORD32
impd_drc_uni_sel_proc_process(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc,ia_drc_config * pstr_drc_config,ia_drc_loudness_info_set_struct * pstr_loudness_info,ia_drc_sel_proc_output_struct * hia_drc_sel_proc_output_struct)72 impd_drc_uni_sel_proc_process(
73     ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
74     ia_drc_config* pstr_drc_config,
75     ia_drc_loudness_info_set_struct* pstr_loudness_info,
76     ia_drc_sel_proc_output_struct* hia_drc_sel_proc_output_struct) {
77   WORD32 i, err, drc_set_id_selected, activeDrcSetIndex;
78   WORD32 eq_set_id_selected;
79   WORD32 loudEqSetIdSelected;
80 
81   if (pstr_drc_config != NULL) {
82     if (memcmp(&pstr_drc_uni_sel_proc->drc_config, pstr_drc_config,
83                sizeof(ia_drc_config))) {
84       pstr_drc_uni_sel_proc->drc_config = *pstr_drc_config;
85       pstr_drc_uni_sel_proc->drc_config_flag = 1;
86 
87       if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_channel_count !=
88           pstr_drc_uni_sel_proc->drc_config.channel_layout.base_channel_count) {
89         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_channel_count =
90             pstr_drc_uni_sel_proc->drc_config.channel_layout.base_channel_count;
91       }
92       if (pstr_drc_uni_sel_proc->drc_config.channel_layout
93                   .layout_signaling_present == 1 &&
94           pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_layout !=
95               pstr_drc_uni_sel_proc->drc_config.channel_layout.defined_layout) {
96         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_layout =
97             pstr_drc_uni_sel_proc->drc_config.channel_layout.defined_layout;
98       }
99     } else {
100       pstr_drc_uni_sel_proc->drc_config_flag = 0;
101     }
102   }
103   if (pstr_loudness_info != NULL) {
104     if (memcmp(&pstr_drc_uni_sel_proc->loudness_info_set, pstr_loudness_info,
105                sizeof(ia_drc_loudness_info_set_struct))) {
106       pstr_drc_uni_sel_proc->loudness_info_set = *pstr_loudness_info;
107       pstr_drc_uni_sel_proc->loudness_info_set_flag = 1;
108     } else {
109       pstr_drc_uni_sel_proc->loudness_info_set_flag = 0;
110     }
111   }
112 
113   if ((pstr_drc_uni_sel_proc->drc_config_flag &&
114        pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
115                .target_config_request_type != 0) ||
116       (pstr_drc_uni_sel_proc->sel_proc_request_flag &&
117        pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
118                .target_config_request_type != 0) ||
119       (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
120                .target_config_request_type == 0 &&
121        pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests ==
122            0)) {
123     err = impd_map_target_config_req_downmix_id(
124         pstr_drc_uni_sel_proc, &pstr_drc_uni_sel_proc->drc_config);
125     if (err) return (err);
126   }
127 
128   if (pstr_drc_uni_sel_proc->drc_config_flag ||
129       pstr_drc_uni_sel_proc->loudness_info_set_flag ||
130       pstr_drc_uni_sel_proc->sel_proc_request_flag) {
131     WORD32 repeat_selection = 1;
132     WORD32 loop_cnt = 0;
133 
134     err = impd_manage_drc_complexity(pstr_drc_uni_sel_proc, pstr_drc_config);
135     if (err) return (err);
136     err = impd_manage_eq_complexity(pstr_drc_uni_sel_proc, pstr_drc_config);
137     if (err) return (err);
138     while (repeat_selection == 1) {
139       err = impd_select_drc_set(pstr_drc_uni_sel_proc, &drc_set_id_selected,
140                                 &eq_set_id_selected, &loudEqSetIdSelected);
141       if (err) return (err);
142 
143       err =
144           impd_get_selected_drc_set(pstr_drc_uni_sel_proc, drc_set_id_selected);
145       if (err) return (err);
146 
147       err = impd_get_dependent_drc_set(pstr_drc_uni_sel_proc);
148       if (err) return (err);
149 
150       err = impd_get_fading_drc_set(pstr_drc_uni_sel_proc);
151       if (err) return (err);
152 
153       err = impd_get_ducking_drc_set(pstr_drc_uni_sel_proc);
154       if (err) return (err);
155 
156       pstr_drc_uni_sel_proc->eq_inst_index[0] = -1;
157       pstr_drc_uni_sel_proc->eq_inst_index[1] = -1;
158 
159       err = impd_get_selected_eq_set(pstr_drc_uni_sel_proc, eq_set_id_selected);
160       if (err) return (err);
161 
162       err = impd_get_dependent_eq_set(pstr_drc_uni_sel_proc);
163       if (err) return (err);
164 
165       err = impd_get_selected_loud_eq_set(pstr_drc_uni_sel_proc,
166                                           loudEqSetIdSelected);
167       if (err) return (err);
168 
169       activeDrcSetIndex = 0;
170       for (i = SUB_DRC_COUNT - 1; i >= 0; i--) {
171         WORD32 drc_instructions_index =
172             pstr_drc_uni_sel_proc->drc_instructions_index[i];
173         if (drc_instructions_index < 0) continue;
174 
175         ia_drc_instructions_struct* str_drc_instruction_str =
176             &(pstr_drc_uni_sel_proc->drc_config
177                   .str_drc_instruction_str[drc_instructions_index]);
178 
179         if (str_drc_instruction_str->drc_set_id > 0) {
180           pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
181               .sel_drc_set_ids[activeDrcSetIndex] =
182               str_drc_instruction_str->drc_set_id;
183 
184           if ((i == 3) && (str_drc_instruction_str->drc_set_effect &
185                            (EFFECT_BIT_DUCK_SELF | EFFECT_BIT_DUCK_OTHER))) {
186             pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
187                 .sel_downmix_ids[activeDrcSetIndex] = 0;
188           } else {
189             if (str_drc_instruction_str->drc_apply_to_dwnmix == 1) {
190               pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
191                   .sel_downmix_ids[activeDrcSetIndex] =
192                   str_drc_instruction_str->downmix_id[0];
193             } else {
194               pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
195                   .sel_downmix_ids[activeDrcSetIndex] = 0;
196             }
197           }
198 
199           activeDrcSetIndex++;
200         }
201       }
202       if (activeDrcSetIndex <= 3) {
203         pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.num_sel_drc_sets =
204             activeDrcSetIndex;
205       } else {
206         pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.num_sel_drc_sets = -1;
207         return (UNEXPECTED_ERROR);
208       }
209 
210       impd_sel_downmix_matrix(pstr_drc_uni_sel_proc,
211                               &pstr_drc_uni_sel_proc->drc_config);
212 
213       err = impd_manage_complexity(pstr_drc_uni_sel_proc, pstr_drc_config,
214                                    &repeat_selection);
215       if (err) return (err);
216 
217       loop_cnt++;
218       if (loop_cnt > 100) {
219         return (UNEXPECTED_ERROR);
220       }
221     }
222 
223     pstr_drc_uni_sel_proc->sel_proc_request_flag = 0;
224     pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.boost =
225         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.boost;
226     pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.compress =
227         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.compress;
228     pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.drc_characteristic_target =
229         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
230             .drc_characteristic_target;
231     pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
232         .loudness_normalization_gain_db +=
233         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
234             .loudness_norm_gain_modification_db;
235   }
236   for (i = 0; i < 2; i++) {
237     if (pstr_drc_uni_sel_proc->eq_inst_index[i] >= 0) {
238       pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_eq_set_ids[i] =
239           pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
240               .str_eq_instructions[pstr_drc_uni_sel_proc->eq_inst_index[i]]
241               .eq_set_id;
242     }
243   }
244   if (pstr_drc_uni_sel_proc->loud_eq_inst_index_sel >= 0) {
245     pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_loud_eq_id =
246         pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
247             .loud_eq_instructions[pstr_drc_uni_sel_proc->loud_eq_inst_index_sel]
248             .loud_eq_set_id;
249   } else {
250     pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_loud_eq_id = 0;
251   }
252   *hia_drc_sel_proc_output_struct =
253       pstr_drc_uni_sel_proc->uni_drc_sel_proc_output;
254 
255   return 0;
256 }
257 
impd_map_target_config_req_downmix_id(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc,ia_drc_config * pstr_drc_config)258 WORD32 impd_map_target_config_req_downmix_id(
259     ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
260     ia_drc_config* pstr_drc_config) {
261   WORD32 i, dwnmix_instructions_count;
262   WORD32 target_ch_count_prelim =
263       pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_channel_count;
264 
265   pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests = 0;
266   switch (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
267               .target_config_request_type) {
268     case 0:
269       if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
270               .num_downmix_id_requests == 0) {
271         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id[0] =
272             0;
273         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests =
274             1;
275       }
276       break;
277     case 1:
278       if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
279               .requested_target_layout ==
280           pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_layout) {
281         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id[0] =
282             0;
283         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests =
284             1;
285       }
286       if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
287               .num_downmix_id_requests == 0) {
288         dwnmix_instructions_count =
289             pstr_drc_uni_sel_proc->drc_config.dwnmix_instructions_count;
290         for (i = 0; i < dwnmix_instructions_count; i++) {
291           ia_downmix_instructions_struct* dwnmix_instructions =
292               &(pstr_drc_config->dwnmix_instructions[i]);
293           if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
294                   .requested_target_layout ==
295               dwnmix_instructions->target_layout) {
296             pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id
297                 [pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
298                      .num_downmix_id_requests] =
299                 dwnmix_instructions->downmix_id;
300             pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
301                 .num_downmix_id_requests += 1;
302             target_ch_count_prelim = dwnmix_instructions->target_channel_count;
303           }
304         }
305       }
306 
307       if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
308               .num_downmix_id_requests == 0) {
309         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id[0] =
310             0;
311         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests =
312             1;
313       }
314       break;
315     case 2:
316       if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
317               .requested_target_ch_count ==
318           pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_channel_count) {
319         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id[0] =
320             0;
321         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests =
322             1;
323       }
324       if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
325               .num_downmix_id_requests == 0) {
326         dwnmix_instructions_count =
327             pstr_drc_uni_sel_proc->drc_config.dwnmix_instructions_count;
328         for (i = 0; i < dwnmix_instructions_count; i++) {
329           ia_downmix_instructions_struct* dwnmix_instructions =
330               &(pstr_drc_config->dwnmix_instructions[i]);
331           if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
332                   .requested_target_ch_count ==
333               dwnmix_instructions->target_channel_count) {
334             pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id
335                 [pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
336                      .num_downmix_id_requests] =
337                 dwnmix_instructions->downmix_id;
338             pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
339                 .num_downmix_id_requests += 1;
340             target_ch_count_prelim = dwnmix_instructions->target_channel_count;
341           }
342         }
343       }
344 
345       if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
346               .num_downmix_id_requests == 0) {
347         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id[0] =
348             0;
349         pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests =
350             1;
351       }
352       break;
353     default:
354       return UNEXPECTED_ERROR;
355       break;
356   }
357   pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.target_ch_count_prelim =
358       target_ch_count_prelim;
359 
360   return 0;
361 }
362 
impd_sel_downmix_matrix(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc,ia_drc_config * pstr_drc_config)363 VOID impd_sel_downmix_matrix(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
364                              ia_drc_config* pstr_drc_config) {
365   WORD32 i, j, n;
366 
367   pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.base_channel_count =
368       pstr_drc_config->channel_layout.base_channel_count;
369   pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.target_channel_count =
370       pstr_drc_config->channel_layout.base_channel_count;
371   pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.target_layout = -1;
372   pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.downmix_matrix_present = 0;
373   pstr_drc_uni_sel_proc->downmix_inst_index_sel = -1;
374 
375   if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.active_downmix_id != 0) {
376     for (n = 0; n < pstr_drc_config->dwnmix_instructions_count; n++) {
377       ia_downmix_instructions_struct* dwnmix_instructions =
378           &(pstr_drc_config->dwnmix_instructions[n]);
379 
380       if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.active_downmix_id ==
381           dwnmix_instructions->downmix_id) {
382         pstr_drc_uni_sel_proc->downmix_inst_index_sel = n;
383         pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.target_channel_count =
384             dwnmix_instructions->target_channel_count;
385         pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.target_layout =
386             dwnmix_instructions->target_layout;
387         if (dwnmix_instructions->downmix_coefficients_present) {
388           for (i = 0; i < pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
389                               .base_channel_count;
390                i++) {
391             for (j = 0; j < pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
392                                 .target_channel_count;
393                  j++) {
394               pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
395                   .downmix_matrix[i][j] =
396                   dwnmix_instructions->downmix_coefficient
397                       [i +
398                        j *
399                            pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
400                                .base_channel_count];
401             }
402           }
403           pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
404               .downmix_matrix_present = 1;
405         }
406         break;
407       }
408     }
409   }
410   return;
411 }
412 
impd_get_selected_eq_set(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc,WORD32 eq_set_id_selected)413 WORD32 impd_get_selected_eq_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
414                                 WORD32 eq_set_id_selected) {
415   WORD32 n;
416 
417   pstr_drc_uni_sel_proc->eq_inst_index_sel = -1;
418 
419   if (eq_set_id_selected > 0) {
420     for (n = 0; n < pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
421                         .eq_instructions_count;
422          n++) {
423       if (pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
424               .str_eq_instructions[n]
425               .eq_set_id == eq_set_id_selected)
426         break;
427     }
428     if (n ==
429         pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
430             .eq_instructions_count) {
431       return (EXTERNAL_ERROR);
432     }
433     pstr_drc_uni_sel_proc->eq_inst_index_sel = n;
434     if (pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
435             .str_eq_instructions[n]
436             .eq_apply_to_downmix == 1) {
437       pstr_drc_uni_sel_proc->eq_inst_index[1] =
438           pstr_drc_uni_sel_proc->eq_inst_index_sel;
439     } else {
440       pstr_drc_uni_sel_proc->eq_inst_index[0] =
441           pstr_drc_uni_sel_proc->eq_inst_index_sel;
442     }
443   }
444   return (0);
445 }
446 
impd_get_dependent_eq_set(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc)447 WORD32 impd_get_dependent_eq_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
448   ia_eq_instructions_struct* str_eq_instructions = NULL;
449 
450   if (pstr_drc_uni_sel_proc->eq_inst_index_sel >= 0) {
451     str_eq_instructions =
452         &(pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
453               .str_eq_instructions[pstr_drc_uni_sel_proc->eq_inst_index_sel]);
454 
455     if (str_eq_instructions->depends_on_eq_set_present == 1) {
456       WORD32 n;
457       WORD32 dependsOnEqSetID = str_eq_instructions->depends_on_eq_set;
458 
459       for (n = 0; n < pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
460                           .eq_instructions_count;
461            n++) {
462         if (pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
463                 .str_eq_instructions[n]
464                 .eq_set_id == dependsOnEqSetID)
465           break;
466       }
467       if (n ==
468           pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
469               .eq_instructions_count) {
470         return (UNEXPECTED_ERROR);
471       }
472       if (pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
473               .str_eq_instructions[n]
474               .eq_apply_to_downmix == 1) {
475         pstr_drc_uni_sel_proc->eq_inst_index[1] = n;
476       } else {
477         pstr_drc_uni_sel_proc->eq_inst_index[0] = n;
478       }
479     }
480   }
481   return (0);
482 }
483 
impd_get_selected_loud_eq_set(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc,WORD32 loudEqSetIdSelected)484 WORD32 impd_get_selected_loud_eq_set(
485     ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc, WORD32 loudEqSetIdSelected) {
486   WORD32 n;
487 
488   pstr_drc_uni_sel_proc->loud_eq_inst_index_sel = -1;
489 
490   if (loudEqSetIdSelected > 0) {
491     for (n = 0; n < pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
492                         .loud_eq_instructions_count;
493          n++) {
494       if (pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
495               .loud_eq_instructions[n]
496               .loud_eq_set_id == loudEqSetIdSelected)
497         break;
498     }
499     if (n ==
500         pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext
501             .loud_eq_instructions_count) {
502       return (EXTERNAL_ERROR);
503     }
504     pstr_drc_uni_sel_proc->loud_eq_inst_index_sel = n;
505   }
506   return (0);
507 }
508 
impd_select_loud_eq(ia_drc_config * pstr_drc_config,WORD32 requested_dwnmix_id,WORD32 drc_set_id_requested,WORD32 eq_set_id_requested,WORD32 * loud_eq_id_sel)509 WORD32 impd_select_loud_eq(ia_drc_config* pstr_drc_config,
510                            WORD32 requested_dwnmix_id,
511                            WORD32 drc_set_id_requested,
512                            WORD32 eq_set_id_requested, WORD32* loud_eq_id_sel) {
513   WORD32 i, c, d, e;
514 
515   *loud_eq_id_sel = 0;
516   for (i = 0;
517        i < pstr_drc_config->str_drc_config_ext.loud_eq_instructions_count;
518        i++) {
519     ia_loud_eq_instructions_struct* loud_eq_instructions =
520         &pstr_drc_config->str_drc_config_ext.loud_eq_instructions[i];
521     if (loud_eq_instructions->drc_location == LOCATION_SELECTED) {
522       for (d = 0; d < loud_eq_instructions->dwnmix_id_count; d++) {
523         if ((loud_eq_instructions->downmix_id[d] == requested_dwnmix_id) ||
524             (loud_eq_instructions->downmix_id[d] == ID_FOR_ANY_DOWNMIX)) {
525           for (c = 0; c < loud_eq_instructions->drc_set_id_count; c++) {
526             if ((loud_eq_instructions->drc_set_id[c] == drc_set_id_requested) ||
527                 (loud_eq_instructions->drc_set_id[c] == ID_FOR_ANY_DRC)) {
528               for (e = 0; e < loud_eq_instructions->eq_set_id_count; e++) {
529                 if ((loud_eq_instructions->eq_set_id[e] ==
530                      eq_set_id_requested) ||
531                     (loud_eq_instructions->eq_set_id[e] == ID_FOR_ANY_EQ)) {
532                   *loud_eq_id_sel = loud_eq_instructions->loud_eq_set_id;
533                 }
534               }
535             }
536           }
537         }
538       }
539     }
540   }
541   return (0);
542 }
543 
impd_match_eq_set(ia_drc_config * drc_config,WORD32 downmix_id,WORD32 drc_set_id,WORD32 * eq_set_id_valid_flag,WORD32 * matching_eq_set_count,WORD32 * matching_eq_set_idx)544 WORD32 impd_match_eq_set(ia_drc_config* drc_config, WORD32 downmix_id,
545                          WORD32 drc_set_id, WORD32* eq_set_id_valid_flag,
546                          WORD32* matching_eq_set_count,
547                          WORD32* matching_eq_set_idx) {
548   ia_eq_instructions_struct* str_eq_instructions = NULL;
549   WORD32 i, k, n;
550   WORD32 match = 0;
551   *matching_eq_set_count = 0;
552   for (i = 0; i < drc_config->str_drc_config_ext.eq_instructions_count; i++) {
553     str_eq_instructions =
554         &drc_config->str_drc_config_ext.str_eq_instructions[i];
555 
556     if (str_eq_instructions->depends_on_eq_set_present == 0) {
557       if (str_eq_instructions->no_independent_eq_use == 1) continue;
558     }
559     if (eq_set_id_valid_flag[str_eq_instructions->eq_set_id] == 0) continue;
560     for (k = 0; k < str_eq_instructions->dwnmix_id_count; k++) {
561       if ((str_eq_instructions->downmix_id[k] == ID_FOR_ANY_DOWNMIX) ||
562           (downmix_id == str_eq_instructions->downmix_id[k])) {
563         for (n = 0; n < str_eq_instructions->drc_set_id_count; n++) {
564           if ((str_eq_instructions->drc_set_id[n] == ID_FOR_ANY_DRC) ||
565               (drc_set_id == str_eq_instructions->drc_set_id[n])) {
566             match = 1;
567             matching_eq_set_idx[*matching_eq_set_count] = i;
568             (*matching_eq_set_count)++;
569           }
570         }
571       }
572     }
573   }
574   return (0);
575 }
576 
impd_match_eq_set_purpose(ia_drc_config * drc_config,WORD32 eq_set_purpose_requested,WORD32 * eq_set_id_valid_flag,WORD32 * selection_candidate_count,ia_selection_candidate_info_struct * selection_candidate_info,ia_selection_candidate_info_struct * selection_candidate_info_step_2)577 WORD32 impd_match_eq_set_purpose(
578     ia_drc_config* drc_config, WORD32 eq_set_purpose_requested,
579     WORD32* eq_set_id_valid_flag, WORD32* selection_candidate_count,
580     ia_selection_candidate_info_struct* selection_candidate_info,
581     ia_selection_candidate_info_struct* selection_candidate_info_step_2) {
582   WORD32 i, j, k;
583   WORD32 match_found_flag;
584   WORD32 loop_cnt = 0;
585   ia_eq_instructions_struct* str_eq_instructions = NULL;
586   match_found_flag = 0;
587 
588   k = 0;
589   while ((k == 0) && (loop_cnt < 2)) {
590     for (j = 0; j < *selection_candidate_count; j++) {
591       WORD32 eq_set_id_requested = selection_candidate_info[j].eq_set_id;
592 
593       for (i = 0; i < drc_config->str_drc_config_ext.eq_instructions_count;
594            i++) {
595         str_eq_instructions =
596             &drc_config->str_drc_config_ext.str_eq_instructions[i];
597 
598         if (str_eq_instructions->depends_on_eq_set_present == 0) {
599           if (eq_set_id_valid_flag[str_eq_instructions->eq_set_id] == 0)
600             continue;
601         }
602         if (eq_set_id_valid_flag[str_eq_instructions->eq_set_id] == 0) continue;
603         if ((str_eq_instructions->eq_set_id == eq_set_id_requested) &&
604             (str_eq_instructions->eq_set_purpose & eq_set_purpose_requested)) {
605           match_found_flag = 1;
606         }
607       }
608 
609       if (match_found_flag > 0) {
610         memcpy(&selection_candidate_info_step_2[k],
611                &selection_candidate_info[j],
612                sizeof(ia_selection_candidate_info_struct));
613         k++;
614       }
615     }
616     eq_set_purpose_requested = EQ_PURPOSE_DEFAULT;
617     loop_cnt++;
618   }
619 
620   if (k > 0) {
621     memcpy(&selection_candidate_info[0], &selection_candidate_info_step_2[0],
622            k * sizeof(ia_selection_candidate_info_struct));
623     *selection_candidate_count = k;
624   }
625 
626   return (0);
627 }
628 
impd_find_eq_set_no_compression(ia_drc_config * pstr_drc_config,WORD32 requested_dwnmix_id,WORD32 * num_compression_eq_count,WORD32 * num_compression_eq_id)629 WORD32 impd_find_eq_set_no_compression(ia_drc_config* pstr_drc_config,
630                                        WORD32 requested_dwnmix_id,
631                                        WORD32* num_compression_eq_count,
632                                        WORD32* num_compression_eq_id) {
633   WORD32 i, d, k, c;
634   k = 0;
635   for (i = 0; i < pstr_drc_config->str_drc_config_ext.eq_instructions_count;
636        i++) {
637     ia_eq_instructions_struct* str_eq_instructions =
638         &pstr_drc_config->str_drc_config_ext.str_eq_instructions[i];
639     for (d = 0; d < str_eq_instructions->dwnmix_id_count; d++) {
640       if (requested_dwnmix_id == str_eq_instructions->downmix_id[d]) {
641         for (c = 0; c < str_eq_instructions->drc_set_id_count; c++) {
642           if ((str_eq_instructions->drc_set_id[c] == ID_FOR_ANY_DRC) ||
643               (str_eq_instructions->drc_set_id[c] == 0)) {
644             if (k >= MAX_NUM_COMPRESSION_EQ) return UNEXPECTED_ERROR;
645             num_compression_eq_id[k] = str_eq_instructions->eq_set_id;
646             k++;
647           }
648         }
649       }
650     }
651   }
652   *num_compression_eq_count = k;
653   return (0);
654 }
655 
impd_select_drc_coeff3(ia_drc_config * drc_config,ia_uni_drc_coeffs_struct ** str_p_loc_drc_coefficients_uni_drc)656 VOID impd_select_drc_coeff3(
657     ia_drc_config* drc_config,
658     ia_uni_drc_coeffs_struct** str_p_loc_drc_coefficients_uni_drc) {
659   WORD32 n;
660   WORD32 cV1 = -1;
661   WORD32 cV0 = -1;
662   for (n = 0; n < drc_config->drc_coefficients_drc_count; n++) {
663     if (drc_config->str_p_loc_drc_coefficients_uni_drc[n].drc_location == 1) {
664       if (drc_config->str_p_loc_drc_coefficients_uni_drc[n].version == 0) {
665         cV0 = n;
666       } else {
667         cV1 = n;
668       }
669     }
670   }
671   if (cV1 >= 0) {
672     *str_p_loc_drc_coefficients_uni_drc =
673         &(drc_config->str_p_loc_drc_coefficients_uni_drc[cV1]);
674   } else if (cV0 >= 0) {
675     *str_p_loc_drc_coefficients_uni_drc =
676         &(drc_config->str_p_loc_drc_coefficients_uni_drc[cV0]);
677   } else {
678     *str_p_loc_drc_coefficients_uni_drc = NULL;
679   }
680   return;
681 }
682 
impd_manage_drc_complexity(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc,ia_drc_config * pstr_drc_config)683 WORD32 impd_manage_drc_complexity(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
684                                   ia_drc_config* pstr_drc_config) {
685   WORD32 i, j, err, channel_count;
686   WORD32 numBandsTooLarge = 0;
687   FLOAT32 complexityDrcPrelim;
688   ia_uni_drc_coeffs_struct* str_p_loc_drc_coefficients_uni_drc;
689   FLOAT32 complexitySupportedTotal =
690       (FLOAT32)(pow(2.0f, pstr_drc_uni_sel_proc->compl_level_supported_total));
691   ia_drc_instructions_struct* str_drc_instruction_str;
692   ia_drc_instructions_struct* drc_inst_uni_drc_dependent;
693   ia_drc_sel_proc_output_struct* uni_drc_sel_proc_output =
694       &pstr_drc_uni_sel_proc->uni_drc_sel_proc_output;
695   ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct =
696       &pstr_drc_uni_sel_proc->uni_drc_sel_proc_params;
697 
698   impd_select_drc_coeff3(pstr_drc_config, &str_p_loc_drc_coefficients_uni_drc);
699   if (str_p_loc_drc_coefficients_uni_drc == NULL) return UNEXPECTED_ERROR;
700   for (i = 0; i < pstr_drc_config->drc_instructions_uni_drc_count; i++) {
701     str_drc_instruction_str = &pstr_drc_config->str_drc_instruction_str[i];
702     if (str_drc_instruction_str->no_independent_use) continue;
703 
704     numBandsTooLarge = 0;
705     if (str_drc_instruction_str->drc_apply_to_dwnmix == 1) {
706       channel_count = uni_drc_sel_proc_output->target_channel_count;
707     } else {
708       channel_count = uni_drc_sel_proc_output->base_channel_count;
709     }
710     if (pstr_drc_uni_sel_proc->subband_domain_mode == SUBBAND_DOMAIN_MODE_OFF) {
711       for (j = 0; j < str_drc_instruction_str->num_drc_ch_groups; j++) {
712         ia_gain_set_params_struct* gain_set_params = &(
713             str_p_loc_drc_coefficients_uni_drc->gain_set_params
714                 [str_drc_instruction_str->gain_set_index_for_channel_group[j]]);
715         if (gain_set_params->band_count >
716             pstr_drc_sel_proc_params_struct->num_bands_supported) {
717           numBandsTooLarge = 1;
718         } else {
719           if (gain_set_params->band_count > 4) {
720             /* Add complexity for analysis and synthesis QMF bank here, if
721              * supported */
722           }
723         }
724       }
725     }
726     complexityDrcPrelim =
727         (FLOAT32)(channel_count *
728                   (1 << str_drc_instruction_str->drc_set_complexity_level));
729 
730     if (str_drc_instruction_str->depends_on_drc_set > 0) {
731       err = impd_find_drc_instructions_uni_drc(
732           pstr_drc_config, str_drc_instruction_str->depends_on_drc_set,
733           &drc_inst_uni_drc_dependent);
734       if (err) return (err);
735       if (drc_inst_uni_drc_dependent->drc_apply_to_dwnmix == 1) {
736         channel_count = uni_drc_sel_proc_output->target_channel_count;
737       } else {
738         channel_count = uni_drc_sel_proc_output->base_channel_count;
739       }
740       if (pstr_drc_uni_sel_proc->subband_domain_mode ==
741           SUBBAND_DOMAIN_MODE_OFF) {
742         for (j = 0; j < str_drc_instruction_str->num_drc_ch_groups; j++) {
743           ia_gain_set_params_struct* gain_set_params = &(
744               str_p_loc_drc_coefficients_uni_drc
745                   ->gain_set_params[drc_inst_uni_drc_dependent
746                                         ->gain_set_index_for_channel_group[j]]);
747           if (gain_set_params->band_count >
748               pstr_drc_sel_proc_params_struct->num_bands_supported) {
749             numBandsTooLarge = 1;
750           } else {
751             if (gain_set_params->band_count > 4) {
752               /* Add complexity for analysis and synthesis QMF bank here, if
753                * supported */
754             }
755           }
756         }
757       }
758       complexityDrcPrelim +=
759           channel_count *
760           (1 << drc_inst_uni_drc_dependent->drc_set_complexity_level);
761     }
762 
763     complexityDrcPrelim *= pstr_drc_config->sampling_rate / 48000.0f;
764 
765     if ((complexityDrcPrelim <= complexitySupportedTotal) &&
766         (numBandsTooLarge == 0)) {
767       pstr_drc_uni_sel_proc
768           ->drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id] = 1;
769     }
770   }
771   return (0);
772 }
773 
impd_manage_eq_complexity(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc,ia_drc_config * pstr_drc_config)774 WORD32 impd_manage_eq_complexity(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
775                                  ia_drc_config* pstr_drc_config) {
776   WORD32 k, n, m, err;
777   WORD32 eqComplexityPrimary = 0;
778   WORD32 eqComplexityDependent = 0;
779   WORD32 eqChannelCountPrimary = 0, eqChannelCountDependent = 0;
780   FLOAT32 complexityTotalEq;
781   ia_drc_config* drc_config = &pstr_drc_uni_sel_proc->drc_config;
782   ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct =
783       &pstr_drc_uni_sel_proc->uni_drc_sel_proc_params;
784   FLOAT32 complexitySupportedTotal =
785       (FLOAT32)(pow(2.0f, pstr_drc_uni_sel_proc->compl_level_supported_total));
786 
787   for (n = 0; n < drc_config->str_drc_config_ext.eq_instructions_count; n++) {
788     ia_eq_instructions_struct* str_eq_instructions =
789         &pstr_drc_config->str_drc_config_ext.str_eq_instructions[n];
790 
791     eqChannelCountPrimary = pstr_drc_sel_proc_params_struct->base_channel_count;
792     eqChannelCountDependent =
793         pstr_drc_sel_proc_params_struct->base_channel_count;
794 
795     eqComplexityPrimary = 1 << str_eq_instructions->eq_set_complexity_level;
796     if (pstr_drc_uni_sel_proc->subband_domain_mode == SUBBAND_DOMAIN_MODE_OFF) {
797       if (str_eq_instructions->td_filter_cascade_present == 0) {
798         eqComplexityPrimary = 0;
799       }
800     } else {
801       if (str_eq_instructions->td_filter_cascade_present == 1) {
802         eqComplexityPrimary = (WORD32)2.5f;
803       }
804     }
805     if (str_eq_instructions->eq_apply_to_downmix == 1) {
806       if (str_eq_instructions->downmix_id[0] == ID_FOR_ANY_DOWNMIX) {
807         eqChannelCountPrimary =
808             pstr_drc_sel_proc_params_struct->target_ch_count_prelim;
809       } else {
810         for (k = 0; k < pstr_drc_config->dwnmix_instructions_count; k++) {
811           for (m = 0; m < str_eq_instructions->dwnmix_id_count; m++) {
812             if (pstr_drc_config->dwnmix_instructions[k].downmix_id ==
813                 str_eq_instructions->downmix_id[m]) {
814               if (eqChannelCountPrimary >
815                   pstr_drc_config->dwnmix_instructions[k]
816                       .target_channel_count) {
817                 eqChannelCountPrimary = pstr_drc_config->dwnmix_instructions[k]
818                                             .target_channel_count;
819               }
820             }
821           }
822         }
823       }
824     }
825     complexityTotalEq = (FLOAT32)(eqChannelCountPrimary * eqComplexityPrimary);
826 
827     if (str_eq_instructions->depends_on_eq_set_present > 0) {
828       ia_eq_instructions_struct* eq_instructionsDependent;
829       err = impd_find_eq_instructions(drc_config,
830                                       str_eq_instructions->depends_on_eq_set,
831                                       &eq_instructionsDependent);
832       if (err) return (err);
833       eqComplexityDependent =
834           1 << eq_instructionsDependent->eq_set_complexity_level;
835       if (pstr_drc_uni_sel_proc->subband_domain_mode ==
836           SUBBAND_DOMAIN_MODE_OFF) {
837         if (str_eq_instructions->td_filter_cascade_present == 0) {
838           eqComplexityDependent = 0;
839         }
840       } else {
841         if (str_eq_instructions->td_filter_cascade_present == 1) {
842           eqComplexityDependent = (WORD32)2.5f;
843         }
844       }
845       if (eq_instructionsDependent->eq_apply_to_downmix == 1) {
846         if (eq_instructionsDependent->downmix_id[0] == ID_FOR_ANY_DOWNMIX) {
847           eqChannelCountDependent =
848               pstr_drc_sel_proc_params_struct->target_ch_count_prelim;
849         } else {
850           for (k = 0; k < pstr_drc_config->dwnmix_instructions_count; k++) {
851             for (m = 0; m < str_eq_instructions->dwnmix_id_count; m++) {
852               if (pstr_drc_config->dwnmix_instructions[k].downmix_id ==
853                   eq_instructionsDependent->downmix_id[m]) {
854                 if (eqChannelCountDependent >
855                     pstr_drc_config->dwnmix_instructions[k]
856                         .target_channel_count) {
857                   eqChannelCountDependent =
858                       pstr_drc_config->dwnmix_instructions[k]
859                           .target_channel_count;
860                 }
861               }
862             }
863           }
864         }
865       }
866       complexityTotalEq += eqChannelCountDependent * eqComplexityDependent;
867     }
868 
869     pstr_drc_uni_sel_proc
870         ->eq_set_id_valid_flag[str_eq_instructions->eq_set_id] = 0;
871     complexityTotalEq *= pstr_drc_config->sampling_rate / 48000.0f;
872 
873     if (complexityTotalEq <= complexitySupportedTotal) {
874       pstr_drc_uni_sel_proc
875           ->eq_set_id_valid_flag[str_eq_instructions->eq_set_id] = 1;
876     }
877   }
878   return 0;
879 }
880 
impd_manage_complexity(ia_drc_sel_pro_struct * pstr_drc_uni_sel_proc,ia_drc_config * pstr_drc_config,WORD32 * repeat_selection)881 WORD32 impd_manage_complexity(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
882                               ia_drc_config* pstr_drc_config,
883                               WORD32* repeat_selection) {
884   WORD32 i, j, p, err;
885   WORD32 channel_count;
886   WORD32 numBandsTooLarge = 0;
887   WORD32 drcRequiresEq;
888   FLOAT32 complexityEq;
889   FLOAT32 complexityDrcTotal = 0.0f;
890   FLOAT32 complexityEqTotal = 0.0f;
891   FLOAT32 freqNorm = pstr_drc_config->sampling_rate / 48000.0f;
892   ia_uni_drc_coeffs_struct* str_p_loc_drc_coefficients_uni_drc;
893   ia_drc_instructions_struct* str_drc_instruction_str =
894       &pstr_drc_config->str_drc_instruction_str[0];
895   ia_drc_sel_proc_output_struct* uni_drc_sel_proc_output =
896       &pstr_drc_uni_sel_proc->uni_drc_sel_proc_output;
897   ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct =
898       &pstr_drc_uni_sel_proc->uni_drc_sel_proc_params;
899   FLOAT32 complexitySupportedTotal =
900       (FLOAT32)(pow(2.0f, pstr_drc_uni_sel_proc->compl_level_supported_total));
901 
902   impd_select_drc_coeff3(pstr_drc_config, &str_p_loc_drc_coefficients_uni_drc);
903 
904   if (str_p_loc_drc_coefficients_uni_drc == NULL) return UNEXPECTED_ERROR;
905 
906   for (p = 0; p < 4; p++) {
907     if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[p] <= 0)
908       continue;
909     err = impd_find_drc_instructions_uni_drc(
910         pstr_drc_config,
911         pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[p],
912         &str_drc_instruction_str);
913     if (err) return (err);
914 
915     if (str_drc_instruction_str->drc_apply_to_dwnmix == 1) {
916       channel_count = uni_drc_sel_proc_output->target_channel_count;
917     } else {
918       channel_count = uni_drc_sel_proc_output->base_channel_count;
919     }
920     if (pstr_drc_uni_sel_proc->subband_domain_mode == SUBBAND_DOMAIN_MODE_OFF) {
921       for (j = 0; j < str_drc_instruction_str->num_drc_ch_groups; j++) {
922         ia_gain_set_params_struct* gain_set_params = &(
923             str_p_loc_drc_coefficients_uni_drc->gain_set_params
924                 [str_drc_instruction_str->gain_set_index_for_channel_group[j]]);
925         if (gain_set_params->band_count >
926             pstr_drc_sel_proc_params_struct->num_bands_supported) {
927           if (p < 2) {
928             numBandsTooLarge = 1;
929           } else {
930             pstr_drc_uni_sel_proc
931                 ->drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id] =
932                 0;
933             pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[p] =
934                 0;
935           }
936         } else {
937           if (gain_set_params->band_count > 4) {
938             /* Add complexity for analysis and synthesis QMF bank here, if
939              * supported */
940           }
941         }
942       }
943     }
944     complexityDrcTotal +=
945         channel_count *
946         (1 << str_drc_instruction_str->drc_set_complexity_level);
947   }
948 
949   if (uni_drc_sel_proc_output->active_downmix_id > 0) {
950     FLOAT32 complexityPerCoeff;
951     ia_downmix_instructions_struct* dwnmix_instructions;
952 
953     if (pstr_drc_uni_sel_proc->subband_domain_mode == SUBBAND_DOMAIN_MODE_OFF) {
954       complexityPerCoeff = 1.0f;
955     } else {
956       complexityPerCoeff = 2.0f;
957     }
958     impd_find_downmix(pstr_drc_config,
959                       uni_drc_sel_proc_output->active_downmix_id,
960                       &dwnmix_instructions);
961     if (dwnmix_instructions->downmix_coefficients_present == 1) {
962       for (i = 0; i < uni_drc_sel_proc_output->base_channel_count; i++) {
963         for (j = 0; j < uni_drc_sel_proc_output->target_channel_count; j++) {
964           if (uni_drc_sel_proc_output->downmix_matrix[i][j] != 0.0f) {
965             complexityDrcTotal += complexityPerCoeff;
966           }
967         }
968       }
969     } else {
970       /* add standard downmix here */
971     }
972   }
973 
974   for (p = 0; p < 2; p++) {
975     if (pstr_drc_uni_sel_proc->eq_inst_index[p] >= 0) {
976       ia_eq_instructions_struct* str_eq_instructions =
977           &pstr_drc_config->str_drc_config_ext
978                .str_eq_instructions[pstr_drc_uni_sel_proc->eq_inst_index[p]];
979       if (p == 0) {
980         channel_count = uni_drc_sel_proc_output->base_channel_count;
981       } else {
982         channel_count = uni_drc_sel_proc_output->target_channel_count;
983       }
984 
985       complexityEq =
986           (FLOAT32)(1 << str_eq_instructions->eq_set_complexity_level);
987       if (pstr_drc_uni_sel_proc->subband_domain_mode ==
988           SUBBAND_DOMAIN_MODE_OFF) {
989         if (str_eq_instructions->td_filter_cascade_present == 0) {
990           complexityEq = 0.0;
991         }
992       } else {
993         if (str_eq_instructions->td_filter_cascade_present == 1) {
994           complexityEq = 2.5;
995         }
996       }
997 
998       complexityEqTotal += channel_count * complexityEq;
999     }
1000   }
1001 
1002   complexityDrcTotal *= freqNorm;
1003   complexityEqTotal *= freqNorm;
1004 
1005   if (numBandsTooLarge == 1) {
1006     if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[0] > 0) {
1007       err = impd_find_drc_instructions_uni_drc(
1008           pstr_drc_config,
1009           pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[0],
1010           &str_drc_instruction_str);
1011       if (err) return (err);
1012 
1013       pstr_drc_uni_sel_proc
1014           ->drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id] = 0;
1015     }
1016     *repeat_selection = 1;
1017   } else {
1018     if (complexityDrcTotal + complexityEqTotal <= complexitySupportedTotal) {
1019       *repeat_selection = 0;
1020     } else {
1021       drcRequiresEq = 0;
1022       for (p = 0; p < 2; p++) {
1023         if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[p] <=
1024             0)
1025           continue;
1026         err = impd_find_drc_instructions_uni_drc(
1027             pstr_drc_config,
1028             pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[p],
1029             &str_drc_instruction_str);
1030         if (err) return (err);
1031         if (str_drc_instruction_str->requires_eq == 1) {
1032           drcRequiresEq = 1;
1033         }
1034       }
1035       if ((drcRequiresEq == 0) &&
1036           (complexityDrcTotal <= complexitySupportedTotal)) {
1037         for (p = 0; p < 2; p++) {
1038           pstr_drc_uni_sel_proc->eq_inst_index[p] = 0;
1039         }
1040         *repeat_selection = 0;
1041       } else {
1042         if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[0] >
1043             0) {
1044           err = impd_find_drc_instructions_uni_drc(
1045               pstr_drc_config,
1046               pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[0],
1047               &str_drc_instruction_str);
1048           if (err) return (err);
1049 
1050           pstr_drc_uni_sel_proc
1051               ->drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id] = 0;
1052         } else {
1053           for (p = 2; p < 4; p++) {
1054             pstr_drc_uni_sel_proc
1055                 ->drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id] =
1056                 0;
1057             pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[p] =
1058                 0;
1059           }
1060         }
1061         *repeat_selection = 1;
1062       }
1063     }
1064   }
1065 
1066   if (*repeat_selection == 1) {
1067     memset(&pstr_drc_uni_sel_proc->uni_drc_sel_proc_output, 0,
1068            sizeof(ia_drc_sel_proc_output_struct));
1069   }
1070   return (0);
1071 }
1072 
impd_find_loud_eq_instructions_idx_for_id(ia_drc_config * drc_config,WORD32 loud_eq_set_id_requested,WORD32 * instructions_idx)1073 WORD32 impd_find_loud_eq_instructions_idx_for_id(
1074     ia_drc_config* drc_config, WORD32 loud_eq_set_id_requested,
1075     WORD32* instructions_idx) {
1076   WORD32 i;
1077   if (loud_eq_set_id_requested > 0) {
1078     for (i = 0; i < drc_config->str_drc_config_ext.loud_eq_instructions_count;
1079          i++) {
1080       if (drc_config->str_drc_config_ext.loud_eq_instructions[i]
1081               .loud_eq_set_id == loud_eq_set_id_requested)
1082         break;
1083     }
1084     if (i == drc_config->str_drc_config_ext.loud_eq_instructions_count) {
1085       return (UNEXPECTED_ERROR);
1086     }
1087     *instructions_idx = i;
1088   } else {
1089     *instructions_idx = -1;
1090   }
1091   return (0);
1092 }
1093 
impd_find_eq_instructions(ia_drc_config * drc_config,WORD32 eq_set_id_requested,ia_eq_instructions_struct ** str_eq_instructions)1094 WORD32 impd_find_eq_instructions(
1095     ia_drc_config* drc_config, WORD32 eq_set_id_requested,
1096     ia_eq_instructions_struct** str_eq_instructions) {
1097   WORD32 i;
1098   for (i = 0; i < drc_config->str_drc_config_ext.eq_instructions_count; i++) {
1099     if (eq_set_id_requested ==
1100         drc_config->str_drc_config_ext.str_eq_instructions[i].eq_set_id)
1101       break;
1102   }
1103   if (i == drc_config->str_drc_config_ext.eq_instructions_count) {
1104     return (UNEXPECTED_ERROR);
1105   }
1106   *str_eq_instructions = &drc_config->str_drc_config_ext.str_eq_instructions[i];
1107   return (0);
1108 }
1109 
impd_find_downmix(ia_drc_config * drc_config,WORD32 requested_dwnmix_id,ia_downmix_instructions_struct ** dwnmix_instructions)1110 WORD32 impd_find_downmix(ia_drc_config* drc_config, WORD32 requested_dwnmix_id,
1111                          ia_downmix_instructions_struct** dwnmix_instructions) {
1112   WORD32 i;
1113   for (i = 0; i < drc_config->dwnmix_instructions_count; i++) {
1114     if (requested_dwnmix_id == drc_config->dwnmix_instructions[i].downmix_id)
1115       break;
1116   }
1117   if (i == drc_config->dwnmix_instructions_count) {
1118     return (UNEXPECTED_ERROR);
1119   }
1120   *dwnmix_instructions = &drc_config->dwnmix_instructions[i];
1121   return (0);
1122 }
1123