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