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