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