libxaac/decoder/drc_src/impd_drc_selection_process_drcset_selection.c
Rajat Kumar 93ade1f683 Fix to define all tables as const in libxaac
libxaac had few tables which were not declared as constants.
Added const and did corresponding changes to build and
execute.

Bug:128433649
Test: Manual Review

Change-Id: I1babf22a45fbd595c5a9c67804ecdc0317ebb96c
2019-07-17 12:24:16 -07:00

1552 lines
61 KiB
C

/******************************************************************************
*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "impd_type_def.h"
#include "impd_drc_extr_delta_coded_info.h"
#include "impd_drc_common.h"
#include "impd_drc_struct.h"
#include "impd_drc_interface.h"
#include "impd_drc_selection_process.h"
#include "impd_drc_sel_proc_drc_set_sel.h"
#include "impd_drc_loudness_control.h"
#include "impd_drc_filter_bank.h"
#include "impd_drc_rom.h"
static const WORD32 effect_types_request_table[] = {
EFFECT_BIT_NIGHT, EFFECT_BIT_NOISY, EFFECT_BIT_LIMITED,
EFFECT_BIT_LOWLEVEL, EFFECT_BIT_DIALOG, EFFECT_BIT_GENERAL_COMPR,
EFFECT_BIT_EXPAND, EFFECT_BIT_ARTISTIC};
WORD32 impd_validate_requested_drc_feature(
ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct) {
WORD32 i, j;
for (i = 0; i < pstr_drc_sel_proc_params_struct->num_drc_feature_requests;
i++) {
switch (pstr_drc_sel_proc_params_struct->drc_feature_req_type[i]) {
case MATCH_EFFECT_TYPE:
for (j = 0; j < pstr_drc_sel_proc_params_struct
->desired_num_drc_effects_of_requested[i];
j++) {
if (pstr_drc_sel_proc_params_struct
->requested_drc_effect_type[i][j] ==
EFFECT_TYPE_REQUESTED_NONE) {
if (pstr_drc_sel_proc_params_struct
->desired_num_drc_effects_of_requested[i] > 1) {
return (UNEXPECTED_ERROR);
}
}
}
break;
case MATCH_DYNAMIC_RANGE:
break;
case MATCH_DRC_CHARACTERISTIC:
break;
default:
return (UNEXPECTED_ERROR);
break;
}
}
return (0);
}
WORD32 impd_find_drc_instructions_uni_drc(
ia_drc_config* drc_config, WORD32 drc_set_id_requested,
ia_drc_instructions_struct** str_drc_instruction_str) {
WORD32 i;
for (i = 0; i < drc_config->drc_instructions_uni_drc_count; i++) {
if (drc_set_id_requested ==
drc_config->str_drc_instruction_str[i].drc_set_id)
break;
}
if (i == drc_config->drc_instructions_uni_drc_count) {
return (UNEXPECTED_ERROR);
}
*str_drc_instruction_str = &drc_config->str_drc_instruction_str[i];
return (0);
}
WORD32 impd_map_requested_effect_bit_idx(WORD32 requested_effect_type,
WORD32* effect_bit_idx) {
switch (requested_effect_type) {
case EFFECT_TYPE_REQUESTED_NONE:
*effect_bit_idx = EFFECT_BIT_NONE;
break;
case EFFECT_TYPE_REQUESTED_NIGHT:
*effect_bit_idx = EFFECT_BIT_NIGHT;
break;
case EFFECT_TYPE_REQUESTED_NOISY:
*effect_bit_idx = EFFECT_BIT_NOISY;
break;
case EFFECT_TYPE_REQUESTED_LIMITED:
*effect_bit_idx = EFFECT_BIT_LIMITED;
break;
case EFFECT_TYPE_REQUESTED_LOWLEVEL:
*effect_bit_idx = EFFECT_BIT_LOWLEVEL;
break;
case EFFECT_TYPE_REQUESTED_DIALOG:
*effect_bit_idx = EFFECT_BIT_DIALOG;
break;
case EFFECT_TYPE_REQUESTED_GENERAL_COMPR:
*effect_bit_idx = EFFECT_BIT_GENERAL_COMPR;
break;
case EFFECT_TYPE_REQUESTED_EXPAND:
*effect_bit_idx = EFFECT_BIT_EXPAND;
break;
case EFFECT_TYPE_REQUESTED_ARTISTIC:
*effect_bit_idx = EFFECT_BIT_ARTISTIC;
break;
default:
return (UNEXPECTED_ERROR);
break;
}
return (0);
}
WORD32 impd_get_fading_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
pstr_drc_uni_sel_proc->drc_instructions_index[2] = -1;
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.album_mode == 0) {
WORD32 n;
ia_drc_instructions_struct* str_drc_instruction_str = NULL;
for (n = 0;
n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_uni_drc_count;
n++) {
str_drc_instruction_str =
&(pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]);
if (str_drc_instruction_str->drc_set_effect & EFFECT_BIT_FADE) {
if (str_drc_instruction_str->downmix_id[0] == ID_FOR_ANY_DOWNMIX) {
pstr_drc_uni_sel_proc->drc_instructions_index[2] = n;
} else {
return (UNEXPECTED_ERROR);
}
}
}
}
return (0);
}
WORD32 impd_get_ducking_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
WORD32 drc_instructions_index;
WORD32 n, k;
ia_drc_instructions_struct* str_drc_instruction_str;
WORD32 requested_dwnmix_id =
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.active_downmix_id;
pstr_drc_uni_sel_proc->drc_instructions_index[3] = -1;
drc_instructions_index = -1;
str_drc_instruction_str = NULL;
for (n = 0;
n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_uni_drc_count;
n++) {
str_drc_instruction_str =
&(pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]);
if (str_drc_instruction_str->drc_set_effect &
(EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) {
for (k = 0; k < str_drc_instruction_str->dwnmix_id_count; k++) {
if (str_drc_instruction_str->downmix_id[k] == requested_dwnmix_id) {
drc_instructions_index = n;
}
}
}
}
if (drc_instructions_index == -1) {
for (n = 0;
n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_uni_drc_count;
n++) {
str_drc_instruction_str =
&(pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]);
if (str_drc_instruction_str->drc_set_effect &
(EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) {
for (k = 0; k < str_drc_instruction_str->dwnmix_id_count; k++) {
if (str_drc_instruction_str->downmix_id[k] == ID_FOR_BASE_LAYOUT) {
drc_instructions_index = n;
}
}
}
}
}
if (drc_instructions_index > -1) {
pstr_drc_uni_sel_proc->drc_instructions_index[2] = -1;
pstr_drc_uni_sel_proc->drc_instructions_index[3] = drc_instructions_index;
}
return (0);
}
WORD32 impd_get_selected_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
WORD32 drc_set_id_selected) {
WORD32 n;
ia_drc_instructions_struct* str_drc_instruction_str = NULL;
for (n = 0; n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_count_plus;
n++) {
if (pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]
.drc_set_id == drc_set_id_selected)
break;
}
if (n == pstr_drc_uni_sel_proc->drc_config.drc_instructions_count_plus) {
return (EXTERNAL_ERROR);
}
pstr_drc_uni_sel_proc->drc_inst_index_sel = n;
str_drc_instruction_str = &(
pstr_drc_uni_sel_proc->drc_config
.str_drc_instruction_str[pstr_drc_uni_sel_proc->drc_inst_index_sel]);
pstr_drc_uni_sel_proc->drc_instructions_index[0] =
pstr_drc_uni_sel_proc->drc_inst_index_sel;
return (0);
}
WORD32 impd_get_dependent_drc_set(
ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
ia_drc_instructions_struct* str_drc_instruction_str = NULL;
str_drc_instruction_str = &(
pstr_drc_uni_sel_proc->drc_config
.str_drc_instruction_str[pstr_drc_uni_sel_proc->drc_inst_index_sel]);
if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
WORD32 n;
WORD32 drc_dependent_set_id = str_drc_instruction_str->depends_on_drc_set;
for (n = 0;
n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_count_plus;
n++) {
if (pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]
.drc_set_id == drc_dependent_set_id)
break;
}
if (n == pstr_drc_uni_sel_proc->drc_config.drc_instructions_count_plus) {
return (UNEXPECTED_ERROR);
}
pstr_drc_uni_sel_proc->drc_instructions_index[1] = n;
} else {
pstr_drc_uni_sel_proc->drc_instructions_index[1] = -1;
}
return (0);
}
WORD32 impd_get_dependent_drc_instructions(
const ia_drc_config* drc_config,
const ia_drc_instructions_struct* str_drc_instruction_str,
ia_drc_instructions_struct** drc_instructions_dependent) {
WORD32 j;
ia_drc_instructions_struct* dependent_drc = NULL;
for (j = 0; j < drc_config->drc_instructions_uni_drc_count; j++) {
dependent_drc =
(ia_drc_instructions_struct*)&(drc_config->str_drc_instruction_str[j]);
if (dependent_drc->drc_set_id ==
str_drc_instruction_str->depends_on_drc_set) {
break;
}
}
if (j == drc_config->drc_instructions_uni_drc_count) {
return (UNEXPECTED_ERROR);
}
if (dependent_drc->depends_on_drc_set_present == 1) {
return (UNEXPECTED_ERROR);
}
*drc_instructions_dependent = dependent_drc;
return (0);
}
WORD32 impd_select_drcs_without_compr_effects(
ia_drc_config* pstr_drc_config, WORD32* match_found_flag,
WORD32* selection_candidate_count,
ia_selection_candidate_info_struct* selection_candidate_info) {
WORD32 i, k, n;
WORD32 selection_candidate_step_2_count = 0;
ia_selection_candidate_info_struct
selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
WORD32 effect_types_request_table_size;
WORD32 match;
ia_drc_instructions_struct* str_drc_instruction_str;
effect_types_request_table_size =
sizeof(effect_types_request_table) / sizeof(WORD32);
k = 0;
for (i = 0; i < *selection_candidate_count; i++) {
str_drc_instruction_str = &(
pstr_drc_config->str_drc_instruction_str[selection_candidate_info[i]
.drc_instructions_index]);
match = 1;
for (n = 0; n < effect_types_request_table_size; n++) {
if ((str_drc_instruction_str->drc_set_effect &
effect_types_request_table[n]) != 0x0) {
match = 0;
}
}
if (match == 1) {
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
memcpy(&selection_candidate_info_step_2[k], &selection_candidate_info[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
}
selection_candidate_step_2_count = k;
if (selection_candidate_step_2_count > 0) {
*match_found_flag = 1;
for (i = 0; i < selection_candidate_step_2_count; i++) {
memcpy(&selection_candidate_info[i], &selection_candidate_info_step_2[i],
sizeof(ia_selection_candidate_info_struct));
*selection_candidate_count = selection_candidate_step_2_count;
}
} else {
*match_found_flag = 0;
}
return (0);
}
WORD32 impd_match_effect_type_attempt(
ia_drc_config* pstr_drc_config, WORD32 requested_effect_type,
WORD32 state_requested, WORD32* match_found_flag,
WORD32* selection_candidate_count,
ia_selection_candidate_info_struct* selection_candidate_info) {
WORD32 i, k, err;
WORD32 selection_candidate_step_2_count = 0;
ia_selection_candidate_info_struct
selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
ia_drc_instructions_struct* str_drc_instruction_str;
ia_drc_instructions_struct* drc_instructions_dependent;
WORD32 effect_bit_idx;
err =
impd_map_requested_effect_bit_idx(requested_effect_type, &effect_bit_idx);
if (err) return (err);
if (effect_bit_idx == EFFECT_BIT_NONE) {
err = impd_select_drcs_without_compr_effects(
pstr_drc_config, match_found_flag, selection_candidate_count,
selection_candidate_info);
if (err) return (err);
} else {
k = 0;
for (i = 0; i < *selection_candidate_count; i++) {
str_drc_instruction_str =
&(pstr_drc_config->str_drc_instruction_str
[selection_candidate_info[i].drc_instructions_index]);
if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
err = impd_get_dependent_drc_instructions(pstr_drc_config,
str_drc_instruction_str,
&drc_instructions_dependent);
if (err) return (err);
if (state_requested == 1) {
if (((str_drc_instruction_str->drc_set_effect & effect_bit_idx) !=
0x0) ||
((drc_instructions_dependent->drc_set_effect & effect_bit_idx) !=
0x0)) {
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
memcpy(&selection_candidate_info_step_2[k],
&selection_candidate_info[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
} else {
if (((str_drc_instruction_str->drc_set_effect & effect_bit_idx) ==
0x0) &&
((drc_instructions_dependent->drc_set_effect & effect_bit_idx) ==
0x0)) {
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
memcpy(&selection_candidate_info_step_2[k],
&selection_candidate_info[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
}
} else {
if (state_requested == 1) {
if ((str_drc_instruction_str->drc_set_effect & effect_bit_idx) !=
0x0) {
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
memcpy(&selection_candidate_info_step_2[k],
&selection_candidate_info[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
} else {
if ((str_drc_instruction_str->drc_set_effect & effect_bit_idx) ==
0x0) {
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
memcpy(&selection_candidate_info_step_2[k],
&selection_candidate_info[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
}
}
}
selection_candidate_step_2_count = k;
if (selection_candidate_step_2_count > 0) {
*match_found_flag = 1;
for (i = 0; i < selection_candidate_step_2_count; i++) {
*selection_candidate_count = selection_candidate_step_2_count;
memcpy(&selection_candidate_info[i],
&selection_candidate_info_step_2[i],
sizeof(ia_selection_candidate_info_struct));
}
} else {
*match_found_flag = 0;
}
}
return (0);
}
WORD32 impd_match_effect_types(
ia_drc_config* pstr_drc_config, WORD32 effect_type_requested_total_count,
WORD32 effect_type_requested_desired_count, WORD32* requested_effect_type,
WORD32* selection_candidate_count,
ia_selection_candidate_info_struct* selection_candidate_info) {
WORD32 k, err;
WORD32 match_found_flag = 0;
WORD32 state_requested;
WORD32 desired_effect_type_found, fallback_effect_type_found;
desired_effect_type_found = 0;
fallback_effect_type_found = 0;
k = 0;
while (k < effect_type_requested_desired_count) {
state_requested = 1;
err = impd_match_effect_type_attempt(
pstr_drc_config, requested_effect_type[k], state_requested,
&match_found_flag, selection_candidate_count, selection_candidate_info);
if (err) return (err);
if (match_found_flag) desired_effect_type_found = 1;
k++;
}
if (desired_effect_type_found == 0) {
while ((k < effect_type_requested_total_count) && (match_found_flag == 0)) {
state_requested = 1;
err = impd_match_effect_type_attempt(
pstr_drc_config, requested_effect_type[k], state_requested,
&match_found_flag, selection_candidate_count,
selection_candidate_info);
if (err) return (err);
if (match_found_flag) fallback_effect_type_found = 1;
k++;
}
}
return (0);
}
WORD32 impd_match_dynamic_range(
ia_drc_config* pstr_drc_config,
ia_drc_loudness_info_set_struct* pstr_loudness_info,
ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
WORD32 num_drc_requests, WORD32* selection_candidate_count,
ia_selection_candidate_info_struct* selection_candidate_info) {
ia_drc_instructions_struct* str_drc_instruction_str;
WORD32 err, i, k;
WORD32 lp_avg_present_val;
FLOAT32 lp_avg_val;
FLOAT32 deviation_min = 1000.0f;
WORD32 selected[DRC_INSTRUCTIONS_COUNT_MAX];
WORD32 dynamic_range_measurement_type =
pstr_drc_sel_proc_params_struct
->requested_dyn_range_measur_type[num_drc_requests];
WORD32 requested_dyn_range_range_flag =
pstr_drc_sel_proc_params_struct
->requested_dyn_range_range_flag[num_drc_requests];
FLOAT32 dynamic_range_requested =
pstr_drc_sel_proc_params_struct
->requested_dyn_range_value[num_drc_requests];
FLOAT32 dynamic_range_min_requested =
pstr_drc_sel_proc_params_struct
->requested_dyn_range_min_val[num_drc_requests];
FLOAT32 dynamic_range_max_requested =
pstr_drc_sel_proc_params_struct
->requested_dyn_range_max_val[num_drc_requests];
WORD32* requested_dwnmix_id =
pstr_drc_sel_proc_params_struct->requested_dwnmix_id;
WORD32 album_mode = pstr_drc_sel_proc_params_struct->album_mode;
k = 0;
for (i = 0; i < *selection_candidate_count; i++) {
str_drc_instruction_str = &(
pstr_drc_config->str_drc_instruction_str[selection_candidate_info[i]
.drc_instructions_index]);
err = impd_loudness_peak_to_average_info(
pstr_loudness_info, str_drc_instruction_str,
requested_dwnmix_id[selection_candidate_info[i]
.downmix_id_request_index],
dynamic_range_measurement_type, album_mode, &lp_avg_present_val,
&lp_avg_val);
if (err) return (err);
if (lp_avg_present_val == 1) {
if (requested_dyn_range_range_flag == 1) {
if ((lp_avg_val >= dynamic_range_min_requested) &&
(lp_avg_val <= dynamic_range_max_requested)) {
if (k >= DRC_INSTRUCTIONS_COUNT_MAX) return UNEXPECTED_ERROR;
selected[k] = i;
k++;
}
} else {
FLOAT32 deviation =
(FLOAT32)fabs((FLOAT64)(dynamic_range_requested - lp_avg_val));
if (deviation_min >= deviation) {
if (deviation_min > deviation) {
deviation_min = deviation;
k = 0;
}
if (k >= DRC_INSTRUCTIONS_COUNT_MAX) return UNEXPECTED_ERROR;
selected[k] = i;
k++;
}
}
}
}
if (k > 0) {
for (i = 0; i < k; i++) {
memcpy(&selection_candidate_info[i],
&selection_candidate_info[selected[i]],
sizeof(ia_selection_candidate_info_struct));
}
*selection_candidate_count = k;
}
return (0);
}
WORD32 impd_match_drc_characteristic_attempt(
ia_drc_config* pstr_drc_config, WORD32 requested_drc_characteristic,
WORD32* match_found_flag, WORD32* selection_candidate_count,
ia_selection_candidate_info_struct* selection_candidate_info) {
WORD32 i, k, n, b, m;
WORD32 ref_count;
WORD32 drc_characteristic;
FLOAT32 match_count;
WORD32 drc_characteristic_request_1;
WORD32 drc_characteristic_request_2;
WORD32 drc_characteristic_request_3;
ia_drc_instructions_struct* str_drc_instruction_str = NULL;
ia_uni_drc_coeffs_struct* str_p_loc_drc_coefficients_uni_drc = NULL;
ia_gain_set_params_struct* gain_set_params = NULL;
*match_found_flag = 0;
if (requested_drc_characteristic < 1) {
return (UNEXPECTED_ERROR);
}
if (requested_drc_characteristic < 12) {
drc_characteristic_request_1 =
drc_characteristic_order_default[requested_drc_characteristic - 1][0];
drc_characteristic_request_2 =
drc_characteristic_order_default[requested_drc_characteristic - 1][1];
drc_characteristic_request_3 =
drc_characteristic_order_default[requested_drc_characteristic - 1][2];
} else {
drc_characteristic_request_1 = requested_drc_characteristic;
drc_characteristic_request_2 = -1;
drc_characteristic_request_3 = -1;
}
if (pstr_drc_config->drc_coefficients_drc_count) {
for (i = 0; i < pstr_drc_config->drc_coefficients_drc_count; i++) {
str_p_loc_drc_coefficients_uni_drc =
&(pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[i]);
if (str_p_loc_drc_coefficients_uni_drc->drc_location == LOCATION_SELECTED)
break;
}
if (i == pstr_drc_config->drc_coefficients_drc_count) {
return (UNEXPECTED_ERROR);
}
}
n = 0;
for (i = 0; i < *selection_candidate_count; i++) {
ref_count = 0;
match_count = 0;
str_drc_instruction_str = &(
pstr_drc_config->str_drc_instruction_str[selection_candidate_info[i]
.drc_instructions_index]);
for (k = 0; k < str_drc_instruction_str->num_drc_ch_groups; k++) {
gain_set_params =
&(str_p_loc_drc_coefficients_uni_drc->gain_set_params
[str_drc_instruction_str->gain_set_index_for_channel_group[k]]);
for (b = 0; b < gain_set_params->band_count; b++) {
ref_count++;
drc_characteristic = gain_set_params->gain_params[b].drc_characteristic;
if (drc_characteristic == drc_characteristic_request_1)
match_count += 1.0f;
else if (drc_characteristic == drc_characteristic_request_2)
match_count += 0.75f;
else if (drc_characteristic == drc_characteristic_request_3)
match_count += 0.5f;
}
}
if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
WORD32 depends_on_drc_set = str_drc_instruction_str->depends_on_drc_set;
for (m = 0; m < pstr_drc_config->drc_instructions_uni_drc_count; m++) {
if (pstr_drc_config->str_drc_instruction_str[m].drc_set_id ==
depends_on_drc_set)
break;
}
if (m == pstr_drc_config->drc_instructions_uni_drc_count) {
return (UNEXPECTED_ERROR);
}
str_drc_instruction_str = &(pstr_drc_config->str_drc_instruction_str[m]);
if ((str_drc_instruction_str->drc_set_effect &
(EFFECT_BIT_FADE | EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) ==
0) {
if (str_drc_instruction_str->drc_set_effect != EFFECT_BIT_CLIPPING) {
for (k = 0; k < str_drc_instruction_str->num_drc_ch_groups; k++) {
gain_set_params =
&(str_p_loc_drc_coefficients_uni_drc->gain_set_params
[str_drc_instruction_str
->gain_set_index_for_channel_group[k]]);
for (b = 0; b < gain_set_params->band_count; b++) {
ref_count++;
drc_characteristic =
gain_set_params->gain_params[b].drc_characteristic;
if (drc_characteristic == drc_characteristic_request_1)
match_count += 1.0f;
else if (drc_characteristic == drc_characteristic_request_2)
match_count += 0.75f;
else if (drc_characteristic == drc_characteristic_request_3)
match_count += 0.5;
}
}
}
}
}
if ((ref_count > 0) && (((FLOAT32)match_count) > 0.5f * ref_count)) {
if (n >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
memcpy(&selection_candidate_info[n], &selection_candidate_info[i],
sizeof(ia_selection_candidate_info_struct));
n++;
}
}
if (n > 0) {
*selection_candidate_count = n;
*match_found_flag = 1;
}
return (0);
}
WORD32 impd_match_drc_characteristic(
ia_drc_config* pstr_drc_config, WORD32 requested_drc_characteristic,
WORD32* selection_candidate_count,
ia_selection_candidate_info_struct* selection_candidate_info) {
WORD32 k, err;
WORD32 match_found_flag = 0;
const WORD32* drc_characteristic_order =
drc_characteristic_order_default[requested_drc_characteristic - 1];
const WORD32 drc_characteristic_order_count =
sizeof(drc_characteristic_order_default[requested_drc_characteristic]) /
sizeof(WORD32);
k = 0;
while ((k < drc_characteristic_order_count) && (match_found_flag == 0) &&
(drc_characteristic_order[k] > 0)) {
err = impd_match_drc_characteristic_attempt(
pstr_drc_config, drc_characteristic_order[k], &match_found_flag,
selection_candidate_count, selection_candidate_info);
if (err) return (err);
k++;
}
return (0);
}
WORD32 impd_drc_set_preselection(
ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
ia_drc_config* pstr_drc_config,
ia_drc_loudness_info_set_struct* pstr_loudness_info,
WORD32 restrict_to_drc_with_album_loudness,
ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
WORD32* selection_candidate_count,
ia_selection_candidate_info_struct* selection_candidate_info) {
WORD32 i, j, k, l, d, n, err;
WORD32 downmix_id_match = 0;
WORD32 selection_candidate_step_2_count;
ia_selection_candidate_info_struct
selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
WORD32 num_downmix_id_requests =
pstr_drc_sel_proc_params_struct->num_downmix_id_requests;
WORD32* requested_dwnmix_id =
pstr_drc_sel_proc_params_struct->requested_dwnmix_id;
FLOAT32 output_peak_level_max =
pstr_drc_sel_proc_params_struct->output_peak_level_max;
WORD32 loudness_deviation_max =
pstr_drc_sel_proc_params_struct->loudness_deviation_max;
WORD32* drc_set_id_valid_flag = pstr_drc_uni_sel_proc->drc_set_id_valid_flag;
WORD32* eq_set_id_valid_flag = pstr_drc_uni_sel_proc->eq_set_id_valid_flag;
FLOAT32 output_peak_level_min = 1000.0f;
FLOAT32 adjustment;
WORD32 loudness_drc_set_id_requested;
WORD32 num_compression_eq_count = 0;
WORD32 num_compression_eq_id[16];
WORD32 loudness_info_count = 0;
WORD32 eq_set_id_loudness[16];
FLOAT32 loudness_normalization_gain_db[16];
FLOAT32 loudness[16];
WORD32 peak_info_count;
WORD32 eq_set_id_Peak[16];
FLOAT32 signal_peak_level[16];
WORD32 explicit_peak_information_present[16];
ia_uni_drc_coeffs_struct* str_p_loc_drc_coefficients_uni_drc = NULL;
ia_drc_instructions_struct* str_drc_instruction_str = NULL;
impd_select_drc_coeff3(pstr_drc_config, &str_p_loc_drc_coefficients_uni_drc);
if (str_p_loc_drc_coefficients_uni_drc == NULL) return UNEXPECTED_ERROR;
k = 0;
for (d = 0; d < num_downmix_id_requests; d++) {
err = impd_find_eq_set_no_compression(
pstr_drc_config, requested_dwnmix_id[d], &num_compression_eq_count,
num_compression_eq_id);
if (err) return (err);
for (i = 0; i < pstr_drc_config->drc_instructions_count_plus; i++) {
downmix_id_match = 0;
str_drc_instruction_str = &(pstr_drc_config->str_drc_instruction_str[i]);
for (j = 0; j < str_drc_instruction_str->dwnmix_id_count; j++) {
if ((str_drc_instruction_str->downmix_id[j] ==
requested_dwnmix_id[d]) ||
((str_drc_instruction_str->downmix_id[j] == ID_FOR_BASE_LAYOUT) &&
(str_drc_instruction_str->drc_set_id > 0)) ||
(str_drc_instruction_str->downmix_id[j] == ID_FOR_ANY_DOWNMIX)) {
downmix_id_match = 1;
}
}
if (downmix_id_match == 1) {
if (pstr_drc_sel_proc_params_struct->dynamic_range_control_on == 1) {
if ((str_drc_instruction_str->drc_set_effect != EFFECT_BIT_FADE) &&
(str_drc_instruction_str->drc_set_effect !=
EFFECT_BIT_DUCK_OTHER) &&
(str_drc_instruction_str->drc_set_effect !=
EFFECT_BIT_DUCK_SELF) &&
(str_drc_instruction_str->drc_set_effect != 0 ||
str_drc_instruction_str->drc_set_id < 0) &&
(((str_drc_instruction_str->depends_on_drc_set_present == 0) &&
(str_drc_instruction_str->no_independent_use == 0)) ||
(str_drc_instruction_str->depends_on_drc_set_present == 1))) {
WORD32 drc_is_permitted = 1;
if (str_drc_instruction_str->drc_set_id > 0) {
drc_is_permitted =
drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id];
}
if (drc_is_permitted == 1) {
err = impd_init_loudness_control(
pstr_drc_sel_proc_params_struct, pstr_loudness_info,
requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
num_compression_eq_count, num_compression_eq_id,
&loudness_info_count, eq_set_id_loudness,
loudness_normalization_gain_db, loudness);
if (err) return (err);
if (loudness_info_count > MAX_LOUDNESS_INFO_COUNT)
return UNEXPECTED_ERROR;
err = impd_signal_peak_level_info(
pstr_drc_config, pstr_loudness_info, str_drc_instruction_str,
requested_dwnmix_id[d],
pstr_drc_sel_proc_params_struct->album_mode,
num_compression_eq_count, num_compression_eq_id,
&peak_info_count, eq_set_id_Peak, signal_peak_level,
explicit_peak_information_present);
if (err) return (err);
for (l = 0; l < loudness_info_count; l++) {
WORD32 match_found_flag = 0;
WORD32 p;
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
selection_candidate_info[k].loudness_norm_db_gain_adjusted =
loudness_normalization_gain_db[l];
selection_candidate_info[k]
.loudness_norm_db_gain_adjusted = min(
selection_candidate_info[k].loudness_norm_db_gain_adjusted,
pstr_drc_sel_proc_params_struct->loudness_norm_gain_db_max);
if (loudness[l] != UNDEFINED_LOUDNESS_VALUE) {
selection_candidate_info[k].output_loudness =
loudness[l] +
selection_candidate_info[k]
.loudness_norm_db_gain_adjusted;
} else {
selection_candidate_info[k].output_loudness =
UNDEFINED_LOUDNESS_VALUE;
}
for (p = 0; p < peak_info_count; p++) {
if (eq_set_id_Peak[p] == eq_set_id_loudness[l]) {
if (eq_set_id_valid_flag[eq_set_id_Peak[p]] == 1)
{
match_found_flag = 1;
break;
}
}
}
if (match_found_flag == 1) {
selection_candidate_info[k].output_peak_level =
signal_peak_level[p] +
selection_candidate_info[k]
.loudness_norm_db_gain_adjusted;
} else {
selection_candidate_info[k].output_peak_level =
selection_candidate_info[k]
.loudness_norm_db_gain_adjusted;
}
if ((str_drc_instruction_str->requires_eq == 1) &&
(eq_set_id_valid_flag[eq_set_id_loudness[l]] == 0))
continue;
selection_candidate_info[k].drc_instructions_index = i;
selection_candidate_info[k].downmix_id_request_index = d;
selection_candidate_info[k].eq_set_id = eq_set_id_loudness[l];
if (explicit_peak_information_present[p] == 1) {
selection_candidate_info[k].selection_flags =
SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT;
} else {
selection_candidate_info[k].selection_flags = 0;
}
impd_mixing_level_info(
pstr_drc_sel_proc_params_struct, pstr_loudness_info,
requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
eq_set_id_loudness[l],
&selection_candidate_info[k].mixing_level);
if (str_drc_instruction_str->drc_set_target_loudness_present &&
((pstr_drc_sel_proc_params_struct
->loudness_normalization_on &&
str_drc_instruction_str
->drc_set_target_loudness_value_upper >=
pstr_drc_sel_proc_params_struct->target_loudness &&
str_drc_instruction_str
->drc_set_target_loudness_value_lower <
pstr_drc_sel_proc_params_struct->target_loudness) ||
!pstr_drc_sel_proc_params_struct
->loudness_normalization_on)) {
selection_candidate_info[k].selection_flags |=
SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH;
if (!explicit_peak_information_present[p]) {
if (pstr_drc_sel_proc_params_struct
->loudness_normalization_on) {
selection_candidate_info[k].output_peak_level =
pstr_drc_sel_proc_params_struct->target_loudness -
str_drc_instruction_str
->drc_set_target_loudness_value_upper;
} else {
selection_candidate_info[k].output_peak_level = 0.0f;
}
}
}
if ((selection_candidate_info[k].selection_flags &
(SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH |
SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT) ||
!str_drc_instruction_str
->drc_set_target_loudness_present)) {
k++;
}
}
}
}
} else {
if (str_drc_instruction_str->drc_set_id < 0) {
err = impd_init_loudness_control(
pstr_drc_sel_proc_params_struct, pstr_loudness_info,
requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
num_compression_eq_count, num_compression_eq_id,
&loudness_info_count, eq_set_id_loudness,
loudness_normalization_gain_db, loudness);
if (err) return (err);
err = impd_signal_peak_level_info(
pstr_drc_config, pstr_loudness_info, str_drc_instruction_str,
requested_dwnmix_id[d],
pstr_drc_sel_proc_params_struct->album_mode,
num_compression_eq_count, num_compression_eq_id,
&peak_info_count, eq_set_id_Peak, signal_peak_level,
explicit_peak_information_present);
if (err) return (err);
for (l = 0; l < loudness_info_count; l++) {
WORD32 match_found_flag = 0;
WORD32 p;
for (p = 0; p < peak_info_count; p++) {
if (eq_set_id_Peak[p] == eq_set_id_loudness[l]) {
if (eq_set_id_valid_flag[eq_set_id_Peak[p]] == 1) {
match_found_flag = 1;
break;
}
}
}
if (match_found_flag == 1) {
adjustment = max(
0.0f,
signal_peak_level[p] + loudness_normalization_gain_db[l] -
pstr_drc_sel_proc_params_struct->output_peak_level_max);
adjustment = min(adjustment, max(0.0f, loudness_deviation_max));
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
selection_candidate_info[k].loudness_norm_db_gain_adjusted =
loudness_normalization_gain_db[l] - adjustment;
selection_candidate_info[k]
.loudness_norm_db_gain_adjusted = min(
selection_candidate_info[k].loudness_norm_db_gain_adjusted,
pstr_drc_sel_proc_params_struct->loudness_norm_gain_db_max);
selection_candidate_info[k].output_peak_level =
signal_peak_level[p] +
selection_candidate_info[k].loudness_norm_db_gain_adjusted;
if (loudness[l] != UNDEFINED_LOUDNESS_VALUE) {
selection_candidate_info[k].output_loudness =
loudness[l] +
selection_candidate_info[k]
.loudness_norm_db_gain_adjusted;
} else {
selection_candidate_info[k].output_loudness =
UNDEFINED_LOUDNESS_VALUE;
}
selection_candidate_info[k].drc_instructions_index = i;
selection_candidate_info[k].downmix_id_request_index = d;
selection_candidate_info[k].eq_set_id = eq_set_id_loudness[l];
if (explicit_peak_information_present[p] == 1) {
selection_candidate_info[k].selection_flags =
SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT;
} else {
selection_candidate_info[k].selection_flags = 0;
}
impd_mixing_level_info(
pstr_drc_sel_proc_params_struct, pstr_loudness_info,
requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
eq_set_id_loudness[l],
&selection_candidate_info[k].mixing_level);
k++;
}
}
}
}
}
}
}
*selection_candidate_count = k;
if (*selection_candidate_count > SELECTION_CANDIDATE_COUNT_MAX) {
return UNEXPECTED_ERROR;
} else if (pstr_drc_sel_proc_params_struct->dynamic_range_control_on == 1) {
n = 0;
for (k = 0; k < *selection_candidate_count; k++) {
str_drc_instruction_str =
&(pstr_drc_config->str_drc_instruction_str
[selection_candidate_info[k].drc_instructions_index]);
if (pstr_drc_sel_proc_params_struct->eq_set_purpose_request !=
EQ_PURPOSE_EQ_OFF) {
WORD32 matching_eq_set_count = 0;
WORD32 matching_eq_instrucions_index[64];
err = impd_match_eq_set(
pstr_drc_config, requested_dwnmix_id[selection_candidate_info[k]
.downmix_id_request_index],
str_drc_instruction_str->drc_set_id, eq_set_id_valid_flag,
&matching_eq_set_count, matching_eq_instrucions_index);
if (err) return (err);
for (j = 0; j < matching_eq_set_count; j++) {
if (n >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
memcpy(&selection_candidate_info_step_2[n],
&selection_candidate_info[k],
sizeof(ia_selection_candidate_info_struct));
selection_candidate_info_step_2[n].eq_set_id =
pstr_drc_config->str_drc_config_ext
.str_eq_instructions[matching_eq_instrucions_index[j]]
.eq_set_id;
n++;
}
}
if (str_drc_instruction_str->requires_eq == 0) {
if (n >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
memcpy(&selection_candidate_info_step_2[n],
&selection_candidate_info[k],
sizeof(ia_selection_candidate_info_struct));
selection_candidate_info_step_2[n].eq_set_id = 0;
n++;
}
}
if (n > SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
memcpy(selection_candidate_info, selection_candidate_info_step_2,
n * sizeof(ia_selection_candidate_info_struct));
*selection_candidate_count = n;
n = 0;
for (k = 0; k < *selection_candidate_count; k++) {
if ((selection_candidate_info[k].selection_flags &
SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH) &&
!(selection_candidate_info[k].selection_flags &
SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT)) {
memcpy(&selection_candidate_info_step_2[n],
&selection_candidate_info[k],
sizeof(ia_selection_candidate_info_struct));
n++;
} else {
if (selection_candidate_info[k].output_peak_level <=
output_peak_level_max) {
memcpy(&selection_candidate_info_step_2[n],
&selection_candidate_info[k],
sizeof(ia_selection_candidate_info_struct));
n++;
}
if (selection_candidate_info[k].output_peak_level <
output_peak_level_min) {
output_peak_level_min = selection_candidate_info[k].output_peak_level;
}
}
}
selection_candidate_step_2_count = n;
if (selection_candidate_step_2_count == 0) {
n = 0;
for (k = 0; k < *selection_candidate_count; k++) {
if ((selection_candidate_info[k].selection_flags &
SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH) &&
(selection_candidate_info[k].selection_flags &
SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT)) {
memcpy(&selection_candidate_info_step_2[n],
&selection_candidate_info[k],
sizeof(ia_selection_candidate_info_struct));
n++;
}
}
selection_candidate_step_2_count = n;
}
if (selection_candidate_step_2_count == 0) {
n = 0;
for (k = 0; k < *selection_candidate_count; k++) {
if (selection_candidate_info_step_2[k].output_peak_level <
output_peak_level_min + 1.0f) {
memcpy(&selection_candidate_info_step_2[n],
&selection_candidate_info[k],
sizeof(ia_selection_candidate_info_struct));
adjustment =
max(0.0f, selection_candidate_info_step_2[n].output_peak_level -
output_peak_level_max);
adjustment = min(adjustment, max(0.0f, loudness_deviation_max));
selection_candidate_info_step_2[n].loudness_norm_db_gain_adjusted -=
adjustment;
selection_candidate_info_step_2[n].output_peak_level -= adjustment;
selection_candidate_info_step_2[n].output_loudness -= adjustment;
n++;
}
}
selection_candidate_step_2_count = n;
}
for (n = 0; n < selection_candidate_step_2_count; n++) {
memcpy(&selection_candidate_info[n], &selection_candidate_info_step_2[n],
sizeof(ia_selection_candidate_info_struct));
}
*selection_candidate_count = selection_candidate_step_2_count;
}
if (restrict_to_drc_with_album_loudness == 1) {
j = 0;
for (k = 0; k < *selection_candidate_count; k++) {
loudness_drc_set_id_requested =
max(0, pstr_drc_config
->str_drc_instruction_str[selection_candidate_info[k]
.drc_instructions_index]
.drc_set_id);
for (n = 0; n < pstr_loudness_info->loudness_info_album_count; n++) {
if (loudness_drc_set_id_requested ==
pstr_loudness_info->str_loudness_info_album[n].drc_set_id) {
if (j >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
memcpy(&selection_candidate_info[j], &selection_candidate_info[k],
sizeof(ia_selection_candidate_info_struct));
j++;
break;
}
}
}
*selection_candidate_count = j;
}
return (0);
}
WORD32 impd_drc_set_final_selection(
ia_drc_config* pstr_drc_config,
ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
WORD32* selection_candidate_count,
ia_selection_candidate_info_struct* selection_candidate_info,
WORD32* eq_set_id_valid_flag) {
WORD32 k, i, n, err;
WORD32 selection_candidate_step_2_count;
ia_selection_candidate_info_struct
selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
WORD32 drc_set_id_max;
FLOAT32 output_level_max;
FLOAT32 output_level_min;
WORD32 effect_count, effect_count_min;
WORD32 effect_types_request_table_size;
WORD32 drc_set_target_loudness_val_upper_min;
ia_drc_instructions_struct* str_drc_instruction_str;
ia_drc_instructions_struct* drc_instructions_dependent;
if (pstr_drc_sel_proc_params_struct->eq_set_purpose_request > 0) {
WORD32 eq_purpose_requested =
pstr_drc_sel_proc_params_struct->eq_set_purpose_request;
impd_match_eq_set_purpose(pstr_drc_config, eq_purpose_requested,
eq_set_id_valid_flag, selection_candidate_count,
selection_candidate_info,
selection_candidate_info_step_2);
}
output_level_min = 10000.0f;
k = 0;
for (i = 0; i < *selection_candidate_count; i++) {
if (output_level_min >= selection_candidate_info[i].output_peak_level) {
if (output_level_min > selection_candidate_info[i].output_peak_level) {
output_level_min = selection_candidate_info[i].output_peak_level;
k = 0;
}
memcpy(&selection_candidate_info_step_2[k], &selection_candidate_info[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
}
selection_candidate_step_2_count = k;
if (output_level_min <= 0.0f) {
selection_candidate_step_2_count = *selection_candidate_count;
k = 0;
for (i = 0; i < selection_candidate_step_2_count; i++) {
if (selection_candidate_info[i].output_peak_level <= 0.0f) {
memcpy(&selection_candidate_info_step_2[k],
&selection_candidate_info[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
}
selection_candidate_step_2_count = k;
k = 0;
for (i = 0; i < selection_candidate_step_2_count; i++) {
str_drc_instruction_str =
&(pstr_drc_config->str_drc_instruction_str
[selection_candidate_info_step_2[i].drc_instructions_index]);
for (n = 0; n < str_drc_instruction_str->dwnmix_id_count; n++) {
if (pstr_drc_sel_proc_params_struct->requested_dwnmix_id
[selection_candidate_info_step_2[i].downmix_id_request_index] ==
str_drc_instruction_str->downmix_id[n]) {
memcpy(&selection_candidate_info_step_2[k],
&selection_candidate_info_step_2[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
}
}
if (k > 0) {
selection_candidate_step_2_count = k;
}
effect_types_request_table_size =
sizeof(effect_types_request_table) / sizeof(WORD32);
effect_count_min = 100;
k = 0;
for (i = 0; i < selection_candidate_step_2_count; i++) {
str_drc_instruction_str =
&(pstr_drc_config->str_drc_instruction_str
[selection_candidate_info_step_2[i].drc_instructions_index]);
effect_count = 0;
if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
err = impd_get_dependent_drc_instructions(pstr_drc_config,
str_drc_instruction_str,
&drc_instructions_dependent);
if (err) return (err);
for (n = 0; n < effect_types_request_table_size; n++) {
if (effect_types_request_table[n] != EFFECT_BIT_GENERAL_COMPR) {
if (((str_drc_instruction_str->drc_set_effect &
effect_types_request_table[n]) != 0x0) ||
((drc_instructions_dependent->drc_set_effect &
effect_types_request_table[n]) != 0x0)) {
effect_count++;
}
}
}
} else {
for (n = 0; n < effect_types_request_table_size; n++) {
if (effect_types_request_table[n] != EFFECT_BIT_GENERAL_COMPR) {
if ((str_drc_instruction_str->drc_set_effect &
effect_types_request_table[n]) != 0x0) {
effect_count++;
}
}
}
}
if (effect_count_min >= effect_count) {
if (effect_count_min > effect_count) {
effect_count_min = effect_count;
k = 0;
}
memcpy(&selection_candidate_info_step_2[k],
&selection_candidate_info_step_2[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
}
selection_candidate_step_2_count = k;
drc_set_target_loudness_val_upper_min = 100;
k = 0;
for (i = 0; i < selection_candidate_step_2_count; i++) {
if (selection_candidate_info_step_2[i].selection_flags &
SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH) {
k++;
}
}
if (k != 0 && k != selection_candidate_step_2_count) {
k = 0;
for (i = 0; i < selection_candidate_step_2_count; i++) {
if (!(selection_candidate_info_step_2[i].selection_flags &
SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH)) {
memcpy(&selection_candidate_info_step_2[k],
&selection_candidate_info_step_2[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
}
selection_candidate_step_2_count = k;
} else if (k == selection_candidate_step_2_count) {
k = 0;
for (i = 0; i < selection_candidate_step_2_count; i++) {
str_drc_instruction_str =
&(pstr_drc_config->str_drc_instruction_str
[selection_candidate_info_step_2[i].drc_instructions_index]);
if (str_drc_instruction_str->drc_set_target_loudness_present != 1) {
return UNEXPECTED_ERROR;
}
if (drc_set_target_loudness_val_upper_min >=
str_drc_instruction_str->drc_set_target_loudness_value_upper) {
if (drc_set_target_loudness_val_upper_min >
str_drc_instruction_str->drc_set_target_loudness_value_upper) {
drc_set_target_loudness_val_upper_min =
str_drc_instruction_str->drc_set_target_loudness_value_upper;
k = 0;
}
memcpy(&selection_candidate_info_step_2[k],
&selection_candidate_info_step_2[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
}
selection_candidate_step_2_count = k;
}
k = 0;
for (i = 0; i < selection_candidate_step_2_count; i++) {
str_drc_instruction_str =
&(pstr_drc_config->str_drc_instruction_str
[selection_candidate_info_step_2[i].drc_instructions_index]);
if (str_drc_instruction_str->drc_set_target_loudness_present &&
pstr_drc_sel_proc_params_struct->loudness_normalization_on &&
str_drc_instruction_str->drc_set_target_loudness_value_upper >=
pstr_drc_sel_proc_params_struct->target_loudness &&
str_drc_instruction_str->drc_set_target_loudness_value_lower <
pstr_drc_sel_proc_params_struct->target_loudness) {
k++;
}
}
if (k != 0 && k != selection_candidate_step_2_count) {
k = 0;
for (i = 0; i < selection_candidate_step_2_count; i++) {
str_drc_instruction_str =
&(pstr_drc_config->str_drc_instruction_str
[selection_candidate_info_step_2[i].drc_instructions_index]);
if (str_drc_instruction_str->drc_set_target_loudness_present &&
pstr_drc_sel_proc_params_struct->loudness_normalization_on &&
str_drc_instruction_str->drc_set_target_loudness_value_upper >=
pstr_drc_sel_proc_params_struct->target_loudness &&
str_drc_instruction_str->drc_set_target_loudness_value_lower <
pstr_drc_sel_proc_params_struct->target_loudness) {
memcpy(&selection_candidate_info_step_2[k],
&selection_candidate_info_step_2[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
}
selection_candidate_step_2_count = k;
drc_set_target_loudness_val_upper_min = 100;
k = 0;
for (i = 0; i < selection_candidate_step_2_count; i++) {
str_drc_instruction_str =
&(pstr_drc_config->str_drc_instruction_str
[selection_candidate_info_step_2[i].drc_instructions_index]);
if (str_drc_instruction_str->drc_set_target_loudness_present != 1) {
return UNEXPECTED_ERROR;
}
if (drc_set_target_loudness_val_upper_min >=
str_drc_instruction_str->drc_set_target_loudness_value_upper) {
if (drc_set_target_loudness_val_upper_min >
str_drc_instruction_str->drc_set_target_loudness_value_upper) {
drc_set_target_loudness_val_upper_min =
str_drc_instruction_str->drc_set_target_loudness_value_upper;
k = 0;
}
memcpy(&selection_candidate_info_step_2[k],
&selection_candidate_info_step_2[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
}
selection_candidate_step_2_count = k;
} else if (k == selection_candidate_step_2_count) {
drc_set_target_loudness_val_upper_min = 100;
k = 0;
for (i = 0; i < selection_candidate_step_2_count; i++) {
str_drc_instruction_str =
&(pstr_drc_config->str_drc_instruction_str
[selection_candidate_info_step_2[i].drc_instructions_index]);
if (str_drc_instruction_str->drc_set_target_loudness_present != 1) {
return UNEXPECTED_ERROR;
}
if (drc_set_target_loudness_val_upper_min >=
str_drc_instruction_str->drc_set_target_loudness_value_upper) {
if (drc_set_target_loudness_val_upper_min >
str_drc_instruction_str->drc_set_target_loudness_value_upper) {
drc_set_target_loudness_val_upper_min =
str_drc_instruction_str->drc_set_target_loudness_value_upper;
k = 0;
}
memcpy(&selection_candidate_info_step_2[k],
&selection_candidate_info_step_2[i],
sizeof(ia_selection_candidate_info_struct));
k++;
}
}
selection_candidate_step_2_count = k;
}
k = 0;
output_level_max = -1000.0f;
for (i = 0; i < selection_candidate_step_2_count; i++) {
if ((selection_candidate_info_step_2[i].output_peak_level <= 0.0f) &&
(output_level_max <=
selection_candidate_info_step_2[i].output_peak_level)) {
if (output_level_max <
selection_candidate_info_step_2[i].output_peak_level) {
output_level_max =
selection_candidate_info_step_2[i].output_peak_level;
k = 0;
}
memcpy(&selection_candidate_info_step_2[k],
&selection_candidate_info_step_2[i],
sizeof(ia_selection_candidate_info_struct));
k++;
output_level_max = selection_candidate_info_step_2[i].output_peak_level;
}
}
selection_candidate_step_2_count = k;
}
drc_set_id_max = -1000;
for (i = 0; i < selection_candidate_step_2_count; i++) {
str_drc_instruction_str =
&(pstr_drc_config->str_drc_instruction_str
[selection_candidate_info_step_2[i].drc_instructions_index]);
if (drc_set_id_max < str_drc_instruction_str->drc_set_id) {
drc_set_id_max = str_drc_instruction_str->drc_set_id;
memcpy(&selection_candidate_info_step_2[0],
&selection_candidate_info_step_2[i],
sizeof(ia_selection_candidate_info_struct));
}
}
memcpy(&selection_candidate_info[0], &selection_candidate_info_step_2[0],
sizeof(ia_selection_candidate_info_struct));
*selection_candidate_count = 1;
return 0;
}
WORD32 impd_select_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
WORD32* drc_set_id_selected,
WORD32* eq_set_id_selected, WORD32* loud_eq_id_sel) {
WORD32 i, err;
ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct =
&pstr_drc_uni_sel_proc->uni_drc_sel_proc_params;
ia_drc_config* pstr_drc_config = &pstr_drc_uni_sel_proc->drc_config;
ia_drc_loudness_info_set_struct* pstr_loudness_info =
&pstr_drc_uni_sel_proc->loudness_info_set;
WORD32 selection_candidate_count = 0;
WORD32 restrict_to_drc_with_album_loudness = 0;
ia_selection_candidate_info_struct
selection_candidate_info[SELECTION_CANDIDATE_COUNT_MAX];
// WORD32 selected_eq_set_count = 0;
if (pstr_drc_sel_proc_params_struct->album_mode == 1) {
restrict_to_drc_with_album_loudness = 1;
}
while (!selection_candidate_count) {
err = impd_drc_set_preselection(
pstr_drc_sel_proc_params_struct, pstr_drc_config, pstr_loudness_info,
restrict_to_drc_with_album_loudness, pstr_drc_uni_sel_proc,
&selection_candidate_count, selection_candidate_info);
if (err) return err;
if (selection_candidate_count == 0) {
if (restrict_to_drc_with_album_loudness == 1) {
restrict_to_drc_with_album_loudness = 0;
continue;
} else {
return (UNEXPECTED_ERROR);
}
}
err = impd_validate_requested_drc_feature(pstr_drc_sel_proc_params_struct);
if (err) return (err);
if (pstr_drc_sel_proc_params_struct->dynamic_range_control_on == 1) {
if (pstr_drc_sel_proc_params_struct->num_drc_feature_requests > 0) {
for (i = 0;
i < pstr_drc_sel_proc_params_struct->num_drc_feature_requests;
i++) {
switch (pstr_drc_sel_proc_params_struct->drc_feature_req_type[i]) {
case MATCH_EFFECT_TYPE:
err = impd_match_effect_types(
pstr_drc_config,
pstr_drc_sel_proc_params_struct->requested_num_drc_effects[i],
pstr_drc_sel_proc_params_struct
->desired_num_drc_effects_of_requested[i],
pstr_drc_sel_proc_params_struct->requested_drc_effect_type[i],
&selection_candidate_count, selection_candidate_info);
if (err) return (err);
break;
case MATCH_DYNAMIC_RANGE:
err = impd_match_dynamic_range(
pstr_drc_config, pstr_loudness_info,
pstr_drc_sel_proc_params_struct, i,
&selection_candidate_count, selection_candidate_info);
if (err) return (err);
break;
case MATCH_DRC_CHARACTERISTIC:
err = impd_match_drc_characteristic(
pstr_drc_config, pstr_drc_sel_proc_params_struct
->requested_drc_characteristic[i],
&selection_candidate_count, selection_candidate_info);
if (err) return (err);
break;
default:
return (UNEXPECTED_ERROR);
break;
}
}
} else {
WORD32 match_found_flag = 0;
err = impd_select_drcs_without_compr_effects(
pstr_drc_config, &match_found_flag, &selection_candidate_count,
selection_candidate_info);
if (err) return (err);
if (match_found_flag == 0) {
WORD32 requested_num_drc_effects = 5;
WORD32 desired_num_drc_effects_of_requested = 1;
WORD32 requested_drc_effect_type[5] = {
EFFECT_TYPE_REQUESTED_GENERAL_COMPR, EFFECT_TYPE_REQUESTED_NIGHT,
EFFECT_TYPE_REQUESTED_NOISY, EFFECT_TYPE_REQUESTED_LIMITED,
EFFECT_TYPE_REQUESTED_LOWLEVEL};
err = impd_match_effect_types(
pstr_drc_config, requested_num_drc_effects,
desired_num_drc_effects_of_requested, requested_drc_effect_type,
&selection_candidate_count, selection_candidate_info);
if (err) return (err);
}
}
if (selection_candidate_count > 0) {
err = impd_drc_set_final_selection(
pstr_drc_config, pstr_drc_sel_proc_params_struct,
&selection_candidate_count, selection_candidate_info,
pstr_drc_uni_sel_proc->eq_set_id_valid_flag);
if (err) return (err);
} else {
selection_candidate_count = 0;
return (UNEXPECTED_ERROR);
}
}
if (selection_candidate_count == 0) {
if (restrict_to_drc_with_album_loudness == 1) {
restrict_to_drc_with_album_loudness = 0;
} else {
return (UNEXPECTED_ERROR);
}
}
}
*drc_set_id_selected =
pstr_drc_config
->str_drc_instruction_str[selection_candidate_info[0]
.drc_instructions_index]
.drc_set_id;
*eq_set_id_selected = selection_candidate_info[0].eq_set_id;
impd_select_loud_eq(
pstr_drc_config,
pstr_drc_sel_proc_params_struct->requested_dwnmix_id
[selection_candidate_info[0].downmix_id_request_index],
*drc_set_id_selected, *eq_set_id_selected, loud_eq_id_sel);
if (selection_candidate_count > 0) {
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
.loudness_normalization_gain_db =
selection_candidate_info[0].loudness_norm_db_gain_adjusted;
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.output_peak_level_db =
selection_candidate_info[0].output_peak_level;
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.output_loudness =
selection_candidate_info[0].output_loudness;
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.active_downmix_id =
pstr_drc_sel_proc_params_struct->requested_dwnmix_id
[selection_candidate_info[0].downmix_id_request_index];
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.mixing_level =
selection_candidate_info[0].mixing_level;
}
return (0);
}