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 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 if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
309 memcpy(&selection_candidate_info_step_2[k], &selection_candidate_info[i],
310 sizeof(ia_selection_candidate_info_struct));
311 k++;
312 }
313 }
314 selection_candidate_step_2_count = k;
315
316 if (selection_candidate_step_2_count > 0) {
317 *match_found_flag = 1;
318 for (i = 0; i < selection_candidate_step_2_count; i++) {
319 memcpy(&selection_candidate_info[i], &selection_candidate_info_step_2[i],
320 sizeof(ia_selection_candidate_info_struct));
321 *selection_candidate_count = selection_candidate_step_2_count;
322 }
323 } else {
324 *match_found_flag = 0;
325 }
326
327 return (0);
328 }
329
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)330 WORD32 impd_match_effect_type_attempt(
331 ia_drc_config* pstr_drc_config, WORD32 requested_effect_type,
332 WORD32 state_requested, WORD32* match_found_flag,
333 WORD32* selection_candidate_count,
334 ia_selection_candidate_info_struct* selection_candidate_info) {
335 WORD32 i, k, err;
336 WORD32 selection_candidate_step_2_count = 0;
337 ia_selection_candidate_info_struct
338 selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
339 ia_drc_instructions_struct* str_drc_instruction_str;
340 ia_drc_instructions_struct* drc_instructions_dependent;
341 WORD32 effect_bit_idx;
342
343 err =
344 impd_map_requested_effect_bit_idx(requested_effect_type, &effect_bit_idx);
345 if (err) return (err);
346
347 if (effect_bit_idx == EFFECT_BIT_NONE) {
348 err = impd_select_drcs_without_compr_effects(
349 pstr_drc_config, match_found_flag, selection_candidate_count,
350 selection_candidate_info);
351 if (err) return (err);
352 } else {
353 k = 0;
354 for (i = 0; i < *selection_candidate_count; i++) {
355 str_drc_instruction_str =
356 &(pstr_drc_config->str_drc_instruction_str
357 [selection_candidate_info[i].drc_instructions_index]);
358 if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
359 err = impd_get_dependent_drc_instructions(pstr_drc_config,
360 str_drc_instruction_str,
361 &drc_instructions_dependent);
362 if (err) return (err);
363
364 if (state_requested == 1) {
365 if (((str_drc_instruction_str->drc_set_effect & effect_bit_idx) !=
366 0x0) ||
367 ((drc_instructions_dependent->drc_set_effect & effect_bit_idx) !=
368 0x0)) {
369 if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
370 memcpy(&selection_candidate_info_step_2[k],
371 &selection_candidate_info[i],
372 sizeof(ia_selection_candidate_info_struct));
373 k++;
374 }
375 } else {
376 if (((str_drc_instruction_str->drc_set_effect & effect_bit_idx) ==
377 0x0) &&
378 ((drc_instructions_dependent->drc_set_effect & effect_bit_idx) ==
379 0x0)) {
380 if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
381 memcpy(&selection_candidate_info_step_2[k],
382 &selection_candidate_info[i],
383 sizeof(ia_selection_candidate_info_struct));
384 k++;
385 }
386 }
387 } else {
388 if (state_requested == 1) {
389 if ((str_drc_instruction_str->drc_set_effect & effect_bit_idx) !=
390 0x0) {
391 if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
392 memcpy(&selection_candidate_info_step_2[k],
393 &selection_candidate_info[i],
394 sizeof(ia_selection_candidate_info_struct));
395 k++;
396 }
397 } else {
398 if ((str_drc_instruction_str->drc_set_effect & effect_bit_idx) ==
399 0x0) {
400 if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
401 memcpy(&selection_candidate_info_step_2[k],
402 &selection_candidate_info[i],
403 sizeof(ia_selection_candidate_info_struct));
404 k++;
405 }
406 }
407 }
408 }
409 selection_candidate_step_2_count = k;
410
411 if (selection_candidate_step_2_count > 0) {
412 *match_found_flag = 1;
413 for (i = 0; i < selection_candidate_step_2_count; i++) {
414 *selection_candidate_count = selection_candidate_step_2_count;
415 memcpy(&selection_candidate_info[i],
416 &selection_candidate_info_step_2[i],
417 sizeof(ia_selection_candidate_info_struct));
418 }
419 } else {
420 *match_found_flag = 0;
421 }
422 }
423 return (0);
424 }
425
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)426 WORD32 impd_match_effect_types(
427 ia_drc_config* pstr_drc_config, WORD32 effect_type_requested_total_count,
428 WORD32 effect_type_requested_desired_count, WORD32* requested_effect_type,
429 WORD32* selection_candidate_count,
430 ia_selection_candidate_info_struct* selection_candidate_info) {
431 WORD32 k, err;
432 WORD32 match_found_flag = 0;
433 WORD32 state_requested;
434 WORD32 desired_effect_type_found, fallback_effect_type_found;
435
436 desired_effect_type_found = 0;
437 fallback_effect_type_found = 0;
438 k = 0;
439 while (k < effect_type_requested_desired_count) {
440 state_requested = 1;
441 err = impd_match_effect_type_attempt(
442 pstr_drc_config, requested_effect_type[k], state_requested,
443 &match_found_flag, selection_candidate_count, selection_candidate_info);
444 if (err) return (err);
445 if (match_found_flag) desired_effect_type_found = 1;
446 k++;
447 }
448 if (desired_effect_type_found == 0) {
449 while ((k < effect_type_requested_total_count) && (match_found_flag == 0)) {
450 state_requested = 1;
451 err = impd_match_effect_type_attempt(
452 pstr_drc_config, requested_effect_type[k], state_requested,
453 &match_found_flag, selection_candidate_count,
454 selection_candidate_info);
455 if (err) return (err);
456 if (match_found_flag) fallback_effect_type_found = 1;
457 k++;
458 }
459 }
460
461 return (0);
462 }
463
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)464 WORD32 impd_match_dynamic_range(
465 ia_drc_config* pstr_drc_config,
466 ia_drc_loudness_info_set_struct* pstr_loudness_info,
467 ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
468 WORD32 num_drc_requests, WORD32* selection_candidate_count,
469 ia_selection_candidate_info_struct* selection_candidate_info) {
470 ia_drc_instructions_struct* str_drc_instruction_str;
471 WORD32 err, i, k;
472 WORD32 lp_avg_present_val;
473 FLOAT32 lp_avg_val;
474 FLOAT32 deviation_min = 1000.0f;
475 WORD32 selected[DRC_INSTRUCTIONS_COUNT_MAX];
476 WORD32 dynamic_range_measurement_type =
477 pstr_drc_sel_proc_params_struct
478 ->requested_dyn_range_measur_type[num_drc_requests];
479
480 WORD32 requested_dyn_range_range_flag =
481 pstr_drc_sel_proc_params_struct
482 ->requested_dyn_range_range_flag[num_drc_requests];
483
484 FLOAT32 dynamic_range_requested =
485 pstr_drc_sel_proc_params_struct
486 ->requested_dyn_range_value[num_drc_requests];
487
488 FLOAT32 dynamic_range_min_requested =
489 pstr_drc_sel_proc_params_struct
490 ->requested_dyn_range_min_val[num_drc_requests];
491
492 FLOAT32 dynamic_range_max_requested =
493 pstr_drc_sel_proc_params_struct
494 ->requested_dyn_range_max_val[num_drc_requests];
495
496 WORD32* requested_dwnmix_id =
497 pstr_drc_sel_proc_params_struct->requested_dwnmix_id;
498
499 WORD32 album_mode = pstr_drc_sel_proc_params_struct->album_mode;
500
501 k = 0;
502 for (i = 0; i < *selection_candidate_count; i++) {
503 str_drc_instruction_str = &(
504 pstr_drc_config->str_drc_instruction_str[selection_candidate_info[i]
505 .drc_instructions_index]);
506
507 err = impd_loudness_peak_to_average_info(
508 pstr_loudness_info, str_drc_instruction_str,
509 requested_dwnmix_id[selection_candidate_info[i]
510 .downmix_id_request_index],
511 dynamic_range_measurement_type, album_mode, &lp_avg_present_val,
512 &lp_avg_val);
513 if (err) return (err);
514
515 if (lp_avg_present_val == 1) {
516 if (requested_dyn_range_range_flag == 1) {
517 if ((lp_avg_val >= dynamic_range_min_requested) &&
518 (lp_avg_val <= dynamic_range_max_requested)) {
519 if (k >= DRC_INSTRUCTIONS_COUNT_MAX) return UNEXPECTED_ERROR;
520 selected[k] = i;
521 k++;
522 }
523 } else {
524 FLOAT32 deviation =
525 (FLOAT32)fabs((FLOAT64)(dynamic_range_requested - lp_avg_val));
526 if (deviation_min >= deviation) {
527 if (deviation_min > deviation) {
528 deviation_min = deviation;
529 k = 0;
530 }
531 if (k >= DRC_INSTRUCTIONS_COUNT_MAX) return UNEXPECTED_ERROR;
532 selected[k] = i;
533 k++;
534 }
535 }
536 }
537 }
538 if (k > 0) {
539 for (i = 0; i < k; i++) {
540 memcpy(&selection_candidate_info[i],
541 &selection_candidate_info[selected[i]],
542 sizeof(ia_selection_candidate_info_struct));
543 }
544 *selection_candidate_count = k;
545 }
546
547 return (0);
548 }
549
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)550 WORD32 impd_match_drc_characteristic_attempt(
551 ia_drc_config* pstr_drc_config, WORD32 requested_drc_characteristic,
552 WORD32* match_found_flag, WORD32* selection_candidate_count,
553 ia_selection_candidate_info_struct* selection_candidate_info) {
554 WORD32 i, k, n, b, m;
555 WORD32 ref_count;
556 WORD32 drc_characteristic;
557 FLOAT32 match_count;
558 WORD32 drc_characteristic_request_1;
559 WORD32 drc_characteristic_request_2;
560 WORD32 drc_characteristic_request_3;
561
562 ia_drc_instructions_struct* str_drc_instruction_str = NULL;
563 ia_uni_drc_coeffs_struct* str_p_loc_drc_coefficients_uni_drc = NULL;
564 ia_gain_set_params_struct* gain_set_params = NULL;
565 *match_found_flag = 0;
566
567 if (requested_drc_characteristic < 1) {
568 return (UNEXPECTED_ERROR);
569 }
570 if (requested_drc_characteristic < 12) {
571 drc_characteristic_request_1 =
572 drc_characteristic_order_default[requested_drc_characteristic - 1][0];
573 drc_characteristic_request_2 =
574 drc_characteristic_order_default[requested_drc_characteristic - 1][1];
575 drc_characteristic_request_3 =
576 drc_characteristic_order_default[requested_drc_characteristic - 1][2];
577 } else {
578 drc_characteristic_request_1 = requested_drc_characteristic;
579 drc_characteristic_request_2 = -1;
580 drc_characteristic_request_3 = -1;
581 }
582
583 if (pstr_drc_config->drc_coefficients_drc_count) {
584 for (i = 0; i < pstr_drc_config->drc_coefficients_drc_count; i++) {
585 str_p_loc_drc_coefficients_uni_drc =
586 &(pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[i]);
587 if (str_p_loc_drc_coefficients_uni_drc->drc_location == LOCATION_SELECTED)
588 break;
589 }
590
591 if (i == pstr_drc_config->drc_coefficients_drc_count) {
592 return (UNEXPECTED_ERROR);
593 }
594 }
595
596 n = 0;
597 for (i = 0; i < *selection_candidate_count; i++) {
598 ref_count = 0;
599 match_count = 0;
600
601 str_drc_instruction_str = &(
602 pstr_drc_config->str_drc_instruction_str[selection_candidate_info[i]
603 .drc_instructions_index]);
604 for (k = 0; k < str_drc_instruction_str->num_drc_ch_groups; k++) {
605 gain_set_params =
606 &(str_p_loc_drc_coefficients_uni_drc->gain_set_params
607 [str_drc_instruction_str->gain_set_index_for_channel_group[k]]);
608 for (b = 0; b < gain_set_params->band_count; b++) {
609 ref_count++;
610 drc_characteristic = gain_set_params->gain_params[b].drc_characteristic;
611 if (drc_characteristic == drc_characteristic_request_1)
612 match_count += 1.0f;
613 else if (drc_characteristic == drc_characteristic_request_2)
614 match_count += 0.75f;
615 else if (drc_characteristic == drc_characteristic_request_3)
616 match_count += 0.5f;
617 }
618 }
619 if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
620 WORD32 depends_on_drc_set = str_drc_instruction_str->depends_on_drc_set;
621 for (m = 0; m < pstr_drc_config->drc_instructions_uni_drc_count; m++) {
622 if (pstr_drc_config->str_drc_instruction_str[m].drc_set_id ==
623 depends_on_drc_set)
624 break;
625 }
626 if (m == pstr_drc_config->drc_instructions_uni_drc_count) {
627 return (UNEXPECTED_ERROR);
628 }
629 str_drc_instruction_str = &(pstr_drc_config->str_drc_instruction_str[m]);
630 if ((str_drc_instruction_str->drc_set_effect &
631 (EFFECT_BIT_FADE | EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) ==
632 0) {
633 if (str_drc_instruction_str->drc_set_effect != EFFECT_BIT_CLIPPING) {
634 for (k = 0; k < str_drc_instruction_str->num_drc_ch_groups; k++) {
635 gain_set_params =
636 &(str_p_loc_drc_coefficients_uni_drc->gain_set_params
637 [str_drc_instruction_str
638 ->gain_set_index_for_channel_group[k]]);
639 for (b = 0; b < gain_set_params->band_count; b++) {
640 ref_count++;
641 drc_characteristic =
642 gain_set_params->gain_params[b].drc_characteristic;
643 if (drc_characteristic == drc_characteristic_request_1)
644 match_count += 1.0f;
645 else if (drc_characteristic == drc_characteristic_request_2)
646 match_count += 0.75f;
647 else if (drc_characteristic == drc_characteristic_request_3)
648 match_count += 0.5;
649 }
650 }
651 }
652 }
653 }
654 if ((ref_count > 0) && (((FLOAT32)match_count) > 0.5f * ref_count)) {
655 if (n >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
656 memcpy(&selection_candidate_info[n], &selection_candidate_info[i],
657 sizeof(ia_selection_candidate_info_struct));
658 n++;
659 }
660 }
661 if (n > 0) {
662 *selection_candidate_count = n;
663 *match_found_flag = 1;
664 }
665
666 return (0);
667 }
668
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)669 WORD32 impd_match_drc_characteristic(
670 ia_drc_config* pstr_drc_config, WORD32 requested_drc_characteristic,
671 WORD32* selection_candidate_count,
672 ia_selection_candidate_info_struct* selection_candidate_info) {
673 WORD32 k, err;
674 WORD32 match_found_flag = 0;
675
676 const WORD32* drc_characteristic_order =
677 drc_characteristic_order_default[requested_drc_characteristic - 1];
678 const WORD32 drc_characteristic_order_count =
679 sizeof(drc_characteristic_order_default[requested_drc_characteristic]) /
680 sizeof(WORD32);
681 k = 0;
682 while ((k < drc_characteristic_order_count) && (match_found_flag == 0) &&
683 (drc_characteristic_order[k] > 0)) {
684 err = impd_match_drc_characteristic_attempt(
685 pstr_drc_config, drc_characteristic_order[k], &match_found_flag,
686 selection_candidate_count, selection_candidate_info);
687 if (err) return (err);
688 k++;
689 }
690 return (0);
691 }
692
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)693 WORD32 impd_drc_set_preselection(
694 ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
695 ia_drc_config* pstr_drc_config,
696 ia_drc_loudness_info_set_struct* pstr_loudness_info,
697 WORD32 restrict_to_drc_with_album_loudness,
698 ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
699 WORD32* selection_candidate_count,
700 ia_selection_candidate_info_struct* selection_candidate_info) {
701 WORD32 i, j, k, l, d, n, err;
702 WORD32 downmix_id_match = 0;
703
704 WORD32 selection_candidate_step_2_count;
705 ia_selection_candidate_info_struct
706 selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
707
708 WORD32 num_downmix_id_requests =
709 pstr_drc_sel_proc_params_struct->num_downmix_id_requests;
710 WORD32* requested_dwnmix_id =
711 pstr_drc_sel_proc_params_struct->requested_dwnmix_id;
712 FLOAT32 output_peak_level_max =
713 pstr_drc_sel_proc_params_struct->output_peak_level_max;
714 WORD32 loudness_deviation_max =
715 pstr_drc_sel_proc_params_struct->loudness_deviation_max;
716 WORD32* drc_set_id_valid_flag = pstr_drc_uni_sel_proc->drc_set_id_valid_flag;
717 WORD32* eq_set_id_valid_flag = pstr_drc_uni_sel_proc->eq_set_id_valid_flag;
718
719 FLOAT32 output_peak_level_min = 1000.0f;
720 FLOAT32 adjustment;
721 WORD32 loudness_drc_set_id_requested;
722
723 WORD32 num_compression_eq_count = 0;
724 WORD32 num_compression_eq_id[16];
725
726 WORD32 loudness_info_count = 0;
727 WORD32 eq_set_id_loudness[16];
728 FLOAT32 loudness_normalization_gain_db[16];
729 FLOAT32 loudness[16];
730 WORD32 peak_info_count;
731 WORD32 eq_set_id_Peak[16];
732 FLOAT32 signal_peak_level[16];
733 WORD32 explicit_peak_information_present[16];
734
735 ia_uni_drc_coeffs_struct* str_p_loc_drc_coefficients_uni_drc = NULL;
736 ia_drc_instructions_struct* str_drc_instruction_str = NULL;
737
738 impd_select_drc_coeff3(pstr_drc_config, &str_p_loc_drc_coefficients_uni_drc);
739 if (str_p_loc_drc_coefficients_uni_drc == NULL) return UNEXPECTED_ERROR;
740 k = 0;
741 for (d = 0; d < num_downmix_id_requests; d++) {
742 err = impd_find_eq_set_no_compression(
743 pstr_drc_config, requested_dwnmix_id[d], &num_compression_eq_count,
744 num_compression_eq_id);
745 if (err) return (err);
746 for (i = 0; i < pstr_drc_config->drc_instructions_count_plus; i++) {
747 downmix_id_match = 0;
748 str_drc_instruction_str = &(pstr_drc_config->str_drc_instruction_str[i]);
749
750 for (j = 0; j < str_drc_instruction_str->dwnmix_id_count; j++) {
751 if ((str_drc_instruction_str->downmix_id[j] ==
752 requested_dwnmix_id[d]) ||
753 ((str_drc_instruction_str->downmix_id[j] == ID_FOR_BASE_LAYOUT) &&
754 (str_drc_instruction_str->drc_set_id > 0)) ||
755 (str_drc_instruction_str->downmix_id[j] == ID_FOR_ANY_DOWNMIX)) {
756 downmix_id_match = 1;
757 }
758 }
759 if (downmix_id_match == 1) {
760 if (pstr_drc_sel_proc_params_struct->dynamic_range_control_on == 1) {
761 if ((str_drc_instruction_str->drc_set_effect != EFFECT_BIT_FADE) &&
762 (str_drc_instruction_str->drc_set_effect !=
763 EFFECT_BIT_DUCK_OTHER) &&
764 (str_drc_instruction_str->drc_set_effect !=
765 EFFECT_BIT_DUCK_SELF) &&
766 (str_drc_instruction_str->drc_set_effect != 0 ||
767 str_drc_instruction_str->drc_set_id < 0) &&
768 (((str_drc_instruction_str->depends_on_drc_set_present == 0) &&
769 (str_drc_instruction_str->no_independent_use == 0)) ||
770 (str_drc_instruction_str->depends_on_drc_set_present == 1))) {
771 WORD32 drc_is_permitted = 1;
772 if (str_drc_instruction_str->drc_set_id > 0) {
773 drc_is_permitted =
774 drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id];
775 }
776 if (drc_is_permitted == 1) {
777 err = impd_init_loudness_control(
778 pstr_drc_sel_proc_params_struct, pstr_loudness_info,
779 requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
780
781 num_compression_eq_count, num_compression_eq_id,
782 &loudness_info_count, eq_set_id_loudness,
783 loudness_normalization_gain_db, loudness);
784 if (err) return (err);
785
786 if (loudness_info_count > MAX_LOUDNESS_INFO_COUNT)
787 return UNEXPECTED_ERROR;
788
789 impd_signal_peak_level_info(
790 pstr_drc_config, pstr_loudness_info, str_drc_instruction_str,
791 requested_dwnmix_id[d],
792 pstr_drc_sel_proc_params_struct->album_mode,
793 num_compression_eq_count, num_compression_eq_id,
794 &peak_info_count, eq_set_id_Peak, signal_peak_level,
795 explicit_peak_information_present);
796
797 for (l = 0; l < loudness_info_count; l++) {
798 WORD32 match_found_flag = 0;
799 WORD32 p;
800 if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
801 selection_candidate_info[k].loudness_norm_db_gain_adjusted =
802 loudness_normalization_gain_db[l];
803
804 selection_candidate_info[k]
805 .loudness_norm_db_gain_adjusted = min(
806 selection_candidate_info[k].loudness_norm_db_gain_adjusted,
807 pstr_drc_sel_proc_params_struct->loudness_norm_gain_db_max);
808
809 if (loudness[l] != UNDEFINED_LOUDNESS_VALUE) {
810 selection_candidate_info[k].output_loudness =
811 loudness[l] +
812 selection_candidate_info[k]
813 .loudness_norm_db_gain_adjusted;
814 } else {
815 selection_candidate_info[k].output_loudness =
816 UNDEFINED_LOUDNESS_VALUE;
817 }
818
819 for (p = 0; p < peak_info_count; p++) {
820 if (eq_set_id_Peak[p] == eq_set_id_loudness[l]) {
821 if (eq_set_id_valid_flag[eq_set_id_Peak[p]] == 1)
822
823 {
824 match_found_flag = 1;
825 break;
826 }
827 }
828 }
829 if (match_found_flag == 1) {
830 selection_candidate_info[k].output_peak_level =
831 signal_peak_level[p] +
832 selection_candidate_info[k]
833 .loudness_norm_db_gain_adjusted;
834 } else {
835 selection_candidate_info[k].output_peak_level =
836 selection_candidate_info[k]
837 .loudness_norm_db_gain_adjusted;
838 }
839 if ((str_drc_instruction_str->requires_eq == 1) &&
840 (eq_set_id_valid_flag[eq_set_id_loudness[l]] == 0))
841 continue;
842 selection_candidate_info[k].drc_instructions_index = i;
843 selection_candidate_info[k].downmix_id_request_index = d;
844 selection_candidate_info[k].eq_set_id = eq_set_id_loudness[l];
845 if (explicit_peak_information_present[p] == 1) {
846 selection_candidate_info[k].selection_flags =
847 SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT;
848 } else {
849 selection_candidate_info[k].selection_flags = 0;
850 }
851 impd_mixing_level_info(
852 pstr_drc_sel_proc_params_struct, pstr_loudness_info,
853 requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
854 eq_set_id_loudness[l],
855 &selection_candidate_info[k].mixing_level);
856 if (str_drc_instruction_str->drc_set_target_loudness_present &&
857 ((pstr_drc_sel_proc_params_struct
858 ->loudness_normalization_on &&
859 str_drc_instruction_str
860 ->drc_set_target_loudness_value_upper >=
861 pstr_drc_sel_proc_params_struct->target_loudness &&
862 str_drc_instruction_str
863 ->drc_set_target_loudness_value_lower <
864 pstr_drc_sel_proc_params_struct->target_loudness) ||
865 !pstr_drc_sel_proc_params_struct
866 ->loudness_normalization_on)) {
867 selection_candidate_info[k].selection_flags |=
868 SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH;
869 if (!explicit_peak_information_present[p]) {
870 if (pstr_drc_sel_proc_params_struct
871 ->loudness_normalization_on) {
872 selection_candidate_info[k].output_peak_level =
873 pstr_drc_sel_proc_params_struct->target_loudness -
874 str_drc_instruction_str
875 ->drc_set_target_loudness_value_upper;
876 } else {
877 selection_candidate_info[k].output_peak_level = 0.0f;
878 }
879 }
880 }
881 if ((selection_candidate_info[k].selection_flags &
882 (SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH |
883 SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT) ||
884 !str_drc_instruction_str
885 ->drc_set_target_loudness_present)) {
886 k++;
887 }
888 }
889 }
890 }
891 } else {
892 if (str_drc_instruction_str->drc_set_id < 0) {
893 err = impd_init_loudness_control(
894 pstr_drc_sel_proc_params_struct, pstr_loudness_info,
895 requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
896 num_compression_eq_count, num_compression_eq_id,
897 &loudness_info_count, eq_set_id_loudness,
898 loudness_normalization_gain_db, loudness);
899 if (err) return (err);
900
901 impd_signal_peak_level_info(
902 pstr_drc_config, pstr_loudness_info, str_drc_instruction_str,
903 requested_dwnmix_id[d],
904 pstr_drc_sel_proc_params_struct->album_mode,
905 num_compression_eq_count, num_compression_eq_id,
906 &peak_info_count, eq_set_id_Peak, signal_peak_level,
907 explicit_peak_information_present);
908 for (l = 0; l < loudness_info_count; l++) {
909 WORD32 match_found_flag = 0;
910 WORD32 p;
911 if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
912 for (p = 0; p < peak_info_count; p++) {
913 if (eq_set_id_Peak[p] == eq_set_id_loudness[l]) {
914 if (eq_set_id_valid_flag[eq_set_id_Peak[p]] == 1) {
915 match_found_flag = 1;
916 break;
917 }
918 }
919 }
920 if (match_found_flag == 1) {
921 adjustment = max(
922 0.0f,
923 signal_peak_level[p] + loudness_normalization_gain_db[l] -
924 pstr_drc_sel_proc_params_struct->output_peak_level_max);
925 adjustment = min(adjustment, max(0.0f, loudness_deviation_max));
926 selection_candidate_info[k].loudness_norm_db_gain_adjusted =
927 loudness_normalization_gain_db[l] - adjustment;
928
929 selection_candidate_info[k]
930 .loudness_norm_db_gain_adjusted = min(
931 selection_candidate_info[k].loudness_norm_db_gain_adjusted,
932 pstr_drc_sel_proc_params_struct->loudness_norm_gain_db_max);
933
934 selection_candidate_info[k].output_peak_level =
935 signal_peak_level[p] +
936 selection_candidate_info[k].loudness_norm_db_gain_adjusted;
937 if (loudness[l] != UNDEFINED_LOUDNESS_VALUE) {
938 selection_candidate_info[k].output_loudness =
939 loudness[l] +
940 selection_candidate_info[k]
941 .loudness_norm_db_gain_adjusted;
942 } else {
943 selection_candidate_info[k].output_loudness =
944 UNDEFINED_LOUDNESS_VALUE;
945 }
946 selection_candidate_info[k].drc_instructions_index = i;
947 selection_candidate_info[k].downmix_id_request_index = d;
948 selection_candidate_info[k].eq_set_id = eq_set_id_loudness[l];
949 if (explicit_peak_information_present[p] == 1) {
950 selection_candidate_info[k].selection_flags =
951 SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT;
952 } else {
953 selection_candidate_info[k].selection_flags = 0;
954 }
955 impd_mixing_level_info(
956 pstr_drc_sel_proc_params_struct, pstr_loudness_info,
957 requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
958 eq_set_id_loudness[l],
959 &selection_candidate_info[k].mixing_level);
960 k++;
961 }
962 }
963 }
964 }
965 }
966 }
967 }
968 if (k > SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
969 *selection_candidate_count = k;
970 if (pstr_drc_sel_proc_params_struct->dynamic_range_control_on == 1) {
971 n = 0;
972 for (k = 0; k < *selection_candidate_count; k++) {
973 str_drc_instruction_str =
974 &(pstr_drc_config->str_drc_instruction_str
975 [selection_candidate_info[k].drc_instructions_index]);
976
977 if (pstr_drc_sel_proc_params_struct->eq_set_purpose_request !=
978 EQ_PURPOSE_EQ_OFF) {
979 WORD32 matching_eq_set_count = 0;
980 WORD32 matching_eq_instrucions_index[64];
981 err = impd_match_eq_set(
982 pstr_drc_config, requested_dwnmix_id[selection_candidate_info[k]
983 .downmix_id_request_index],
984 str_drc_instruction_str->drc_set_id, eq_set_id_valid_flag,
985 &matching_eq_set_count, matching_eq_instrucions_index);
986 if (err) return (err);
987 for (j = 0; j < matching_eq_set_count; j++) {
988 if (n >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
989 memcpy(&selection_candidate_info_step_2[n],
990 &selection_candidate_info[k],
991 sizeof(ia_selection_candidate_info_struct));
992 selection_candidate_info_step_2[n].eq_set_id =
993 pstr_drc_config->str_drc_config_ext
994 .str_eq_instructions[matching_eq_instrucions_index[j]]
995 .eq_set_id;
996 n++;
997 }
998 }
999 if (str_drc_instruction_str->requires_eq == 0) {
1000 if (n >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
1001 memcpy(&selection_candidate_info_step_2[n],
1002 &selection_candidate_info[k],
1003 sizeof(ia_selection_candidate_info_struct));
1004 selection_candidate_info_step_2[n].eq_set_id = 0;
1005 n++;
1006 }
1007 }
1008 if (n > SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
1009 memcpy(selection_candidate_info, selection_candidate_info_step_2,
1010 n * sizeof(ia_selection_candidate_info_struct));
1011 *selection_candidate_count = n;
1012 n = 0;
1013 for (k = 0; k < *selection_candidate_count; k++) {
1014 if ((selection_candidate_info[k].selection_flags &
1015 SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH) &&
1016 !(selection_candidate_info[k].selection_flags &
1017 SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT)) {
1018 memcpy(&selection_candidate_info_step_2[n],
1019 &selection_candidate_info[k],
1020 sizeof(ia_selection_candidate_info_struct));
1021 n++;
1022 } else {
1023 if (selection_candidate_info[k].output_peak_level <=
1024 output_peak_level_max) {
1025 memcpy(&selection_candidate_info_step_2[n],
1026 &selection_candidate_info[k],
1027 sizeof(ia_selection_candidate_info_struct));
1028 n++;
1029 }
1030 if (selection_candidate_info[k].output_peak_level <
1031 output_peak_level_min) {
1032 output_peak_level_min = selection_candidate_info[k].output_peak_level;
1033 }
1034 }
1035 }
1036 selection_candidate_step_2_count = n;
1037 if (selection_candidate_step_2_count == 0) {
1038 n = 0;
1039 for (k = 0; k < *selection_candidate_count; k++) {
1040 if ((selection_candidate_info[k].selection_flags &
1041 SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH) &&
1042 (selection_candidate_info[k].selection_flags &
1043 SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT)) {
1044 memcpy(&selection_candidate_info_step_2[n],
1045 &selection_candidate_info[k],
1046 sizeof(ia_selection_candidate_info_struct));
1047 n++;
1048 }
1049 }
1050 selection_candidate_step_2_count = n;
1051 }
1052 if (selection_candidate_step_2_count == 0) {
1053 n = 0;
1054 for (k = 0; k < *selection_candidate_count; k++) {
1055 if (selection_candidate_info_step_2[k].output_peak_level <
1056 output_peak_level_min + 1.0f) {
1057 memcpy(&selection_candidate_info_step_2[n],
1058 &selection_candidate_info[k],
1059 sizeof(ia_selection_candidate_info_struct));
1060 adjustment =
1061 max(0.0f, selection_candidate_info_step_2[n].output_peak_level -
1062 output_peak_level_max);
1063 adjustment = min(adjustment, max(0.0f, loudness_deviation_max));
1064 selection_candidate_info_step_2[n].loudness_norm_db_gain_adjusted -=
1065 adjustment;
1066 selection_candidate_info_step_2[n].output_peak_level -= adjustment;
1067 selection_candidate_info_step_2[n].output_loudness -= adjustment;
1068 n++;
1069 }
1070 }
1071 selection_candidate_step_2_count = n;
1072 }
1073
1074 for (n = 0; n < selection_candidate_step_2_count; n++) {
1075 memcpy(&selection_candidate_info[n], &selection_candidate_info_step_2[n],
1076 sizeof(ia_selection_candidate_info_struct));
1077 }
1078 *selection_candidate_count = selection_candidate_step_2_count;
1079 }
1080
1081 if (restrict_to_drc_with_album_loudness == 1) {
1082 j = 0;
1083 for (k = 0; k < *selection_candidate_count; k++) {
1084 loudness_drc_set_id_requested =
1085 max(0, pstr_drc_config
1086 ->str_drc_instruction_str[selection_candidate_info[k]
1087 .drc_instructions_index]
1088 .drc_set_id);
1089 for (n = 0; n < pstr_loudness_info->loudness_info_album_count; n++) {
1090 if (loudness_drc_set_id_requested ==
1091 pstr_loudness_info->str_loudness_info_album[n].drc_set_id) {
1092 if (j >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
1093 memcpy(&selection_candidate_info[j], &selection_candidate_info[k],
1094 sizeof(ia_selection_candidate_info_struct));
1095 j++;
1096 break;
1097 }
1098 }
1099 }
1100 *selection_candidate_count = j;
1101 }
1102 return (0);
1103 }
1104
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)1105 WORD32 impd_drc_set_final_selection(
1106 ia_drc_config* pstr_drc_config,
1107 ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
1108 WORD32* selection_candidate_count,
1109 ia_selection_candidate_info_struct* selection_candidate_info,
1110 WORD32* eq_set_id_valid_flag) {
1111 WORD32 k, i, n, err;
1112 WORD32 selection_candidate_step_2_count;
1113 ia_selection_candidate_info_struct
1114 selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
1115 WORD32 drc_set_id_max;
1116 FLOAT32 output_level_max;
1117 FLOAT32 output_level_min;
1118 WORD32 effect_count, effect_count_min;
1119 WORD32 effect_types_request_table_size;
1120 WORD32 drc_set_target_loudness_val_upper_min;
1121 ia_drc_instructions_struct* str_drc_instruction_str;
1122 ia_drc_instructions_struct* drc_instructions_dependent;
1123
1124 if (pstr_drc_sel_proc_params_struct->eq_set_purpose_request > 0) {
1125 WORD32 eq_purpose_requested =
1126 pstr_drc_sel_proc_params_struct->eq_set_purpose_request;
1127
1128 err = impd_match_eq_set_purpose(
1129 pstr_drc_config, eq_purpose_requested, eq_set_id_valid_flag,
1130 selection_candidate_count, selection_candidate_info,
1131 selection_candidate_info_step_2);
1132 if (err) return (err);
1133 }
1134
1135 output_level_min = 10000.0f;
1136 k = 0;
1137 for (i = 0; i < *selection_candidate_count; i++) {
1138 if (output_level_min >= selection_candidate_info[i].output_peak_level) {
1139 if (output_level_min > selection_candidate_info[i].output_peak_level) {
1140 output_level_min = selection_candidate_info[i].output_peak_level;
1141 k = 0;
1142 }
1143 memcpy(&selection_candidate_info_step_2[k], &selection_candidate_info[i],
1144 sizeof(ia_selection_candidate_info_struct));
1145 k++;
1146 }
1147 }
1148 selection_candidate_step_2_count = k;
1149
1150 if (output_level_min <= 0.0f) {
1151 selection_candidate_step_2_count = *selection_candidate_count;
1152 k = 0;
1153 for (i = 0; i < selection_candidate_step_2_count; i++) {
1154 if (selection_candidate_info[i].output_peak_level <= 0.0f) {
1155 memcpy(&selection_candidate_info_step_2[k],
1156 &selection_candidate_info[i],
1157 sizeof(ia_selection_candidate_info_struct));
1158 k++;
1159 }
1160 }
1161 selection_candidate_step_2_count = k;
1162
1163 k = 0;
1164 for (i = 0; i < selection_candidate_step_2_count; i++) {
1165 str_drc_instruction_str =
1166 &(pstr_drc_config->str_drc_instruction_str
1167 [selection_candidate_info_step_2[i].drc_instructions_index]);
1168 for (n = 0; n < str_drc_instruction_str->dwnmix_id_count; n++) {
1169 if (pstr_drc_sel_proc_params_struct->requested_dwnmix_id
1170 [selection_candidate_info_step_2[i].downmix_id_request_index] ==
1171 str_drc_instruction_str->downmix_id[n]) {
1172 if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
1173 memcpy(&selection_candidate_info_step_2[k],
1174 &selection_candidate_info_step_2[i],
1175 sizeof(ia_selection_candidate_info_struct));
1176 k++;
1177 }
1178 }
1179 }
1180 if (k > 0) {
1181 selection_candidate_step_2_count = k;
1182 }
1183
1184 effect_types_request_table_size =
1185 sizeof(effect_types_request_table) / sizeof(WORD32);
1186 effect_count_min = 100;
1187 k = 0;
1188 for (i = 0; i < selection_candidate_step_2_count; i++) {
1189 str_drc_instruction_str =
1190 &(pstr_drc_config->str_drc_instruction_str
1191 [selection_candidate_info_step_2[i].drc_instructions_index]);
1192 effect_count = 0;
1193 if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
1194 err = impd_get_dependent_drc_instructions(pstr_drc_config,
1195 str_drc_instruction_str,
1196 &drc_instructions_dependent);
1197 if (err) return (err);
1198
1199 for (n = 0; n < effect_types_request_table_size; n++) {
1200 if (effect_types_request_table[n] != EFFECT_BIT_GENERAL_COMPR) {
1201 if (((str_drc_instruction_str->drc_set_effect &
1202 effect_types_request_table[n]) != 0x0) ||
1203 ((drc_instructions_dependent->drc_set_effect &
1204 effect_types_request_table[n]) != 0x0)) {
1205 effect_count++;
1206 }
1207 }
1208 }
1209 } else {
1210 for (n = 0; n < effect_types_request_table_size; n++) {
1211 if (effect_types_request_table[n] != EFFECT_BIT_GENERAL_COMPR) {
1212 if ((str_drc_instruction_str->drc_set_effect &
1213 effect_types_request_table[n]) != 0x0) {
1214 effect_count++;
1215 }
1216 }
1217 }
1218 }
1219 if (effect_count_min >= effect_count) {
1220 if (effect_count_min > effect_count) {
1221 effect_count_min = effect_count;
1222 k = 0;
1223 }
1224 memcpy(&selection_candidate_info_step_2[k],
1225 &selection_candidate_info_step_2[i],
1226 sizeof(ia_selection_candidate_info_struct));
1227 k++;
1228 }
1229 }
1230 selection_candidate_step_2_count = k;
1231
1232 drc_set_target_loudness_val_upper_min = 100;
1233 k = 0;
1234 for (i = 0; i < selection_candidate_step_2_count; i++) {
1235 if (selection_candidate_info_step_2[i].selection_flags &
1236 SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH) {
1237 k++;
1238 }
1239 }
1240 if (k != 0 && k != selection_candidate_step_2_count) {
1241 k = 0;
1242 for (i = 0; i < selection_candidate_step_2_count; i++) {
1243 if (!(selection_candidate_info_step_2[i].selection_flags &
1244 SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH)) {
1245 memcpy(&selection_candidate_info_step_2[k],
1246 &selection_candidate_info_step_2[i],
1247 sizeof(ia_selection_candidate_info_struct));
1248 k++;
1249 }
1250 }
1251 selection_candidate_step_2_count = k;
1252 } else if (k == selection_candidate_step_2_count) {
1253 k = 0;
1254 for (i = 0; i < selection_candidate_step_2_count; i++) {
1255 str_drc_instruction_str =
1256 &(pstr_drc_config->str_drc_instruction_str
1257 [selection_candidate_info_step_2[i].drc_instructions_index]);
1258 if (str_drc_instruction_str->drc_set_target_loudness_present != 1) {
1259 return UNEXPECTED_ERROR;
1260 }
1261 if (drc_set_target_loudness_val_upper_min >=
1262 str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1263 if (drc_set_target_loudness_val_upper_min >
1264 str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1265 drc_set_target_loudness_val_upper_min =
1266 str_drc_instruction_str->drc_set_target_loudness_value_upper;
1267 k = 0;
1268 }
1269 memcpy(&selection_candidate_info_step_2[k],
1270 &selection_candidate_info_step_2[i],
1271 sizeof(ia_selection_candidate_info_struct));
1272 k++;
1273 }
1274 }
1275 selection_candidate_step_2_count = k;
1276 }
1277
1278 k = 0;
1279 for (i = 0; i < selection_candidate_step_2_count; i++) {
1280 str_drc_instruction_str =
1281 &(pstr_drc_config->str_drc_instruction_str
1282 [selection_candidate_info_step_2[i].drc_instructions_index]);
1283 if (str_drc_instruction_str->drc_set_target_loudness_present &&
1284 pstr_drc_sel_proc_params_struct->loudness_normalization_on &&
1285 str_drc_instruction_str->drc_set_target_loudness_value_upper >=
1286 pstr_drc_sel_proc_params_struct->target_loudness &&
1287 str_drc_instruction_str->drc_set_target_loudness_value_lower <
1288 pstr_drc_sel_proc_params_struct->target_loudness) {
1289 k++;
1290 }
1291 }
1292 if (k != 0 && k != selection_candidate_step_2_count) {
1293 k = 0;
1294 for (i = 0; i < selection_candidate_step_2_count; i++) {
1295 str_drc_instruction_str =
1296 &(pstr_drc_config->str_drc_instruction_str
1297 [selection_candidate_info_step_2[i].drc_instructions_index]);
1298 if (str_drc_instruction_str->drc_set_target_loudness_present &&
1299 pstr_drc_sel_proc_params_struct->loudness_normalization_on &&
1300 str_drc_instruction_str->drc_set_target_loudness_value_upper >=
1301 pstr_drc_sel_proc_params_struct->target_loudness &&
1302 str_drc_instruction_str->drc_set_target_loudness_value_lower <
1303 pstr_drc_sel_proc_params_struct->target_loudness) {
1304 memcpy(&selection_candidate_info_step_2[k],
1305 &selection_candidate_info_step_2[i],
1306 sizeof(ia_selection_candidate_info_struct));
1307 k++;
1308 }
1309 }
1310 selection_candidate_step_2_count = k;
1311 drc_set_target_loudness_val_upper_min = 100;
1312 k = 0;
1313 for (i = 0; i < selection_candidate_step_2_count; i++) {
1314 str_drc_instruction_str =
1315 &(pstr_drc_config->str_drc_instruction_str
1316 [selection_candidate_info_step_2[i].drc_instructions_index]);
1317 if (str_drc_instruction_str->drc_set_target_loudness_present != 1) {
1318 return UNEXPECTED_ERROR;
1319 }
1320 if (drc_set_target_loudness_val_upper_min >=
1321 str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1322 if (drc_set_target_loudness_val_upper_min >
1323 str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1324 drc_set_target_loudness_val_upper_min =
1325 str_drc_instruction_str->drc_set_target_loudness_value_upper;
1326 k = 0;
1327 }
1328 memcpy(&selection_candidate_info_step_2[k],
1329 &selection_candidate_info_step_2[i],
1330 sizeof(ia_selection_candidate_info_struct));
1331 k++;
1332 }
1333 }
1334 selection_candidate_step_2_count = k;
1335 } else if (k == selection_candidate_step_2_count) {
1336 drc_set_target_loudness_val_upper_min = 100;
1337 k = 0;
1338 for (i = 0; i < selection_candidate_step_2_count; i++) {
1339 str_drc_instruction_str =
1340 &(pstr_drc_config->str_drc_instruction_str
1341 [selection_candidate_info_step_2[i].drc_instructions_index]);
1342 if (str_drc_instruction_str->drc_set_target_loudness_present != 1) {
1343 return UNEXPECTED_ERROR;
1344 }
1345 if (drc_set_target_loudness_val_upper_min >=
1346 str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1347 if (drc_set_target_loudness_val_upper_min >
1348 str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1349 drc_set_target_loudness_val_upper_min =
1350 str_drc_instruction_str->drc_set_target_loudness_value_upper;
1351 k = 0;
1352 }
1353 memcpy(&selection_candidate_info_step_2[k],
1354 &selection_candidate_info_step_2[i],
1355 sizeof(ia_selection_candidate_info_struct));
1356 k++;
1357 }
1358 }
1359 selection_candidate_step_2_count = k;
1360 }
1361 k = 0;
1362 output_level_max = -1000.0f;
1363 for (i = 0; i < selection_candidate_step_2_count; i++) {
1364 if ((selection_candidate_info_step_2[i].output_peak_level <= 0.0f) &&
1365 (output_level_max <=
1366 selection_candidate_info_step_2[i].output_peak_level)) {
1367 if (output_level_max <
1368 selection_candidate_info_step_2[i].output_peak_level) {
1369 output_level_max =
1370 selection_candidate_info_step_2[i].output_peak_level;
1371 k = 0;
1372 }
1373 memcpy(&selection_candidate_info_step_2[k],
1374 &selection_candidate_info_step_2[i],
1375 sizeof(ia_selection_candidate_info_struct));
1376 k++;
1377 output_level_max = selection_candidate_info_step_2[i].output_peak_level;
1378 }
1379 }
1380 selection_candidate_step_2_count = k;
1381 }
1382
1383 drc_set_id_max = -1000;
1384 for (i = 0; i < selection_candidate_step_2_count; i++) {
1385 str_drc_instruction_str =
1386 &(pstr_drc_config->str_drc_instruction_str
1387 [selection_candidate_info_step_2[i].drc_instructions_index]);
1388 if (drc_set_id_max < str_drc_instruction_str->drc_set_id) {
1389 drc_set_id_max = str_drc_instruction_str->drc_set_id;
1390 memcpy(&selection_candidate_info_step_2[0],
1391 &selection_candidate_info_step_2[i],
1392 sizeof(ia_selection_candidate_info_struct));
1393 }
1394 }
1395 memcpy(&selection_candidate_info[0], &selection_candidate_info_step_2[0],
1396 sizeof(ia_selection_candidate_info_struct));
1397 *selection_candidate_count = 1;
1398
1399 return 0;
1400 }
1401
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)1402 WORD32 impd_select_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
1403 WORD32* drc_set_id_selected,
1404 WORD32* eq_set_id_selected, WORD32* loud_eq_id_sel) {
1405 WORD32 i, err;
1406
1407 ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct =
1408 &pstr_drc_uni_sel_proc->uni_drc_sel_proc_params;
1409 ia_drc_config* pstr_drc_config = &pstr_drc_uni_sel_proc->drc_config;
1410 ia_drc_loudness_info_set_struct* pstr_loudness_info =
1411 &pstr_drc_uni_sel_proc->loudness_info_set;
1412
1413 WORD32 selection_candidate_count = 0;
1414 WORD32 restrict_to_drc_with_album_loudness = 0;
1415 ia_selection_candidate_info_struct
1416 selection_candidate_info[SELECTION_CANDIDATE_COUNT_MAX];
1417
1418 // WORD32 selected_eq_set_count = 0;
1419
1420 if (pstr_drc_sel_proc_params_struct->album_mode == 1) {
1421 restrict_to_drc_with_album_loudness = 1;
1422 }
1423
1424 while (!selection_candidate_count) {
1425 err = impd_drc_set_preselection(
1426 pstr_drc_sel_proc_params_struct, pstr_drc_config, pstr_loudness_info,
1427 restrict_to_drc_with_album_loudness, pstr_drc_uni_sel_proc,
1428 &selection_candidate_count, selection_candidate_info);
1429 if (err) return err;
1430
1431 if (selection_candidate_count == 0) {
1432 if (restrict_to_drc_with_album_loudness == 1) {
1433 restrict_to_drc_with_album_loudness = 0;
1434 continue;
1435 } else {
1436 return (UNEXPECTED_ERROR);
1437 }
1438 }
1439
1440 err = impd_validate_requested_drc_feature(pstr_drc_sel_proc_params_struct);
1441 if (err) return (err);
1442
1443 if (pstr_drc_sel_proc_params_struct->dynamic_range_control_on == 1) {
1444 if (pstr_drc_sel_proc_params_struct->num_drc_feature_requests > 0) {
1445 for (i = 0;
1446 i < pstr_drc_sel_proc_params_struct->num_drc_feature_requests;
1447 i++) {
1448 switch (pstr_drc_sel_proc_params_struct->drc_feature_req_type[i]) {
1449 case MATCH_EFFECT_TYPE:
1450 err = impd_match_effect_types(
1451 pstr_drc_config,
1452 pstr_drc_sel_proc_params_struct->requested_num_drc_effects[i],
1453 pstr_drc_sel_proc_params_struct
1454 ->desired_num_drc_effects_of_requested[i],
1455 pstr_drc_sel_proc_params_struct->requested_drc_effect_type[i],
1456 &selection_candidate_count, selection_candidate_info);
1457 if (err) return (err);
1458 break;
1459 case MATCH_DYNAMIC_RANGE:
1460 err = impd_match_dynamic_range(
1461 pstr_drc_config, pstr_loudness_info,
1462 pstr_drc_sel_proc_params_struct, i,
1463 &selection_candidate_count, selection_candidate_info);
1464 if (err) return (err);
1465 break;
1466 case MATCH_DRC_CHARACTERISTIC:
1467 err = impd_match_drc_characteristic(
1468 pstr_drc_config, pstr_drc_sel_proc_params_struct
1469 ->requested_drc_characteristic[i],
1470 &selection_candidate_count, selection_candidate_info);
1471 if (err) return (err);
1472 break;
1473
1474 default:
1475 return (UNEXPECTED_ERROR);
1476 break;
1477 }
1478 }
1479 } else {
1480 WORD32 match_found_flag = 0;
1481
1482 err = impd_select_drcs_without_compr_effects(
1483 pstr_drc_config, &match_found_flag, &selection_candidate_count,
1484 selection_candidate_info);
1485 if (err) return (err);
1486
1487 if (match_found_flag == 0) {
1488 WORD32 requested_num_drc_effects = 5;
1489 WORD32 desired_num_drc_effects_of_requested = 1;
1490 WORD32 requested_drc_effect_type[5] = {
1491 EFFECT_TYPE_REQUESTED_GENERAL_COMPR, EFFECT_TYPE_REQUESTED_NIGHT,
1492 EFFECT_TYPE_REQUESTED_NOISY, EFFECT_TYPE_REQUESTED_LIMITED,
1493 EFFECT_TYPE_REQUESTED_LOWLEVEL};
1494
1495 err = impd_match_effect_types(
1496 pstr_drc_config, requested_num_drc_effects,
1497 desired_num_drc_effects_of_requested, requested_drc_effect_type,
1498 &selection_candidate_count, selection_candidate_info);
1499 if (err) return (err);
1500 }
1501 }
1502
1503 if (selection_candidate_count > 0) {
1504 err = impd_drc_set_final_selection(
1505 pstr_drc_config, pstr_drc_sel_proc_params_struct,
1506 &selection_candidate_count, selection_candidate_info,
1507 pstr_drc_uni_sel_proc->eq_set_id_valid_flag);
1508 if (err) return (err);
1509 } else {
1510 selection_candidate_count = 0;
1511 return (UNEXPECTED_ERROR);
1512 }
1513 }
1514
1515 if (selection_candidate_count == 0) {
1516 if (restrict_to_drc_with_album_loudness == 1) {
1517 restrict_to_drc_with_album_loudness = 0;
1518 } else {
1519 return (UNEXPECTED_ERROR);
1520 }
1521 }
1522 }
1523 *drc_set_id_selected =
1524 pstr_drc_config
1525 ->str_drc_instruction_str[selection_candidate_info[0]
1526 .drc_instructions_index]
1527 .drc_set_id;
1528 *eq_set_id_selected = selection_candidate_info[0].eq_set_id;
1529
1530 err = impd_select_loud_eq(
1531 pstr_drc_config,
1532 pstr_drc_sel_proc_params_struct->requested_dwnmix_id
1533 [selection_candidate_info[0].downmix_id_request_index],
1534 *drc_set_id_selected, *eq_set_id_selected, loud_eq_id_sel);
1535 if (err) return (err);
1536 if (selection_candidate_count > 0) {
1537 pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
1538 .loudness_normalization_gain_db =
1539 selection_candidate_info[0].loudness_norm_db_gain_adjusted;
1540 pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.output_peak_level_db =
1541 selection_candidate_info[0].output_peak_level;
1542 pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.output_loudness =
1543 selection_candidate_info[0].output_loudness;
1544 pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.active_downmix_id =
1545 pstr_drc_sel_proc_params_struct->requested_dwnmix_id
1546 [selection_candidate_info[0].downmix_id_request_index];
1547 pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.mixing_level =
1548 selection_candidate_info[0].mixing_level;
1549 }
1550 return (0);
1551 }
1552