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 <math.h>
22
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_filter_bank.h"
30 #include "impd_drc_rom.h"
impd_signal_peak_level_info(ia_drc_config * pstr_drc_config,ia_drc_loudness_info_set_struct * pstr_loudness_info,ia_drc_instructions_struct * str_drc_instruction_str,WORD32 requested_dwnmix_id,WORD32 album_mode,WORD32 num_compression_eq_count,WORD32 * num_compression_eq_id,WORD32 * peak_info_count,WORD32 eq_set_id[],FLOAT32 signal_peak_level[],WORD32 explicit_peak_information_present[])31 VOID impd_signal_peak_level_info(
32 ia_drc_config* pstr_drc_config,
33 ia_drc_loudness_info_set_struct* pstr_loudness_info,
34 ia_drc_instructions_struct* str_drc_instruction_str,
35 WORD32 requested_dwnmix_id, WORD32 album_mode,
36 WORD32 num_compression_eq_count, WORD32* num_compression_eq_id,
37 WORD32* peak_info_count, WORD32 eq_set_id[], FLOAT32 signal_peak_level[],
38 WORD32 explicit_peak_information_present[]) {
39 WORD32 c, d, i, k, n, base_channel_count, mode;
40 WORD32 pre_lim_count;
41 WORD32 peak_count = 0;
42 WORD32 loudness_info_count = 0;
43 ia_loudness_info_struct* loudness_info;
44 FLOAT32 sum, max_sum;
45 WORD32 drc_set_id_requested = str_drc_instruction_str->drc_set_id;
46 WORD32 loudness_drc_set_id_requested;
47 WORD32 match_found_flag = 0;
48
49 FLOAT32 signal_peak_level_tmp;
50 eq_set_id[0] = 0;
51 signal_peak_level[0] = 0.0f;
52 explicit_peak_information_present[0] = 0;
53
54 k = 0;
55 if (drc_set_id_requested < 0) {
56 for (k = 0; k < num_compression_eq_count; k++) {
57 eq_set_id[k] = num_compression_eq_id[k];
58 signal_peak_level[k] = 0.0f;
59 explicit_peak_information_present[k] = 0;
60 }
61 }
62 eq_set_id[k] = 0;
63 signal_peak_level[k] = 0.0f;
64 explicit_peak_information_present[k] = 0;
65 k++;
66
67 pre_lim_count = k;
68
69 if (drc_set_id_requested < 0) {
70 loudness_drc_set_id_requested = 0;
71 } else {
72 loudness_drc_set_id_requested = drc_set_id_requested;
73 }
74
75 if (album_mode == 1) {
76 mode = 1;
77 loudness_info_count = pstr_loudness_info->loudness_info_album_count;
78 } else {
79 mode = 0;
80 loudness_info_count = pstr_loudness_info->loudness_info_count;
81 }
82
83 for (n = 0; n < loudness_info_count; n++) {
84 if (mode == 1) {
85 loudness_info = &(pstr_loudness_info->str_loudness_info_album[n]);
86 } else {
87 loudness_info = &(pstr_loudness_info->loudness_info[n]);
88 }
89 if (loudness_drc_set_id_requested == loudness_info->drc_set_id &&
90 requested_dwnmix_id == loudness_info->downmix_id) {
91 if (loudness_info->true_peak_level_present) {
92 eq_set_id[peak_count] = loudness_info->eq_set_id;
93
94 signal_peak_level[peak_count] = loudness_info->true_peak_level;
95 explicit_peak_information_present[peak_count] = 1;
96
97 match_found_flag = 1;
98 peak_count++;
99 }
100 if (match_found_flag == 0) {
101 if (loudness_info->sample_peak_level_present) {
102 eq_set_id[peak_count] = loudness_info->eq_set_id;
103
104 signal_peak_level[peak_count] = loudness_info->sample_peak_level;
105 explicit_peak_information_present[peak_count] = 1;
106
107 match_found_flag = 1;
108 peak_count++;
109 }
110 }
111 }
112 }
113 if (match_found_flag == 0) {
114 for (n = 0; n < loudness_info_count; n++) {
115 if (mode == 1) {
116 loudness_info = &(pstr_loudness_info->str_loudness_info_album[n]);
117 } else {
118 loudness_info = &(pstr_loudness_info->loudness_info[n]);
119 }
120 if (ID_FOR_ANY_DRC == loudness_info->drc_set_id &&
121 requested_dwnmix_id == loudness_info->downmix_id) {
122 if (loudness_info->true_peak_level_present) {
123 eq_set_id[peak_count] = loudness_info->eq_set_id;
124
125 signal_peak_level[peak_count] = loudness_info->true_peak_level;
126 explicit_peak_information_present[peak_count] = 1;
127
128 match_found_flag = 1;
129 peak_count++;
130 }
131 if (match_found_flag == 0) {
132 if (loudness_info->sample_peak_level_present) {
133 eq_set_id[peak_count] = loudness_info->eq_set_id;
134
135 signal_peak_level[peak_count] = loudness_info->sample_peak_level;
136 explicit_peak_information_present[peak_count] = 1;
137
138 match_found_flag = 1;
139 peak_count++;
140 }
141 }
142 }
143 }
144 }
145 if (match_found_flag == 0) {
146 for (i = 0; i < str_drc_instruction_str->dwnmix_id_count; i++) {
147 if (requested_dwnmix_id == str_drc_instruction_str->downmix_id[0] ||
148 ID_FOR_ANY_DOWNMIX == str_drc_instruction_str->downmix_id[0]) {
149 if (str_drc_instruction_str->limiter_peak_target_present) {
150 if (str_drc_instruction_str->requires_eq == 1) {
151 for (d = 0;
152 d < pstr_drc_config->str_drc_config_ext.eq_instructions_count;
153 d++) {
154 ia_eq_instructions_struct* eq_instructions =
155 &pstr_drc_config->str_drc_config_ext.str_eq_instructions[d];
156 for (c = 0; c < eq_instructions->drc_set_id_count; c++) {
157 if ((eq_instructions->drc_set_id[c] ==
158 loudness_drc_set_id_requested) ||
159 (eq_instructions->drc_set_id[c] == ID_FOR_ANY_DRC)) {
160 for (i = 0; i < eq_instructions->dwnmix_id_count; i++) {
161 if ((eq_instructions->downmix_id[i] ==
162 requested_dwnmix_id) ||
163 (eq_instructions->downmix_id[i] ==
164 ID_FOR_ANY_DOWNMIX)) {
165 eq_set_id[peak_count] = eq_instructions->eq_set_id;
166 signal_peak_level[peak_count] =
167 str_drc_instruction_str->limiter_peak_target;
168 explicit_peak_information_present[peak_count] = 1;
169 match_found_flag = 1;
170 peak_count++;
171 }
172 }
173 }
174 }
175 }
176 } else
177
178 {
179 eq_set_id[peak_count] = 0;
180 signal_peak_level[peak_count] =
181 str_drc_instruction_str->limiter_peak_target;
182 explicit_peak_information_present[peak_count] = 1;
183 match_found_flag = 1;
184 peak_count++;
185 }
186 }
187 }
188 }
189 }
190 if (match_found_flag == 0) {
191 for (i = 1; i < str_drc_instruction_str->dwnmix_id_count; i++) {
192 if (requested_dwnmix_id == str_drc_instruction_str->downmix_id[i]) {
193 if (str_drc_instruction_str->limiter_peak_target_present) {
194 {
195 eq_set_id[peak_count] = 0;
196 signal_peak_level[peak_count] =
197 str_drc_instruction_str->limiter_peak_target;
198 explicit_peak_information_present[peak_count] = 1;
199 match_found_flag = 1;
200 peak_count++;
201 }
202 }
203 }
204 }
205 }
206 if (match_found_flag == 0) {
207 if (requested_dwnmix_id != ID_FOR_BASE_LAYOUT) {
208 signal_peak_level_tmp = 0.f;
209 for (i = 0; i < pstr_drc_config->dwnmix_instructions_count; i++) {
210 if (pstr_drc_config->dwnmix_instructions[i].downmix_id ==
211 requested_dwnmix_id) {
212 if (pstr_drc_config->dwnmix_instructions[i]
213 .downmix_coefficients_present) {
214 base_channel_count =
215 pstr_drc_config->channel_layout.base_channel_count;
216 max_sum = 0.0f;
217 for (c = 0;
218 c <
219 pstr_drc_config->dwnmix_instructions[i].target_channel_count;
220 c++) {
221 sum = 0.0f;
222 for (d = 0; d < base_channel_count; d++) {
223 sum += pstr_drc_config->dwnmix_instructions[i]
224 .downmix_coefficient[c * base_channel_count + d];
225 }
226 if (max_sum < sum) max_sum = sum;
227 }
228 signal_peak_level_tmp = 20.0f * (FLOAT32)log10(max_sum);
229 } else {
230 }
231 break;
232 }
233 }
234 for (n = 0; n < loudness_info_count; n++) {
235 if (mode == 1) {
236 loudness_info = &(pstr_loudness_info->str_loudness_info_album[n]);
237 } else {
238 loudness_info = &(pstr_loudness_info->loudness_info[n]);
239 }
240 if (loudness_drc_set_id_requested == loudness_info->drc_set_id &&
241 ID_FOR_BASE_LAYOUT == loudness_info->downmix_id) {
242 if (loudness_info->true_peak_level_present) {
243 eq_set_id[peak_count] = loudness_info->eq_set_id;
244
245 signal_peak_level[peak_count] =
246 loudness_info->true_peak_level + signal_peak_level_tmp;
247 explicit_peak_information_present[peak_count] = 0;
248
249 match_found_flag = 1;
250 peak_count++;
251 }
252 if (match_found_flag == 0) {
253 if (loudness_info->sample_peak_level_present) {
254 eq_set_id[peak_count] = loudness_info->eq_set_id;
255
256 signal_peak_level[peak_count] =
257 loudness_info->sample_peak_level + signal_peak_level_tmp;
258 explicit_peak_information_present[peak_count] = 0;
259
260 match_found_flag = 1;
261 peak_count++;
262 }
263 }
264 }
265 }
266 if (match_found_flag == 0) {
267 for (n = 0; n < loudness_info_count; n++) {
268 if (mode == 1) {
269 loudness_info = &(pstr_loudness_info->str_loudness_info_album[n]);
270 } else {
271 loudness_info = &(pstr_loudness_info->loudness_info[n]);
272 }
273 if (ID_FOR_ANY_DRC == loudness_info->drc_set_id &&
274 ID_FOR_BASE_LAYOUT == loudness_info->downmix_id) {
275 if (loudness_info->true_peak_level_present) {
276 eq_set_id[peak_count] = loudness_info->eq_set_id;
277
278 signal_peak_level[peak_count] =
279 loudness_info->true_peak_level + signal_peak_level_tmp;
280 explicit_peak_information_present[peak_count] = 0;
281
282 match_found_flag = 1;
283 peak_count++;
284 }
285 if (match_found_flag == 0) {
286 if (loudness_info->sample_peak_level_present) {
287 eq_set_id[peak_count] = loudness_info->eq_set_id;
288
289 signal_peak_level[peak_count] =
290 loudness_info->sample_peak_level + signal_peak_level_tmp;
291 explicit_peak_information_present[peak_count] = 0;
292
293 match_found_flag = 1;
294 peak_count++;
295 }
296 }
297 }
298 }
299 }
300 if (match_found_flag == 0) {
301 ia_drc_instructions_struct* drc_instructions_drc_tmp;
302 for (n = 0; n < pstr_drc_config->drc_instructions_count_plus; n++) {
303 drc_instructions_drc_tmp =
304 &pstr_drc_config->str_drc_instruction_str[n];
305 if (loudness_drc_set_id_requested ==
306 drc_instructions_drc_tmp->drc_set_id) {
307 if (ID_FOR_BASE_LAYOUT == drc_instructions_drc_tmp->downmix_id[0]) {
308 if (drc_instructions_drc_tmp->limiter_peak_target_present) {
309 eq_set_id[peak_count] = -1;
310 signal_peak_level[peak_count] =
311 drc_instructions_drc_tmp->limiter_peak_target +
312 signal_peak_level_tmp;
313 explicit_peak_information_present[peak_count] = 0;
314 match_found_flag = 1;
315 peak_count++;
316 }
317 }
318 }
319 }
320 }
321 }
322 }
323 if (peak_count > 0) {
324 *peak_info_count = peak_count;
325 } else {
326 *peak_info_count = pre_lim_count;
327 }
328 return;
329 }
330
331 WORD32
impd_extract_loudness_peak_to_average_info(ia_loudness_info_struct * loudness_info,WORD32 dyn_range_measurement_type,WORD32 * loudness_peak_2_avg_value_present,FLOAT32 * loudness_peak_2_avg_value)332 impd_extract_loudness_peak_to_average_info(
333 ia_loudness_info_struct* loudness_info, WORD32 dyn_range_measurement_type,
334 WORD32* loudness_peak_2_avg_value_present,
335 FLOAT32* loudness_peak_2_avg_value) {
336 WORD32 k;
337 WORD32 program_loudness_present = 0;
338 WORD32 peak_loudness_present = 0;
339 WORD32 match_measure_program_loudness = 0;
340 WORD32 match_measure_peak_loudness = 0;
341 FLOAT32 program_loudness = 0.0f;
342 FLOAT32 peak_loudness = 0.0f;
343 ia_loudness_measure_struct* loudness_measure = NULL;
344
345 for (k = 0; k < loudness_info->measurement_count; k++) {
346 loudness_measure = &(loudness_info->loudness_measure[k]);
347 if (loudness_measure->method_def == METHOD_DEFINITION_PROGRAM_LOUDNESS) {
348 if (match_measure_program_loudness <
349 measurement_method_prog_loudness_tbl[loudness_measure
350 ->measurement_system]) {
351 program_loudness = loudness_measure->method_val;
352 program_loudness_present = 1;
353 match_measure_program_loudness =
354 measurement_method_prog_loudness_tbl[loudness_measure
355 ->measurement_system];
356 }
357 }
358 switch (dyn_range_measurement_type) {
359 case SHORT_TERM_LOUDNESS_TO_AVG:
360 if (loudness_measure->method_def ==
361 METHOD_DEFINITION_SHORT_TERM_LOUDNESS_MAX) {
362 if (match_measure_peak_loudness <
363 measurement_method_peak_loudness_tbl[loudness_measure
364 ->measurement_system]) {
365 peak_loudness = loudness_measure->method_val;
366 peak_loudness_present = 1;
367 match_measure_peak_loudness =
368 measurement_method_peak_loudness_tbl[loudness_measure
369 ->measurement_system];
370 }
371 }
372 break;
373
374 case MOMENTARY_LOUDNESS_TO_AVG:
375 if (loudness_measure->method_def ==
376 METHOD_DEFINITION_MOMENTARY_LOUDNESS_MAX) {
377 if (match_measure_peak_loudness <
378 measurement_method_peak_loudness_tbl[loudness_measure
379 ->measurement_system]) {
380 peak_loudness = loudness_measure->method_val;
381 peak_loudness_present = 1;
382 match_measure_peak_loudness =
383 measurement_method_peak_loudness_tbl[loudness_measure
384 ->measurement_system];
385 }
386 }
387 break;
388
389 case TOP_OF_LOUDNESS_RANGE_TO_AVG:
390 if (loudness_measure->method_def ==
391 METHOD_DEFINITION_MAX_OF_LOUDNESS_RANGE) {
392 if (match_measure_peak_loudness <
393 measurement_method_peak_loudness_tbl[loudness_measure
394 ->measurement_system]) {
395 peak_loudness = loudness_measure->method_val;
396 peak_loudness_present = 1;
397 match_measure_peak_loudness =
398 measurement_method_peak_loudness_tbl[loudness_measure
399 ->measurement_system];
400 }
401 }
402 break;
403
404 default:
405 return (UNEXPECTED_ERROR);
406
407 break;
408 }
409 }
410 if ((program_loudness_present == 1) && (peak_loudness_present == 1)) {
411 *loudness_peak_2_avg_value = peak_loudness - program_loudness;
412 *loudness_peak_2_avg_value_present = 1;
413 }
414 return (0);
415 }
416
impd_loudness_peak_to_average_info(ia_drc_loudness_info_set_struct * pstr_loudness_info,ia_drc_instructions_struct * str_drc_instruction_str,WORD32 requested_dwnmix_id,WORD32 dyn_range_measurement_type,WORD32 album_mode,WORD32 * loudness_peak_2_avg_value_present,FLOAT32 * loudness_peak_2_avg_value)417 WORD32 impd_loudness_peak_to_average_info(
418 ia_drc_loudness_info_set_struct* pstr_loudness_info,
419 ia_drc_instructions_struct* str_drc_instruction_str,
420 WORD32 requested_dwnmix_id, WORD32 dyn_range_measurement_type,
421 WORD32 album_mode, WORD32* loudness_peak_2_avg_value_present,
422 FLOAT32* loudness_peak_2_avg_value) {
423 WORD32 n, err;
424 WORD32 drc_set_id = max(0, str_drc_instruction_str->drc_set_id);
425
426 *loudness_peak_2_avg_value_present = 0;
427
428 if (album_mode == 1) {
429 for (n = 0; n < pstr_loudness_info->loudness_info_album_count; n++) {
430 ia_loudness_info_struct* loudness_info =
431 &(pstr_loudness_info->str_loudness_info_album[n]);
432 if (drc_set_id == loudness_info->drc_set_id) {
433 if (requested_dwnmix_id == loudness_info->downmix_id) {
434 err = impd_extract_loudness_peak_to_average_info(
435 loudness_info, dyn_range_measurement_type,
436 loudness_peak_2_avg_value_present, loudness_peak_2_avg_value);
437 if (err) return (err);
438 }
439 }
440 }
441 }
442 if (*loudness_peak_2_avg_value_present == 0) {
443 for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) {
444 ia_loudness_info_struct* loudness_info =
445 &(pstr_loudness_info->loudness_info[n]);
446 if (drc_set_id == loudness_info->drc_set_id) {
447 if (requested_dwnmix_id == loudness_info->downmix_id) {
448 err = impd_extract_loudness_peak_to_average_info(
449 loudness_info, dyn_range_measurement_type,
450 loudness_peak_2_avg_value_present, loudness_peak_2_avg_value);
451 if (err) return (err);
452 }
453 }
454 }
455 }
456 return (0);
457 }
458
impd_overall_loudness_present(ia_loudness_info_struct * loudness_info,WORD32 * loudness_info_present)459 VOID impd_overall_loudness_present(ia_loudness_info_struct* loudness_info,
460 WORD32* loudness_info_present) {
461 WORD32 m;
462
463 *loudness_info_present = 0;
464 for (m = 0; m < loudness_info->measurement_count; m++) {
465 if ((loudness_info->loudness_measure[m].method_def ==
466 METHOD_DEFINITION_PROGRAM_LOUDNESS) ||
467 (loudness_info->loudness_measure[m].method_def ==
468 METHOD_DEFINITION_ANCHOR_LOUDNESS)) {
469 *loudness_info_present = 1;
470 }
471 }
472 return;
473 }
474
impd_check_loud_info(WORD32 loudness_info_count,ia_loudness_info_struct * loudness_info,WORD32 requested_dwnmix_id,WORD32 drc_set_id_requested,WORD32 * info_count,ia_loudness_info_struct * loudness_info_matching[])475 WORD32 impd_check_loud_info(WORD32 loudness_info_count,
476 ia_loudness_info_struct* loudness_info,
477 WORD32 requested_dwnmix_id,
478 WORD32 drc_set_id_requested, WORD32* info_count,
479 ia_loudness_info_struct* loudness_info_matching[]) {
480 WORD32 n;
481 WORD32 loudness_info_present;
482 for (n = 0; n < loudness_info_count; n++) {
483 if (requested_dwnmix_id == loudness_info[n].downmix_id) {
484 if (drc_set_id_requested == loudness_info[n].drc_set_id) {
485 impd_overall_loudness_present(&(loudness_info[n]),
486 &loudness_info_present);
487
488 if (loudness_info_present) {
489 loudness_info_matching[*info_count] = &(loudness_info[n]);
490 (*info_count)++;
491 }
492 }
493 }
494 }
495
496 return (0);
497 }
498
impd_check_loud_payload(WORD32 loudness_info_count,ia_loudness_info_struct * loudness_info,WORD32 requested_dwnmix_id,WORD32 drc_set_id_requested,WORD32 * info_count,ia_loudness_info_struct * loudness_info_matching[])499 WORD32 impd_check_loud_payload(
500 WORD32 loudness_info_count, ia_loudness_info_struct* loudness_info,
501 WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested, WORD32* info_count,
502 ia_loudness_info_struct* loudness_info_matching[]) {
503 WORD32 err = 0;
504
505 err = impd_check_loud_info(loudness_info_count, loudness_info,
506 requested_dwnmix_id, drc_set_id_requested,
507 info_count, loudness_info_matching);
508 if (err || *info_count) goto matchEnd;
509 err = impd_check_loud_info(loudness_info_count, loudness_info,
510 ID_FOR_ANY_DOWNMIX, drc_set_id_requested,
511 info_count, loudness_info_matching);
512 if (err || *info_count) goto matchEnd;
513 err = impd_check_loud_info(loudness_info_count, loudness_info,
514 requested_dwnmix_id, ID_FOR_ANY_DRC, info_count,
515 loudness_info_matching);
516 if (err || *info_count) goto matchEnd;
517 err = impd_check_loud_info(loudness_info_count, loudness_info,
518 requested_dwnmix_id, ID_FOR_NO_DRC, info_count,
519 loudness_info_matching);
520 if (err || *info_count) goto matchEnd;
521 err = impd_check_loud_info(loudness_info_count, loudness_info,
522 ID_FOR_ANY_DOWNMIX, ID_FOR_ANY_DRC, info_count,
523 loudness_info_matching);
524 if (err || *info_count) goto matchEnd;
525 err = impd_check_loud_info(loudness_info_count, loudness_info,
526 ID_FOR_ANY_DOWNMIX, ID_FOR_NO_DRC, info_count,
527 loudness_info_matching);
528 if (err || *info_count) goto matchEnd;
529 err = impd_check_loud_info(loudness_info_count, loudness_info,
530 ID_FOR_BASE_LAYOUT, drc_set_id_requested,
531 info_count, loudness_info_matching);
532 if (err || *info_count) goto matchEnd;
533 err = impd_check_loud_info(loudness_info_count, loudness_info,
534 ID_FOR_BASE_LAYOUT, ID_FOR_ANY_DRC, info_count,
535 loudness_info_matching);
536 if (err || *info_count) goto matchEnd;
537 err = impd_check_loud_info(loudness_info_count, loudness_info,
538 ID_FOR_BASE_LAYOUT, ID_FOR_NO_DRC, info_count,
539 loudness_info_matching);
540 if (err || *info_count) goto matchEnd;
541 matchEnd:
542 return (err);
543 }
544
impd_find_overall_loudness_info(ia_drc_sel_proc_params_struct * pstr_drc_sel_proc_params_struct,ia_drc_loudness_info_set_struct * pstr_loudness_info,WORD32 requested_dwnmix_id,WORD32 drc_set_id_requested,WORD32 * overall_loudness_info_present,WORD32 * info_count,ia_loudness_info_struct * loudness_info_matching[])545 WORD32 impd_find_overall_loudness_info(
546 ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
547 ia_drc_loudness_info_set_struct* pstr_loudness_info,
548 WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested,
549 WORD32* overall_loudness_info_present, WORD32* info_count,
550 ia_loudness_info_struct* loudness_info_matching[]) {
551 WORD32 err;
552 WORD32 loudness_drc_set_id_requested;
553
554 *info_count = 0;
555 if (drc_set_id_requested < 0) {
556 loudness_drc_set_id_requested = ID_FOR_NO_DRC;
557 } else {
558 loudness_drc_set_id_requested = drc_set_id_requested;
559 }
560 if (pstr_drc_sel_proc_params_struct->album_mode == 1) {
561 err = impd_check_loud_payload(
562 pstr_loudness_info->loudness_info_album_count,
563 pstr_loudness_info->str_loudness_info_album, requested_dwnmix_id,
564 loudness_drc_set_id_requested, info_count, loudness_info_matching);
565 if (err) return (err);
566 }
567 if (*info_count == 0) {
568 err = impd_check_loud_payload(pstr_loudness_info->loudness_info_count,
569 pstr_loudness_info->loudness_info,
570 requested_dwnmix_id,
571 loudness_drc_set_id_requested,
572
573 info_count, loudness_info_matching);
574 if (err) return (err);
575 }
576 *overall_loudness_info_present = (*info_count > 0);
577 return (0);
578 }
579
580 WORD32
impd_high_pass_loudness_adjust_info(ia_loudness_info_struct * loudness_info,WORD32 * loudness_hp_adjust_present,FLOAT32 * loudness_hp_adjust)581 impd_high_pass_loudness_adjust_info(ia_loudness_info_struct* loudness_info,
582 WORD32* loudness_hp_adjust_present,
583 FLOAT32* loudness_hp_adjust) {
584 WORD32 m, k;
585
586 *loudness_hp_adjust_present = 0;
587 *loudness_hp_adjust = 0.0f;
588 for (m = 0; m < loudness_info->measurement_count; m++) {
589 if (loudness_info->loudness_measure[m].measurement_system ==
590 MEASUREMENT_SYSTEM_BS_1770_4_PRE_PROCESSING) {
591 for (k = 0; k < loudness_info->measurement_count; k++) {
592 if (loudness_info->loudness_measure[k].measurement_system ==
593 MEASUREMENT_SYSTEM_BS_1770_4) {
594 if (loudness_info->loudness_measure[m].method_def ==
595 loudness_info->loudness_measure[k].method_def) {
596 *loudness_hp_adjust_present = 1;
597 *loudness_hp_adjust =
598 loudness_info->loudness_measure[m].method_val -
599 loudness_info->loudness_measure[k].method_val;
600 }
601 }
602 }
603 }
604 }
605 return (0);
606 }
607
impd_find_high_pass_loudness_adjust(ia_drc_loudness_info_set_struct * pstr_loudness_info,WORD32 requested_dwnmix_id,WORD32 drc_set_id_requested,WORD32 album_mode,FLOAT32 device_cutoff_freq,WORD32 * loudness_hp_adjust_present,FLOAT32 * loudness_hp_adjust)608 WORD32 impd_find_high_pass_loudness_adjust(
609 ia_drc_loudness_info_set_struct* pstr_loudness_info,
610 WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested, WORD32 album_mode,
611 FLOAT32 device_cutoff_freq, WORD32* loudness_hp_adjust_present,
612 FLOAT32* loudness_hp_adjust) {
613 WORD32 n, err;
614 WORD32 loudness_drc_set_id_requested;
615
616 if (drc_set_id_requested < 0) {
617 loudness_drc_set_id_requested = 0;
618 } else {
619 loudness_drc_set_id_requested = drc_set_id_requested;
620 }
621
622 *loudness_hp_adjust_present = 0;
623
624 if (album_mode == 1) {
625 for (n = 0; n < pstr_loudness_info->loudness_info_album_count; n++) {
626 if ((requested_dwnmix_id ==
627 pstr_loudness_info->str_loudness_info_album[n].downmix_id) ||
628 (ID_FOR_ANY_DOWNMIX ==
629 pstr_loudness_info->str_loudness_info_album[n].downmix_id)) {
630 if (loudness_drc_set_id_requested ==
631 pstr_loudness_info->str_loudness_info_album[n].drc_set_id) {
632 err = impd_high_pass_loudness_adjust_info(
633 &(pstr_loudness_info->loudness_info[n]),
634 loudness_hp_adjust_present, loudness_hp_adjust);
635 if (err) return (err);
636 }
637 }
638 }
639 }
640 if (*loudness_hp_adjust_present == 0) {
641 for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) {
642 if ((requested_dwnmix_id ==
643 pstr_loudness_info->loudness_info[n].downmix_id) ||
644 (ID_FOR_ANY_DOWNMIX ==
645 pstr_loudness_info->loudness_info[n].downmix_id)) {
646 if (loudness_drc_set_id_requested ==
647 pstr_loudness_info->loudness_info[n].drc_set_id) {
648 err = impd_high_pass_loudness_adjust_info(
649 &(pstr_loudness_info->loudness_info[n]),
650 loudness_hp_adjust_present, loudness_hp_adjust);
651 if (err) return (err);
652 }
653 }
654 }
655 }
656 if (*loudness_hp_adjust_present == 0) {
657 for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) {
658 if (ID_FOR_BASE_LAYOUT ==
659 pstr_loudness_info->loudness_info[n].downmix_id) /* base layout */
660 {
661 if (loudness_drc_set_id_requested ==
662 pstr_loudness_info->loudness_info[n].drc_set_id) {
663 err = impd_high_pass_loudness_adjust_info(
664 &(pstr_loudness_info->loudness_info[n]),
665 loudness_hp_adjust_present, loudness_hp_adjust);
666 if (err) return (err);
667 }
668 }
669 }
670 }
671 if (*loudness_hp_adjust_present == 0) {
672 for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) {
673 if (ID_FOR_BASE_LAYOUT ==
674 pstr_loudness_info->loudness_info[n].downmix_id) /* base layout */
675 {
676 if (0 == pstr_loudness_info->loudness_info[n].drc_set_id) {
677 err = impd_high_pass_loudness_adjust_info(
678 &(pstr_loudness_info->loudness_info[n]),
679 loudness_hp_adjust_present, loudness_hp_adjust);
680 if (err) return (err);
681 }
682 }
683 }
684 }
685 if (*loudness_hp_adjust_present == 0) {
686 *loudness_hp_adjust = 0.0f;
687 } else {
688 *loudness_hp_adjust *=
689 (max(20.0f, min(500.0f, device_cutoff_freq)) - 20.0f) /
690 (500.0f - 20.0f);
691 }
692 return (0);
693 }
694
impd_init_loudness_control(ia_drc_sel_proc_params_struct * pstr_drc_sel_proc_params_struct,ia_drc_loudness_info_set_struct * pstr_loudness_info,WORD32 requested_dwnmix_id,WORD32 drc_set_id_requested,WORD32 num_compression_eq_count,WORD32 * num_compression_eq_id,WORD32 * loudness_info_count,WORD32 eq_set_id[],FLOAT32 loudness_normalization_gain_db[],FLOAT32 loudness[])695 WORD32 impd_init_loudness_control(
696 ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
697 ia_drc_loudness_info_set_struct* pstr_loudness_info,
698 WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested,
699 WORD32 num_compression_eq_count, WORD32* num_compression_eq_id,
700 WORD32* loudness_info_count, WORD32 eq_set_id[],
701 FLOAT32 loudness_normalization_gain_db[], FLOAT32 loudness[]) {
702 WORD32 err, k, info_count = 0, pre_lim_count;
703 WORD32 loudness_hp_adjust_present;
704 WORD32 overall_loudness_info_present;
705 FLOAT32 pre_proc_adjust;
706
707 k = 0;
708 if (drc_set_id_requested < 0) {
709 for (k = 0; k < num_compression_eq_count; k++) {
710 eq_set_id[k] = num_compression_eq_id[k];
711 loudness[k] = UNDEFINED_LOUDNESS_VALUE;
712 loudness_normalization_gain_db[k] = 0.0f;
713 }
714 }
715 if (k >= MAX_NUM_COMPRESSION_EQ) return UNEXPECTED_ERROR;
716 eq_set_id[k] = 0;
717
718 loudness[k] = UNDEFINED_LOUDNESS_VALUE;
719
720 loudness_normalization_gain_db[k] = 0.0f;
721 k++;
722
723 pre_lim_count = k;
724
725 if (pstr_drc_sel_proc_params_struct->loudness_normalization_on == 1) {
726 WORD32 n;
727 ia_loudness_info_struct* loudness_info[16];
728 err = impd_find_overall_loudness_info(
729 pstr_drc_sel_proc_params_struct, pstr_loudness_info,
730 requested_dwnmix_id, drc_set_id_requested,
731 &overall_loudness_info_present, &info_count, loudness_info);
732 if (err) return (err);
733
734 if (overall_loudness_info_present == 1) {
735 WORD32 requested_method_definition = METHOD_DEFINITION_PROGRAM_LOUDNESS;
736 WORD32 other_method_definition = METHOD_DEFINITION_PROGRAM_LOUDNESS;
737 WORD32 requested_preprocessing = 0;
738
739 const WORD32* system_bonus = measurement_system_default_tbl;
740
741 WORD32 match_measure;
742 FLOAT32 method_val = 0;
743
744 switch (pstr_drc_sel_proc_params_struct->loudness_measurement_method) {
745 case USER_METHOD_DEFINITION_DEFAULT:
746 case USER_METHOD_DEFINITION_PROGRAM_LOUDNESS:
747 requested_method_definition = METHOD_DEFINITION_PROGRAM_LOUDNESS;
748 other_method_definition = METHOD_DEFINITION_ANCHOR_LOUDNESS;
749 break;
750 case USER_METHOD_DEFINITION_ANCHOR_LOUDNESS:
751 requested_method_definition = METHOD_DEFINITION_ANCHOR_LOUDNESS;
752 other_method_definition = METHOD_DEFINITION_PROGRAM_LOUDNESS;
753 break;
754
755 default:
756 return (UNEXPECTED_ERROR);
757 break;
758 }
759
760 switch (pstr_drc_sel_proc_params_struct->loudness_measurement_system) {
761 case USER_MEASUREMENT_SYSTEM_DEFAULT:
762 case USER_MEASUREMENT_SYSTEM_BS_1770_4:
763 system_bonus = measurement_system_bs1770_3_tbl;
764 break;
765 case USER_MEASUREMENT_SYSTEM_USER:
766 system_bonus = measurement_system_user_tbl;
767 break;
768 case USER_MEASUREMENT_SYSTEM_EXPERT_PANEL:
769 system_bonus = measurement_system_expert_tbl;
770 break;
771 case USER_MEASUREMENT_SYSTEM_RESERVED_A:
772 system_bonus = measurement_system_rms_a_tbl;
773 break;
774 case USER_MEASUREMENT_SYSTEM_RESERVED_B:
775 system_bonus = measurement_system_rms_b_tbl;
776 break;
777 case USER_MEASUREMENT_SYSTEM_RESERVED_C:
778 system_bonus = measurement_system_rms_c_tbl;
779 break;
780 case USER_MEASUREMENT_SYSTEM_RESERVED_D:
781 system_bonus = measurement_system_rms_d_tbl;
782 break;
783 case USER_MEASUREMENT_SYSTEM_RESERVED_E:
784 system_bonus = measurement_system_rms_e_tbl;
785 break;
786
787 default:
788 return (UNEXPECTED_ERROR);
789 break;
790 }
791
792 switch (pstr_drc_sel_proc_params_struct->loudness_measurement_pre_proc) {
793 case USER_LOUDNESS_PREPROCESSING_DEFAULT:
794 case USER_LOUDNESS_PREPROCESSING_OFF:
795 requested_preprocessing = 0;
796 break;
797 case USER_LOUDNESS_PREPROCESSING_HIGHPASS:
798 requested_preprocessing = 1;
799 break;
800
801 default:
802 return (UNEXPECTED_ERROR);
803 break;
804 }
805
806 for (k = 0; k < info_count; k++) {
807 match_measure = -1;
808 for (n = 0; n < loudness_info[k]->measurement_count; n++) {
809 ia_loudness_measure_struct* loudness_measure =
810 &(loudness_info[k]->loudness_measure[n]);
811 if (match_measure <
812 system_bonus[loudness_measure->measurement_system] &&
813 requested_method_definition == loudness_measure->method_def) {
814 method_val = loudness_measure->method_val;
815 match_measure = system_bonus[loudness_measure->measurement_system];
816 }
817 }
818 if (match_measure == -1) {
819 for (n = 0; n < loudness_info[k]->measurement_count; n++) {
820 ia_loudness_measure_struct* loudness_measure =
821 &(loudness_info[k]->loudness_measure[n]);
822 if (match_measure <
823 system_bonus[loudness_measure->measurement_system] &&
824 other_method_definition == loudness_measure->method_def) {
825 method_val = loudness_measure->method_val;
826 match_measure =
827 system_bonus[loudness_measure->measurement_system];
828 }
829 }
830 }
831
832 if (requested_preprocessing == 1) {
833 err = impd_find_high_pass_loudness_adjust(
834 pstr_loudness_info, requested_dwnmix_id, drc_set_id_requested,
835 pstr_drc_sel_proc_params_struct->album_mode,
836 (FLOAT32)
837 pstr_drc_sel_proc_params_struct->device_cut_off_frequency,
838 &loudness_hp_adjust_present, &pre_proc_adjust);
839 if (err) return (err);
840
841 if (loudness_hp_adjust_present == 0) {
842 pre_proc_adjust = -2.0f;
843 }
844 method_val += pre_proc_adjust;
845 }
846
847 eq_set_id[k] = 0;
848
849 loudness_normalization_gain_db[k] =
850 pstr_drc_sel_proc_params_struct->target_loudness - method_val;
851 loudness[k] = method_val;
852 }
853 }
854 }
855 if (info_count > 0) {
856 *loudness_info_count = info_count;
857 } else {
858 *loudness_info_count = pre_lim_count;
859 }
860
861 return (0);
862 }
863
864 #define MIXING_LEVEL_DEFAULT 85.0f
865 WORD32
impd_mixing_level_info(ia_drc_sel_proc_params_struct * pstr_drc_sel_proc_params_struct,ia_drc_loudness_info_set_struct * pstr_loudness_info,WORD32 requested_dwnmix_id,WORD32 drc_set_id_requested,WORD32 eq_set_id_requested,FLOAT32 * mixing_level)866 impd_mixing_level_info(
867 ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
868 ia_drc_loudness_info_set_struct* pstr_loudness_info,
869 WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested,
870 WORD32 eq_set_id_requested, FLOAT32* mixing_level) {
871 WORD32 n, k, info_count;
872 WORD32 album_mode = pstr_drc_sel_proc_params_struct->album_mode;
873 WORD32 loudness_drc_set_id_requested;
874 ia_loudness_info_struct* loudness_info;
875
876 *mixing_level = MIXING_LEVEL_DEFAULT;
877 if (drc_set_id_requested < 0) {
878 loudness_drc_set_id_requested = 0;
879 } else {
880 loudness_drc_set_id_requested = drc_set_id_requested;
881 }
882 if (album_mode == 1) {
883 info_count = pstr_loudness_info->loudness_info_album_count;
884 loudness_info = pstr_loudness_info->str_loudness_info_album;
885 } else {
886 info_count = pstr_loudness_info->loudness_info_count;
887 loudness_info = pstr_loudness_info->loudness_info;
888 }
889 for (n = 0; n < info_count; n++) {
890 if ((requested_dwnmix_id == loudness_info[n].downmix_id) ||
891 (ID_FOR_ANY_DOWNMIX == loudness_info[n].downmix_id)) {
892 if (loudness_drc_set_id_requested == loudness_info[n].drc_set_id) {
893 if (eq_set_id_requested == loudness_info[n].eq_set_id) {
894 for (k = 0; k < loudness_info[n].measurement_count; k++) {
895 if (loudness_info[n].loudness_measure[k].method_def ==
896 METHOD_DEFINITION_MIXING_LEVEL) {
897 *mixing_level = loudness_info[n].loudness_measure[k].method_val;
898 break;
899 }
900 }
901 }
902 }
903 }
904 }
905 return (0);
906 }
907