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