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