libxaac/decoder/drc_src/impd_drc_selection_process_drcset_selection.c
Ray Essick 4908247643 Sanitization fixes from new CTS tests
Updates from vendor to remedy issues exposed by new CTS tests

Bug: 77287124
Test: CTS DecoderTest, DecoderTest{AacDrc,XheAac}

@ Sanitizer fixes in libxaac

Fixes few integer overflow sanitizer errors
Progagate few errors
ENABLE_DRC macro is removed
AMMENDMENT1 macro is removed

Change-Id: Ic61163dfd6318bd4a00ed45e1295c819cb0f637b

@ Add support for audio pre-roll and DRC effect type

Also includes the following
MPEG-D DRC parameters related changes
USAC config switch changes
SBR config switch changes

Bug: 80133175
Change-Id: I0ab25641768cf523b66f7b0fcb4137429c1c4a77

@ Fixed trailing spaces

Change-Id: I32de0c9d3f7237e1fbf8dfef1cac485ef8458173

@ Replaced tabs

Change-Id: Ic741ee13d7b978b37edc27d087903caaa40b8d90
2018-05-25 11:35:52 -07:00

1537 lines
66 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 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)
{
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))
{
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))
{
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)
{
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)
{
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))
{
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;
}
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))
{
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;
WORD32* drc_characteristic_order = drc_characteristic_order_default[requested_drc_characteristic-1];
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);
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);
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;
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 {
}
}
}
}
}
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));
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++) {
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) {
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++;
}
}
for (k=0; k<n; k++)
{
memcpy(&selection_candidate_info[k], &selection_candidate_info_step_2[k], 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)
{
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)
{
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 (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);
}