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