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" 31 WORD32 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 for (k = 0; k < drc_instructions_drc_tmp->dwnmix_id_count; k++) { 308 if (ID_FOR_BASE_LAYOUT == 309 drc_instructions_drc_tmp->downmix_id[k]) { 310 if (drc_instructions_drc_tmp->limiter_peak_target_present) { 311 eq_set_id[peak_count] = -1; 312 signal_peak_level[peak_count] = 313 drc_instructions_drc_tmp->limiter_peak_target + 314 signal_peak_level_tmp; 315 explicit_peak_information_present[peak_count] = 0; 316 match_found_flag = 1; 317 peak_count++; 318 } 319 } 320 break; 321 } 322 } 323 } 324 } 325 } 326 } 327 if (peak_count > 0) { 328 *peak_info_count = peak_count; 329 } else { 330 *peak_info_count = pre_lim_count; 331 } 332 return (0); 333 } 334 335 WORD32 336 impd_extract_loudness_peak_to_average_info( 337 ia_loudness_info_struct* loudness_info, WORD32 dyn_range_measurement_type, 338 WORD32* loudness_peak_2_avg_value_present, 339 FLOAT32* loudness_peak_2_avg_value) { 340 WORD32 k; 341 WORD32 program_loudness_present = 0; 342 WORD32 peak_loudness_present = 0; 343 WORD32 match_measure_program_loudness = 0; 344 WORD32 match_measure_peak_loudness = 0; 345 FLOAT32 program_loudness = 0.0f; 346 FLOAT32 peak_loudness = 0.0f; 347 ia_loudness_measure_struct* loudness_measure = NULL; 348 349 for (k = 0; k < loudness_info->measurement_count; k++) { 350 loudness_measure = &(loudness_info->loudness_measure[k]); 351 if (loudness_measure->method_def == METHOD_DEFINITION_PROGRAM_LOUDNESS) { 352 if (match_measure_program_loudness < 353 measurement_method_prog_loudness_tbl[loudness_measure 354 ->measurement_system]) { 355 program_loudness = loudness_measure->method_val; 356 program_loudness_present = 1; 357 match_measure_program_loudness = 358 measurement_method_prog_loudness_tbl[loudness_measure 359 ->measurement_system]; 360 } 361 } 362 switch (dyn_range_measurement_type) { 363 case SHORT_TERM_LOUDNESS_TO_AVG: 364 if (loudness_measure->method_def == 365 METHOD_DEFINITION_SHORT_TERM_LOUDNESS_MAX) { 366 if (match_measure_peak_loudness < 367 measurement_method_peak_loudness_tbl[loudness_measure 368 ->measurement_system]) { 369 peak_loudness = loudness_measure->method_val; 370 peak_loudness_present = 1; 371 match_measure_peak_loudness = 372 measurement_method_peak_loudness_tbl[loudness_measure 373 ->measurement_system]; 374 } 375 } 376 break; 377 378 case MOMENTARY_LOUDNESS_TO_AVG: 379 if (loudness_measure->method_def == 380 METHOD_DEFINITION_MOMENTARY_LOUDNESS_MAX) { 381 if (match_measure_peak_loudness < 382 measurement_method_peak_loudness_tbl[loudness_measure 383 ->measurement_system]) { 384 peak_loudness = loudness_measure->method_val; 385 peak_loudness_present = 1; 386 match_measure_peak_loudness = 387 measurement_method_peak_loudness_tbl[loudness_measure 388 ->measurement_system]; 389 } 390 } 391 break; 392 393 case TOP_OF_LOUDNESS_RANGE_TO_AVG: 394 if (loudness_measure->method_def == 395 METHOD_DEFINITION_MAX_OF_LOUDNESS_RANGE) { 396 if (match_measure_peak_loudness < 397 measurement_method_peak_loudness_tbl[loudness_measure 398 ->measurement_system]) { 399 peak_loudness = loudness_measure->method_val; 400 peak_loudness_present = 1; 401 match_measure_peak_loudness = 402 measurement_method_peak_loudness_tbl[loudness_measure 403 ->measurement_system]; 404 } 405 } 406 break; 407 408 default: 409 return (UNEXPECTED_ERROR); 410 411 break; 412 } 413 } 414 if ((program_loudness_present == 1) && (peak_loudness_present == 1)) { 415 *loudness_peak_2_avg_value = peak_loudness - program_loudness; 416 *loudness_peak_2_avg_value_present = 1; 417 } 418 return (0); 419 } 420 421 WORD32 impd_loudness_peak_to_average_info( 422 ia_drc_loudness_info_set_struct* pstr_loudness_info, 423 ia_drc_instructions_struct* str_drc_instruction_str, 424 WORD32 requested_dwnmix_id, WORD32 dyn_range_measurement_type, 425 WORD32 album_mode, WORD32* loudness_peak_2_avg_value_present, 426 FLOAT32* loudness_peak_2_avg_value) { 427 WORD32 n, err; 428 WORD32 drc_set_id = max(0, str_drc_instruction_str->drc_set_id); 429 430 *loudness_peak_2_avg_value_present = 0; 431 432 if (album_mode == 1) { 433 for (n = 0; n < pstr_loudness_info->loudness_info_album_count; n++) { 434 ia_loudness_info_struct* loudness_info = 435 &(pstr_loudness_info->str_loudness_info_album[n]); 436 if (drc_set_id == loudness_info->drc_set_id) { 437 if (requested_dwnmix_id == loudness_info->downmix_id) { 438 err = impd_extract_loudness_peak_to_average_info( 439 loudness_info, dyn_range_measurement_type, 440 loudness_peak_2_avg_value_present, loudness_peak_2_avg_value); 441 if (err) return (err); 442 } 443 } 444 } 445 } 446 if (*loudness_peak_2_avg_value_present == 0) { 447 for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) { 448 ia_loudness_info_struct* loudness_info = 449 &(pstr_loudness_info->loudness_info[n]); 450 if (drc_set_id == loudness_info->drc_set_id) { 451 if (requested_dwnmix_id == loudness_info->downmix_id) { 452 err = impd_extract_loudness_peak_to_average_info( 453 loudness_info, dyn_range_measurement_type, 454 loudness_peak_2_avg_value_present, loudness_peak_2_avg_value); 455 if (err) return (err); 456 } 457 } 458 } 459 } 460 return (0); 461 } 462 463 WORD32 impd_overall_loudness_present(ia_loudness_info_struct* loudness_info, 464 WORD32* loudness_info_present) { 465 WORD32 m; 466 467 *loudness_info_present = 0; 468 for (m = 0; m < loudness_info->measurement_count; m++) { 469 if ((loudness_info->loudness_measure[m].method_def == 470 METHOD_DEFINITION_PROGRAM_LOUDNESS) || 471 (loudness_info->loudness_measure[m].method_def == 472 METHOD_DEFINITION_ANCHOR_LOUDNESS)) { 473 *loudness_info_present = 1; 474 } 475 } 476 return (0); 477 } 478 479 WORD32 impd_check_loud_info(WORD32 loudness_info_count, 480 ia_loudness_info_struct* loudness_info, 481 WORD32 requested_dwnmix_id, 482 WORD32 drc_set_id_requested, WORD32* info_count, 483 ia_loudness_info_struct* loudness_info_matching[]) { 484 WORD32 n, err; 485 WORD32 loudness_info_present; 486 for (n = 0; n < loudness_info_count; n++) { 487 if (requested_dwnmix_id == loudness_info[n].downmix_id) { 488 if (drc_set_id_requested == loudness_info[n].drc_set_id) { 489 err = impd_overall_loudness_present(&(loudness_info[n]), 490 &loudness_info_present); 491 if (err) return (err); 492 if (loudness_info_present) { 493 loudness_info_matching[*info_count] = &(loudness_info[n]); 494 (*info_count)++; 495 } 496 } 497 } 498 } 499 500 return (0); 501 } 502 503 WORD32 impd_check_loud_payload( 504 WORD32 loudness_info_count, ia_loudness_info_struct* loudness_info, 505 WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested, WORD32* info_count, 506 ia_loudness_info_struct* loudness_info_matching[]) { 507 WORD32 err = 0; 508 509 err = impd_check_loud_info(loudness_info_count, loudness_info, 510 requested_dwnmix_id, 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 ID_FOR_ANY_DOWNMIX, drc_set_id_requested, 515 info_count, 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_ANY_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 requested_dwnmix_id, ID_FOR_NO_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_ANY_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_ANY_DOWNMIX, ID_FOR_NO_DRC, info_count, 531 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, drc_set_id_requested, 535 info_count, 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_ANY_DRC, info_count, 539 loudness_info_matching); 540 if (err || *info_count) goto matchEnd; 541 err = impd_check_loud_info(loudness_info_count, loudness_info, 542 ID_FOR_BASE_LAYOUT, ID_FOR_NO_DRC, info_count, 543 loudness_info_matching); 544 if (err || *info_count) goto matchEnd; 545 matchEnd: 546 return (err); 547 } 548 549 WORD32 impd_find_overall_loudness_info( 550 ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct, 551 ia_drc_loudness_info_set_struct* pstr_loudness_info, 552 WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested, 553 WORD32* overall_loudness_info_present, WORD32* info_count, 554 ia_loudness_info_struct* loudness_info_matching[]) { 555 WORD32 err; 556 WORD32 loudness_drc_set_id_requested; 557 558 *info_count = 0; 559 if (drc_set_id_requested < 0) { 560 loudness_drc_set_id_requested = ID_FOR_NO_DRC; 561 } else { 562 loudness_drc_set_id_requested = drc_set_id_requested; 563 } 564 if (pstr_drc_sel_proc_params_struct->album_mode == 1) { 565 err = impd_check_loud_payload( 566 pstr_loudness_info->loudness_info_album_count, 567 pstr_loudness_info->str_loudness_info_album, requested_dwnmix_id, 568 loudness_drc_set_id_requested, info_count, loudness_info_matching); 569 if (err) return (err); 570 } 571 if (*info_count == 0) { 572 err = impd_check_loud_payload(pstr_loudness_info->loudness_info_count, 573 pstr_loudness_info->loudness_info, 574 requested_dwnmix_id, 575 loudness_drc_set_id_requested, 576 577 info_count, loudness_info_matching); 578 if (err) return (err); 579 } 580 *overall_loudness_info_present = (*info_count > 0); 581 return (0); 582 } 583 584 WORD32 585 impd_high_pass_loudness_adjust_info(ia_loudness_info_struct* loudness_info, 586 WORD32* loudness_hp_adjust_present, 587 FLOAT32* loudness_hp_adjust) { 588 WORD32 m, k; 589 590 *loudness_hp_adjust_present = 0; 591 *loudness_hp_adjust = 0.0f; 592 for (m = 0; m < loudness_info->measurement_count; m++) { 593 if (loudness_info->loudness_measure[m].measurement_system == 594 MEASUREMENT_SYSTEM_BS_1770_4_PRE_PROCESSING) { 595 for (k = 0; k < loudness_info->measurement_count; k++) { 596 if (loudness_info->loudness_measure[k].measurement_system == 597 MEASUREMENT_SYSTEM_BS_1770_4) { 598 if (loudness_info->loudness_measure[m].method_def == 599 loudness_info->loudness_measure[k].method_def) { 600 *loudness_hp_adjust_present = 1; 601 *loudness_hp_adjust = 602 loudness_info->loudness_measure[m].method_val - 603 loudness_info->loudness_measure[k].method_val; 604 } 605 } 606 } 607 } 608 } 609 return (0); 610 } 611 612 WORD32 impd_find_high_pass_loudness_adjust( 613 ia_drc_loudness_info_set_struct* pstr_loudness_info, 614 WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested, WORD32 album_mode, 615 FLOAT32 device_cutoff_freq, WORD32* loudness_hp_adjust_present, 616 FLOAT32* loudness_hp_adjust) { 617 WORD32 n, err; 618 WORD32 loudness_drc_set_id_requested; 619 620 if (drc_set_id_requested < 0) { 621 loudness_drc_set_id_requested = 0; 622 } else { 623 loudness_drc_set_id_requested = drc_set_id_requested; 624 } 625 626 *loudness_hp_adjust_present = 0; 627 628 if (album_mode == 1) { 629 for (n = 0; n < pstr_loudness_info->loudness_info_album_count; n++) { 630 if ((requested_dwnmix_id == 631 pstr_loudness_info->str_loudness_info_album[n].downmix_id) || 632 (ID_FOR_ANY_DOWNMIX == 633 pstr_loudness_info->str_loudness_info_album[n].downmix_id)) { 634 if (loudness_drc_set_id_requested == 635 pstr_loudness_info->str_loudness_info_album[n].drc_set_id) { 636 err = impd_high_pass_loudness_adjust_info( 637 &(pstr_loudness_info->loudness_info[n]), 638 loudness_hp_adjust_present, loudness_hp_adjust); 639 if (err) return (err); 640 } 641 } 642 } 643 } 644 if (*loudness_hp_adjust_present == 0) { 645 for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) { 646 if ((requested_dwnmix_id == 647 pstr_loudness_info->loudness_info[n].downmix_id) || 648 (ID_FOR_ANY_DOWNMIX == 649 pstr_loudness_info->loudness_info[n].downmix_id)) { 650 if (loudness_drc_set_id_requested == 651 pstr_loudness_info->loudness_info[n].drc_set_id) { 652 err = impd_high_pass_loudness_adjust_info( 653 &(pstr_loudness_info->loudness_info[n]), 654 loudness_hp_adjust_present, loudness_hp_adjust); 655 if (err) return (err); 656 } 657 } 658 } 659 } 660 if (*loudness_hp_adjust_present == 0) { 661 for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) { 662 if (ID_FOR_BASE_LAYOUT == 663 pstr_loudness_info->loudness_info[n].downmix_id) /* base layout */ 664 { 665 if (loudness_drc_set_id_requested == 666 pstr_loudness_info->loudness_info[n].drc_set_id) { 667 err = impd_high_pass_loudness_adjust_info( 668 &(pstr_loudness_info->loudness_info[n]), 669 loudness_hp_adjust_present, loudness_hp_adjust); 670 if (err) return (err); 671 } 672 } 673 } 674 } 675 if (*loudness_hp_adjust_present == 0) { 676 for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) { 677 if (ID_FOR_BASE_LAYOUT == 678 pstr_loudness_info->loudness_info[n].downmix_id) /* base layout */ 679 { 680 if (0 == pstr_loudness_info->loudness_info[n].drc_set_id) { 681 err = impd_high_pass_loudness_adjust_info( 682 &(pstr_loudness_info->loudness_info[n]), 683 loudness_hp_adjust_present, loudness_hp_adjust); 684 if (err) return (err); 685 } 686 } 687 } 688 } 689 if (*loudness_hp_adjust_present == 0) { 690 *loudness_hp_adjust = 0.0f; 691 } else { 692 *loudness_hp_adjust *= 693 (max(20.0f, min(500.0f, device_cutoff_freq)) - 20.0f) / 694 (500.0f - 20.0f); 695 } 696 return (0); 697 } 698 699 WORD32 impd_init_loudness_control( 700 ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct, 701 ia_drc_loudness_info_set_struct* pstr_loudness_info, 702 WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested, 703 WORD32 num_compression_eq_count, WORD32* num_compression_eq_id, 704 WORD32* loudness_info_count, WORD32 eq_set_id[], 705 FLOAT32 loudness_normalization_gain_db[], FLOAT32 loudness[]) { 706 WORD32 err, k, info_count = 0, pre_lim_count; 707 WORD32 loudness_hp_adjust_present; 708 WORD32 overall_loudness_info_present; 709 FLOAT32 pre_proc_adjust; 710 711 k = 0; 712 if (drc_set_id_requested < 0) { 713 for (k = 0; k < num_compression_eq_count; k++) { 714 eq_set_id[k] = num_compression_eq_id[k]; 715 loudness[k] = UNDEFINED_LOUDNESS_VALUE; 716 loudness_normalization_gain_db[k] = 0.0f; 717 } 718 } 719 if (k >= MAX_NUM_COMPRESSION_EQ) return UNEXPECTED_ERROR; 720 eq_set_id[k] = 0; 721 722 loudness[k] = UNDEFINED_LOUDNESS_VALUE; 723 724 loudness_normalization_gain_db[k] = 0.0f; 725 k++; 726 727 pre_lim_count = k; 728 729 if (pstr_drc_sel_proc_params_struct->loudness_normalization_on == 1) { 730 WORD32 n; 731 ia_loudness_info_struct* loudness_info[16]; 732 err = impd_find_overall_loudness_info( 733 pstr_drc_sel_proc_params_struct, pstr_loudness_info, 734 requested_dwnmix_id, drc_set_id_requested, 735 &overall_loudness_info_present, &info_count, loudness_info); 736 if (err) return (err); 737 738 if (overall_loudness_info_present == 1) { 739 WORD32 requested_method_definition = METHOD_DEFINITION_PROGRAM_LOUDNESS; 740 WORD32 other_method_definition = METHOD_DEFINITION_PROGRAM_LOUDNESS; 741 WORD32 requested_measurement_system = MEASUREMENT_SYSTEM_BS_1770_4; 742 WORD32 requested_preprocessing = 0; 743 744 const WORD32* system_bonus = measurement_system_default_tbl; 745 746 WORD32 match_measure; 747 FLOAT32 method_val = 0; 748 749 switch (pstr_drc_sel_proc_params_struct->loudness_measurement_method) { 750 case USER_METHOD_DEFINITION_DEFAULT: 751 case USER_METHOD_DEFINITION_PROGRAM_LOUDNESS: 752 requested_method_definition = METHOD_DEFINITION_PROGRAM_LOUDNESS; 753 other_method_definition = METHOD_DEFINITION_ANCHOR_LOUDNESS; 754 break; 755 case USER_METHOD_DEFINITION_ANCHOR_LOUDNESS: 756 requested_method_definition = METHOD_DEFINITION_ANCHOR_LOUDNESS; 757 other_method_definition = METHOD_DEFINITION_PROGRAM_LOUDNESS; 758 break; 759 760 default: 761 return (UNEXPECTED_ERROR); 762 break; 763 } 764 765 switch (pstr_drc_sel_proc_params_struct->loudness_measurement_system) { 766 case USER_MEASUREMENT_SYSTEM_DEFAULT: 767 case USER_MEASUREMENT_SYSTEM_BS_1770_4: 768 requested_measurement_system = MEASUREMENT_SYSTEM_BS_1770_4; 769 system_bonus = measurement_system_bs1770_3_tbl; 770 break; 771 case USER_MEASUREMENT_SYSTEM_USER: 772 requested_measurement_system = MEASUREMENT_SYSTEM_USER; 773 system_bonus = measurement_system_user_tbl; 774 break; 775 case USER_MEASUREMENT_SYSTEM_EXPERT_PANEL: 776 requested_measurement_system = MEASUREMENT_SYSTEM_EXPERT_PANEL; 777 system_bonus = measurement_system_expert_tbl; 778 break; 779 case USER_MEASUREMENT_SYSTEM_RESERVED_A: 780 requested_measurement_system = USER_MEASUREMENT_SYSTEM_RESERVED_A; 781 system_bonus = measurement_system_rms_a_tbl; 782 break; 783 case USER_MEASUREMENT_SYSTEM_RESERVED_B: 784 requested_measurement_system = USER_MEASUREMENT_SYSTEM_RESERVED_B; 785 system_bonus = measurement_system_rms_b_tbl; 786 break; 787 case USER_MEASUREMENT_SYSTEM_RESERVED_C: 788 requested_measurement_system = USER_MEASUREMENT_SYSTEM_RESERVED_C; 789 system_bonus = measurement_system_rms_c_tbl; 790 break; 791 case USER_MEASUREMENT_SYSTEM_RESERVED_D: 792 requested_measurement_system = USER_MEASUREMENT_SYSTEM_RESERVED_D; 793 system_bonus = measurement_system_rms_d_tbl; 794 break; 795 case USER_MEASUREMENT_SYSTEM_RESERVED_E: 796 requested_measurement_system = USER_MEASUREMENT_SYSTEM_RESERVED_E; 797 system_bonus = measurement_system_rms_e_tbl; 798 break; 799 800 default: 801 return (UNEXPECTED_ERROR); 802 break; 803 } 804 805 switch (pstr_drc_sel_proc_params_struct->loudness_measurement_pre_proc) { 806 case USER_LOUDNESS_PREPROCESSING_DEFAULT: 807 case USER_LOUDNESS_PREPROCESSING_OFF: 808 requested_preprocessing = 0; 809 break; 810 case USER_LOUDNESS_PREPROCESSING_HIGHPASS: 811 requested_preprocessing = 1; 812 break; 813 814 default: 815 return (UNEXPECTED_ERROR); 816 break; 817 } 818 819 for (k = 0; k < info_count; k++) { 820 match_measure = -1; 821 for (n = 0; n < loudness_info[k]->measurement_count; n++) { 822 ia_loudness_measure_struct* loudness_measure = 823 &(loudness_info[k]->loudness_measure[n]); 824 if (match_measure < 825 system_bonus[loudness_measure->measurement_system] && 826 requested_method_definition == loudness_measure->method_def) { 827 method_val = loudness_measure->method_val; 828 match_measure = system_bonus[loudness_measure->measurement_system]; 829 } 830 } 831 if (match_measure == -1) { 832 for (n = 0; n < loudness_info[k]->measurement_count; n++) { 833 ia_loudness_measure_struct* loudness_measure = 834 &(loudness_info[k]->loudness_measure[n]); 835 if (match_measure < 836 system_bonus[loudness_measure->measurement_system] && 837 other_method_definition == loudness_measure->method_def) { 838 method_val = loudness_measure->method_val; 839 match_measure = 840 system_bonus[loudness_measure->measurement_system]; 841 } 842 } 843 } 844 845 if (requested_preprocessing == 1) { 846 err = impd_find_high_pass_loudness_adjust( 847 pstr_loudness_info, requested_dwnmix_id, drc_set_id_requested, 848 pstr_drc_sel_proc_params_struct->album_mode, 849 (FLOAT32) 850 pstr_drc_sel_proc_params_struct->device_cut_off_frequency, 851 &loudness_hp_adjust_present, &pre_proc_adjust); 852 if (err) return (err); 853 854 if (loudness_hp_adjust_present == 0) { 855 pre_proc_adjust = -2.0f; 856 } 857 method_val += pre_proc_adjust; 858 } 859 860 eq_set_id[k] = 0; 861 862 loudness_normalization_gain_db[k] = 863 pstr_drc_sel_proc_params_struct->target_loudness - method_val; 864 loudness[k] = method_val; 865 } 866 } 867 } 868 if (info_count > 0) { 869 *loudness_info_count = info_count; 870 } else { 871 *loudness_info_count = pre_lim_count; 872 } 873 874 return (0); 875 } 876 877 #define MIXING_LEVEL_DEFAULT 85.0f 878 WORD32 879 impd_mixing_level_info( 880 ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct, 881 ia_drc_loudness_info_set_struct* pstr_loudness_info, 882 WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested, 883 WORD32 eq_set_id_requested, FLOAT32* mixing_level) { 884 WORD32 n, k, info_count; 885 WORD32 album_mode = pstr_drc_sel_proc_params_struct->album_mode; 886 WORD32 loudness_drc_set_id_requested; 887 ia_loudness_info_struct* loudness_info; 888 889 *mixing_level = MIXING_LEVEL_DEFAULT; 890 if (drc_set_id_requested < 0) { 891 loudness_drc_set_id_requested = 0; 892 } else { 893 loudness_drc_set_id_requested = drc_set_id_requested; 894 } 895 if (album_mode == 1) { 896 info_count = pstr_loudness_info->loudness_info_album_count; 897 loudness_info = pstr_loudness_info->str_loudness_info_album; 898 } else { 899 info_count = pstr_loudness_info->loudness_info_count; 900 loudness_info = pstr_loudness_info->loudness_info; 901 } 902 for (n = 0; n < info_count; n++) { 903 if ((requested_dwnmix_id == loudness_info[n].downmix_id) || 904 (ID_FOR_ANY_DOWNMIX == loudness_info[n].downmix_id)) { 905 if (loudness_drc_set_id_requested == loudness_info[n].drc_set_id) { 906 if (eq_set_id_requested == loudness_info[n].eq_set_id) { 907 for (k = 0; k < loudness_info[n].measurement_count; k++) { 908 if (loudness_info[n].loudness_measure[k].method_def == 909 METHOD_DEFINITION_MIXING_LEVEL) { 910 *mixing_level = loudness_info[n].loudness_measure[k].method_val; 911 break; 912 } 913 } 914 } 915 } 916 } 917 } 918 return (0); 919 } 920