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