Clean copy of version XHEAAC_V1_36 as delivered 2018/4/13 Sole change is to map cr/lf line termination to unix lf. Added appropriate LICENSE, MODULE_LICENSE_APACHE2, and NOTICE files as part of folding into internal master. Bug: 77287124 Test: CTS audio/media Change-Id: I3c8d124033f967b29d6e384cce5c843ee17a7bb1
1101 lines
No EOL
46 KiB
C
1101 lines
No EOL
46 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 <stdlib.h>
|
|
#include <math.h>
|
|
#include <string.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"
|
|
|
|
WORD32 impd_drc_uni_selction_proc_init(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
|
|
ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
|
|
ia_drc_interface_struct* pstr_drc_interface,
|
|
WORD32 subband_domain_mode)
|
|
{
|
|
WORD32 err = 0;
|
|
|
|
if (pstr_drc_uni_sel_proc == NULL) {
|
|
return 1;
|
|
}
|
|
|
|
if (pstr_drc_uni_sel_proc->first_frame == 1) {
|
|
err = impd_drc_sel_proc_init_dflt(pstr_drc_uni_sel_proc);
|
|
if (err) return (err);
|
|
}
|
|
|
|
err = impd_drc_sel_proc_init_sel_proc_params(pstr_drc_uni_sel_proc,
|
|
pstr_drc_sel_proc_params_struct);
|
|
if (err) return (err);
|
|
{
|
|
WORD32 i;
|
|
pstr_drc_uni_sel_proc->drc_set_id_valid_flag[0] = 1;
|
|
for (i=1; i<DRC_INSTRUCTIONS_COUNT_MAX; i++)
|
|
{
|
|
pstr_drc_uni_sel_proc->drc_set_id_valid_flag[i] = 0;
|
|
}
|
|
|
|
pstr_drc_uni_sel_proc->eq_set_id_valid_flag[0] = 1;
|
|
for (i=1; i<EQ_INSTRUCTIONS_COUNT_MAX; i++)
|
|
{
|
|
pstr_drc_uni_sel_proc->eq_set_id_valid_flag[i] = 0;
|
|
}
|
|
}
|
|
err = impd_drc_sel_proc_init_interface_params(pstr_drc_uni_sel_proc,
|
|
pstr_drc_interface);
|
|
if (err) return (err);
|
|
|
|
pstr_drc_uni_sel_proc->subband_domain_mode = subband_domain_mode;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
WORD32
|
|
impd_drc_uni_sel_proc_process(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
|
|
ia_drc_config* pstr_drc_config,
|
|
ia_drc_loudness_info_set_struct* pstr_loudness_info,
|
|
ia_drc_sel_proc_output_struct* hia_drc_sel_proc_output_struct)
|
|
{
|
|
WORD32 i, err, drc_set_id_selected, activeDrcSetIndex;
|
|
WORD32 eq_set_id_selected;
|
|
WORD32 loudEqSetIdSelected;
|
|
|
|
|
|
if (pstr_drc_config != NULL)
|
|
{
|
|
if ( memcmp ( &pstr_drc_uni_sel_proc->drc_config, pstr_drc_config, sizeof(ia_drc_config) ))
|
|
{
|
|
pstr_drc_uni_sel_proc->drc_config = *pstr_drc_config;
|
|
pstr_drc_uni_sel_proc->drc_config_flag = 1;
|
|
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_channel_count != pstr_drc_uni_sel_proc->drc_config.channel_layout.base_channel_count)
|
|
{
|
|
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_channel_count = pstr_drc_uni_sel_proc->drc_config.channel_layout.base_channel_count;
|
|
}
|
|
if (pstr_drc_uni_sel_proc->drc_config.channel_layout.layout_signaling_present == 1 && pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_layout != pstr_drc_uni_sel_proc->drc_config.channel_layout.defined_layout)
|
|
{
|
|
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_layout = pstr_drc_uni_sel_proc->drc_config.channel_layout.defined_layout;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pstr_drc_uni_sel_proc->drc_config_flag = 0;
|
|
}
|
|
}
|
|
if (pstr_loudness_info != NULL)
|
|
{
|
|
if ( memcmp ( &pstr_drc_uni_sel_proc->loudness_info_set, pstr_loudness_info, sizeof(ia_drc_loudness_info_set_struct) ))
|
|
{
|
|
pstr_drc_uni_sel_proc->loudness_info_set = *pstr_loudness_info;
|
|
pstr_drc_uni_sel_proc->loudness_info_set_flag = 1;
|
|
}
|
|
else
|
|
{
|
|
pstr_drc_uni_sel_proc->loudness_info_set_flag = 0;
|
|
}
|
|
}
|
|
|
|
if ((pstr_drc_uni_sel_proc->drc_config_flag && pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.target_config_request_type != 0) ||
|
|
(pstr_drc_uni_sel_proc->sel_proc_request_flag && pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.target_config_request_type != 0) ||
|
|
(pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.target_config_request_type == 0 && pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests == 0))
|
|
{
|
|
err = impd_map_target_config_req_downmix_id(pstr_drc_uni_sel_proc,
|
|
&pstr_drc_uni_sel_proc->drc_config);
|
|
if (err) return (err);
|
|
}
|
|
|
|
if (pstr_drc_uni_sel_proc->drc_config_flag || pstr_drc_uni_sel_proc->loudness_info_set_flag || pstr_drc_uni_sel_proc->sel_proc_request_flag) {
|
|
|
|
WORD32 repeat_selection = 1;
|
|
WORD32 loop_cnt = 0;
|
|
|
|
err = impd_manage_drc_complexity (pstr_drc_uni_sel_proc, pstr_drc_config);
|
|
if (err) return(err);
|
|
err = impd_manage_eq_complexity (pstr_drc_uni_sel_proc, pstr_drc_config);
|
|
if (err) return(err);
|
|
while (repeat_selection==1)
|
|
{
|
|
err = impd_select_drc_set(pstr_drc_uni_sel_proc,
|
|
&drc_set_id_selected
|
|
, &eq_set_id_selected
|
|
, &loudEqSetIdSelected
|
|
);
|
|
if (err) return (err);
|
|
|
|
err = impd_get_selected_drc_set(pstr_drc_uni_sel_proc,
|
|
drc_set_id_selected);
|
|
if (err) return (err);
|
|
|
|
err = impd_get_dependent_drc_set(pstr_drc_uni_sel_proc);
|
|
if (err) return (err);
|
|
|
|
err = impd_get_fading_drc_set(pstr_drc_uni_sel_proc);
|
|
if (err) return (err);
|
|
|
|
err = impd_get_ducking_drc_set(pstr_drc_uni_sel_proc);
|
|
if (err) return (err);
|
|
|
|
pstr_drc_uni_sel_proc->eq_inst_index[0] = -1;
|
|
pstr_drc_uni_sel_proc->eq_inst_index[1] = -1;
|
|
|
|
err = impd_get_selected_eq_set(pstr_drc_uni_sel_proc, eq_set_id_selected);
|
|
if (err) return (err);
|
|
|
|
err = impd_get_dependent_eq_set(pstr_drc_uni_sel_proc);
|
|
if (err) return (err);
|
|
|
|
err = impd_get_selected_loud_eq_set(pstr_drc_uni_sel_proc, loudEqSetIdSelected);
|
|
if (err) return (err);
|
|
|
|
activeDrcSetIndex = 0;
|
|
for (i=SUB_DRC_COUNT-1; i>=0; i--) {
|
|
WORD32 drc_instructions_index = pstr_drc_uni_sel_proc->drc_instructions_index[i];
|
|
ia_drc_instructions_struct str_drc_instruction_str;
|
|
|
|
str_drc_instruction_str = pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[drc_instructions_index];
|
|
|
|
if (drc_instructions_index >= 0 && str_drc_instruction_str.drc_set_id > 0)
|
|
{
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[activeDrcSetIndex] = str_drc_instruction_str.drc_set_id;
|
|
|
|
if ((i==3) && (str_drc_instruction_str.drc_set_effect & (EFFECT_BIT_DUCK_SELF | EFFECT_BIT_DUCK_OTHER))) {
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_downmix_ids[activeDrcSetIndex] = 0;
|
|
}
|
|
else {
|
|
if (str_drc_instruction_str.drc_apply_to_dwnmix == 1) {
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_downmix_ids[activeDrcSetIndex] = str_drc_instruction_str.downmix_id[0];
|
|
} else {
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_downmix_ids[activeDrcSetIndex] = 0;
|
|
}
|
|
}
|
|
|
|
activeDrcSetIndex++;
|
|
}
|
|
}
|
|
if (activeDrcSetIndex <= 3)
|
|
{
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.num_sel_drc_sets = activeDrcSetIndex;
|
|
} else
|
|
{
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.num_sel_drc_sets = -1;
|
|
return(UNEXPECTED_ERROR);
|
|
}
|
|
|
|
impd_sel_downmix_matrix(pstr_drc_uni_sel_proc,
|
|
&pstr_drc_uni_sel_proc->drc_config);
|
|
|
|
err = impd_manage_complexity (pstr_drc_uni_sel_proc, pstr_drc_config, &repeat_selection);
|
|
if (err) return(err);
|
|
|
|
loop_cnt++;
|
|
if (loop_cnt > 100)
|
|
{
|
|
return (UNEXPECTED_ERROR);
|
|
}
|
|
}
|
|
|
|
pstr_drc_uni_sel_proc->sel_proc_request_flag = 0;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.boost = pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.boost;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.compress = pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.compress;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.drc_characteristic_target = pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.drc_characteristic_target;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.loudness_normalization_gain_db += pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.loudness_norm_gain_modification_db;
|
|
|
|
|
|
|
|
}
|
|
for (i=0; i<2; i++)
|
|
{
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_eq_set_ids[i] = pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.str_eq_instructions[pstr_drc_uni_sel_proc->eq_inst_index[i]].eq_set_id;
|
|
}
|
|
if (pstr_drc_uni_sel_proc->loud_eq_inst_index_sel >= 0)
|
|
{
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_loud_eq_id = pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.loud_eq_instructions[pstr_drc_uni_sel_proc->loud_eq_inst_index_sel].loud_eq_set_id;
|
|
}
|
|
else
|
|
{
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_loud_eq_id = 0;
|
|
}
|
|
*hia_drc_sel_proc_output_struct = pstr_drc_uni_sel_proc->uni_drc_sel_proc_output;
|
|
|
|
return 0;
|
|
}
|
|
|
|
WORD32 impd_map_target_config_req_downmix_id(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
|
|
ia_drc_config* pstr_drc_config)
|
|
{
|
|
WORD32 i, dwnmix_instructions_count;
|
|
WORD32 target_ch_count_prelim = pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_channel_count;
|
|
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests = 0;
|
|
switch (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.target_config_request_type) {
|
|
case 0:
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests == 0)
|
|
{
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id[0] = 0;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests = 1;
|
|
}
|
|
break;
|
|
case 1:
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_target_layout == pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_layout)
|
|
{
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id[0] = 0;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests = 1;
|
|
}
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests == 0) {
|
|
dwnmix_instructions_count = pstr_drc_uni_sel_proc->drc_config.dwnmix_instructions_count;
|
|
for (i=0; i<dwnmix_instructions_count; i++)
|
|
{
|
|
ia_downmix_instructions_struct* dwnmix_instructions = &(pstr_drc_config->dwnmix_instructions[i]);
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_target_layout == dwnmix_instructions->target_layout)
|
|
{
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id[pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests] = dwnmix_instructions->downmix_id;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests += 1;
|
|
target_ch_count_prelim = dwnmix_instructions->target_channel_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests == 0)
|
|
{
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id[0] = 0;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests = 1;
|
|
}
|
|
break;
|
|
case 2:
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_target_ch_count == pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.base_channel_count)
|
|
{
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id[0] = 0;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests = 1;
|
|
}
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests == 0)
|
|
{
|
|
dwnmix_instructions_count = pstr_drc_uni_sel_proc->drc_config.dwnmix_instructions_count;
|
|
for (i=0; i<dwnmix_instructions_count; i++)
|
|
{
|
|
ia_downmix_instructions_struct* dwnmix_instructions = &(pstr_drc_config->dwnmix_instructions[i]);
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_target_ch_count == dwnmix_instructions->target_channel_count) {
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id[pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests] = dwnmix_instructions->downmix_id;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests += 1;
|
|
target_ch_count_prelim = dwnmix_instructions->target_channel_count;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests == 0)
|
|
{
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.requested_dwnmix_id[0] = 0;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.num_downmix_id_requests = 1;
|
|
}
|
|
break;
|
|
default:
|
|
return UNEXPECTED_ERROR;
|
|
break;
|
|
}
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.target_ch_count_prelim = target_ch_count_prelim;
|
|
|
|
return 0;
|
|
}
|
|
|
|
VOID impd_sel_downmix_matrix(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
|
|
ia_drc_config* pstr_drc_config)
|
|
{
|
|
WORD32 i, j, n;
|
|
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.base_channel_count = pstr_drc_config->channel_layout.base_channel_count;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.target_channel_count = pstr_drc_config->channel_layout.base_channel_count;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.target_layout = -1;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.downmix_matrix_present = 0;
|
|
pstr_drc_uni_sel_proc->downmix_inst_index_sel = -1;
|
|
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.active_downmix_id != 0) {
|
|
|
|
for (n=0; n<pstr_drc_config->dwnmix_instructions_count; n++) {
|
|
ia_downmix_instructions_struct* dwnmix_instructions = &(pstr_drc_config->dwnmix_instructions[n]);
|
|
|
|
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.active_downmix_id == dwnmix_instructions->downmix_id) {
|
|
pstr_drc_uni_sel_proc->downmix_inst_index_sel = n;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.target_channel_count = dwnmix_instructions->target_channel_count;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.target_layout = dwnmix_instructions->target_layout;
|
|
if (dwnmix_instructions->downmix_coefficients_present) {
|
|
for( i =0 ; i < pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.base_channel_count; i++)
|
|
{
|
|
for( j =0 ; j < pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.target_channel_count; j++)
|
|
{
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.downmix_matrix[i][j] = dwnmix_instructions->downmix_coefficient[i+j*pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.base_channel_count];
|
|
}
|
|
}
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.downmix_matrix_present = 1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
WORD32 impd_get_selected_eq_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
|
|
WORD32 eq_set_id_selected)
|
|
{
|
|
WORD32 n;
|
|
|
|
pstr_drc_uni_sel_proc->eq_inst_index_sel = -1;
|
|
|
|
if (eq_set_id_selected > 0)
|
|
{
|
|
for(n=0; n<pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.eq_instructions_count; n++)
|
|
{
|
|
if (pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.str_eq_instructions[n].eq_set_id == eq_set_id_selected) break;
|
|
}
|
|
if (n == pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.eq_instructions_count)
|
|
{
|
|
return(EXTERNAL_ERROR);
|
|
}
|
|
pstr_drc_uni_sel_proc->eq_inst_index_sel = n;
|
|
if (pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.str_eq_instructions[n].eq_apply_to_downmix == 1)
|
|
{
|
|
pstr_drc_uni_sel_proc->eq_inst_index[1] = pstr_drc_uni_sel_proc->eq_inst_index_sel;
|
|
}
|
|
else
|
|
{
|
|
pstr_drc_uni_sel_proc->eq_inst_index[0] = pstr_drc_uni_sel_proc->eq_inst_index_sel;
|
|
}
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
WORD32 impd_get_dependent_eq_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc)
|
|
{
|
|
ia_eq_instructions_struct* str_eq_instructions = NULL;
|
|
|
|
if (pstr_drc_uni_sel_proc->eq_inst_index_sel >= 0)
|
|
{
|
|
str_eq_instructions = &(pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.str_eq_instructions[pstr_drc_uni_sel_proc->eq_inst_index_sel]);
|
|
|
|
if (str_eq_instructions->depends_on_eq_set_present == 1)
|
|
{
|
|
WORD32 n;
|
|
WORD32 dependsOnEqSetID = str_eq_instructions->depends_on_eq_set;
|
|
|
|
for(n=0; n<pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.eq_instructions_count; n++)
|
|
{
|
|
if (pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.str_eq_instructions[n].eq_set_id == dependsOnEqSetID) break;
|
|
}
|
|
if (n == pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.eq_instructions_count)
|
|
{
|
|
return(UNEXPECTED_ERROR);
|
|
}
|
|
if (pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.str_eq_instructions[n].eq_apply_to_downmix == 1)
|
|
{
|
|
pstr_drc_uni_sel_proc->eq_inst_index[1] = n;
|
|
}
|
|
else
|
|
{
|
|
pstr_drc_uni_sel_proc->eq_inst_index[0] = n;
|
|
}
|
|
}
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
WORD32 impd_get_selected_loud_eq_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
|
|
WORD32 loudEqSetIdSelected)
|
|
{
|
|
WORD32 n;
|
|
|
|
pstr_drc_uni_sel_proc->loud_eq_inst_index_sel = -1;
|
|
|
|
if (loudEqSetIdSelected > 0)
|
|
{
|
|
for(n=0; n<pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.loud_eq_instructions_count; n++)
|
|
{
|
|
if (pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.loud_eq_instructions[n].loud_eq_set_id == loudEqSetIdSelected) break;
|
|
}
|
|
if (n == pstr_drc_uni_sel_proc->drc_config.str_drc_config_ext.loud_eq_instructions_count)
|
|
{
|
|
return(EXTERNAL_ERROR);
|
|
}
|
|
pstr_drc_uni_sel_proc->loud_eq_inst_index_sel = n;
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
WORD32 impd_select_loud_eq(ia_drc_config* pstr_drc_config,
|
|
WORD32 requested_dwnmix_id,
|
|
WORD32 drc_set_id_requested,
|
|
WORD32 eq_set_id_requested,
|
|
WORD32* loud_eq_id_sel)
|
|
{
|
|
WORD32 i, c, d, e;
|
|
|
|
*loud_eq_id_sel = 0;
|
|
for (i=0; i<pstr_drc_config->str_drc_config_ext.loud_eq_instructions_count; i++)
|
|
{
|
|
ia_loud_eq_instructions_struct* loud_eq_instructions = &pstr_drc_config->str_drc_config_ext.loud_eq_instructions[i];
|
|
if (loud_eq_instructions->drc_location == LOCATION_SELECTED) {
|
|
for (d=0; d<loud_eq_instructions->dwnmix_id_count; d++)
|
|
{
|
|
if ((loud_eq_instructions->downmix_id[d] == requested_dwnmix_id) || (loud_eq_instructions->downmix_id[d] == ID_FOR_ANY_DOWNMIX)) {
|
|
for (c=0; c<loud_eq_instructions->drc_set_id_count; c++)
|
|
{
|
|
if ((loud_eq_instructions->drc_set_id[c] == drc_set_id_requested) || (loud_eq_instructions->drc_set_id[c] == ID_FOR_ANY_DRC)) {
|
|
for (e=0; e<loud_eq_instructions->eq_set_id_count; e++)
|
|
{
|
|
if ((loud_eq_instructions->eq_set_id[e] == eq_set_id_requested) || (loud_eq_instructions->eq_set_id[e] == ID_FOR_ANY_EQ)) {
|
|
*loud_eq_id_sel = loud_eq_instructions->loud_eq_set_id;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
WORD32 impd_match_eq_set(ia_drc_config* drc_config,
|
|
WORD32 downmix_id,
|
|
WORD32 drc_set_id,
|
|
WORD32* eq_set_id_valid_flag,
|
|
WORD32* matching_eq_set_count,
|
|
WORD32* matching_eq_set_idx)
|
|
{
|
|
ia_eq_instructions_struct* str_eq_instructions = NULL;
|
|
WORD32 i, k, n;
|
|
WORD32 match = 0;
|
|
*matching_eq_set_count = 0;
|
|
for (i=0; i<drc_config->str_drc_config_ext.eq_instructions_count; i++)
|
|
{
|
|
str_eq_instructions = &drc_config->str_drc_config_ext.str_eq_instructions[i];
|
|
|
|
if (str_eq_instructions->depends_on_eq_set_present == 0) {
|
|
if (str_eq_instructions->no_independent_eq_use == 1) continue;
|
|
}
|
|
if (eq_set_id_valid_flag[str_eq_instructions->eq_set_id] == 0) continue;
|
|
for (k=0; k<str_eq_instructions->dwnmix_id_count; k++) {
|
|
if ((str_eq_instructions->downmix_id[k] == ID_FOR_ANY_DOWNMIX) || (downmix_id == str_eq_instructions->downmix_id[k])) {
|
|
for (n=0; n<str_eq_instructions->drc_set_id_count; n++) {
|
|
if ((str_eq_instructions->drc_set_id[n] == ID_FOR_ANY_DRC) || (drc_set_id == str_eq_instructions->drc_set_id[n])) {
|
|
match = 1;
|
|
matching_eq_set_idx[*matching_eq_set_count] = i;
|
|
(*matching_eq_set_count)++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
WORD32 impd_match_eq_set_purpose(ia_drc_config* drc_config,
|
|
WORD32 eq_set_purpose_requested,
|
|
WORD32* eq_set_id_valid_flag,
|
|
WORD32* selection_candidate_count,
|
|
ia_selection_candidate_info_struct* selection_candidate_info,
|
|
ia_selection_candidate_info_struct* selection_candidate_info_step_2
|
|
)
|
|
{
|
|
WORD32 i,j,k;
|
|
WORD32 match_found_flag;
|
|
WORD32 loop_cnt = 0;
|
|
ia_eq_instructions_struct* str_eq_instructions = NULL;
|
|
match_found_flag = 0;
|
|
|
|
k = 0;
|
|
while ((k==0) && (loop_cnt < 2))
|
|
{
|
|
for (j=0; j < *selection_candidate_count; j++)
|
|
{
|
|
WORD32 eq_set_id_requested = selection_candidate_info[j].eq_set_id;
|
|
|
|
for (i=0; i<drc_config->str_drc_config_ext.eq_instructions_count; i++)
|
|
{
|
|
str_eq_instructions = &drc_config->str_drc_config_ext.str_eq_instructions[i];
|
|
|
|
if (str_eq_instructions->depends_on_eq_set_present == 0) {
|
|
if (eq_set_id_valid_flag[str_eq_instructions->eq_set_id] == 0) continue;
|
|
}
|
|
if (eq_set_id_valid_flag[str_eq_instructions->eq_set_id] == 0) continue;
|
|
if ((str_eq_instructions->eq_set_id == eq_set_id_requested) && (str_eq_instructions->eq_set_purpose & eq_set_purpose_requested))
|
|
{
|
|
match_found_flag = 1;
|
|
}
|
|
}
|
|
|
|
if (match_found_flag > 0)
|
|
{
|
|
memcpy(&selection_candidate_info_step_2[k], &selection_candidate_info[j], sizeof(ia_selection_candidate_info_struct));
|
|
k++;
|
|
}
|
|
}
|
|
eq_set_purpose_requested = EQ_PURPOSE_DEFAULT;
|
|
loop_cnt++;
|
|
}
|
|
|
|
if (k>0) {
|
|
memcpy(&selection_candidate_info[0], &selection_candidate_info_step_2[0], k * sizeof(ia_selection_candidate_info_struct));
|
|
*selection_candidate_count = k;
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
WORD32 impd_find_eq_set_no_compression(ia_drc_config* pstr_drc_config,
|
|
WORD32 requested_dwnmix_id,
|
|
WORD32* num_compression_eq_count,
|
|
WORD32* num_compression_eq_id)
|
|
{
|
|
WORD32 i, d, k, c;
|
|
k=0;
|
|
for (i=0; i<pstr_drc_config->str_drc_config_ext.eq_instructions_count; i++)
|
|
{
|
|
ia_eq_instructions_struct* str_eq_instructions = &pstr_drc_config->str_drc_config_ext.str_eq_instructions[i];
|
|
for (d=0; d<str_eq_instructions->dwnmix_id_count; d++)
|
|
{
|
|
if (requested_dwnmix_id == str_eq_instructions->downmix_id[d])
|
|
{
|
|
for (c=0; c<str_eq_instructions->drc_set_id_count; c++)
|
|
{
|
|
if ((str_eq_instructions->drc_set_id[c] == ID_FOR_ANY_DRC) || (str_eq_instructions->drc_set_id[c] == 0))
|
|
{
|
|
num_compression_eq_id[k] = str_eq_instructions->eq_set_id;
|
|
k++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*num_compression_eq_count = k;
|
|
return (0);
|
|
}
|
|
|
|
|
|
VOID impd_select_drc_coeff3(ia_drc_config* drc_config,
|
|
ia_uni_drc_coeffs_struct** str_p_loc_drc_coefficients_uni_drc)
|
|
{
|
|
WORD32 n;
|
|
WORD32 cV1 = -1;
|
|
WORD32 cV0 = -1;
|
|
for(n=0; n<drc_config->drc_coefficients_drc_count; n++)
|
|
{
|
|
if (drc_config->str_p_loc_drc_coefficients_uni_drc[n].drc_location == 1)
|
|
{
|
|
if (drc_config->str_p_loc_drc_coefficients_uni_drc[n].version == 0)
|
|
{
|
|
cV0 = n;
|
|
}
|
|
else
|
|
{
|
|
cV1 = n;
|
|
}
|
|
}
|
|
}
|
|
if (cV1 >= 0) {
|
|
*str_p_loc_drc_coefficients_uni_drc = &(drc_config->str_p_loc_drc_coefficients_uni_drc[cV1]);
|
|
}
|
|
else if (cV0 >= 0) {
|
|
*str_p_loc_drc_coefficients_uni_drc = &(drc_config->str_p_loc_drc_coefficients_uni_drc[cV0]);
|
|
}
|
|
else {
|
|
*str_p_loc_drc_coefficients_uni_drc = NULL;
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
WORD32 impd_manage_drc_complexity (ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
|
|
ia_drc_config* pstr_drc_config)
|
|
{
|
|
WORD32 i, j, err, channel_count;
|
|
WORD32 numBandsTooLarge = 0;
|
|
FLOAT32 complexityDrcPrelim;
|
|
ia_uni_drc_coeffs_struct* str_p_loc_drc_coefficients_uni_drc;
|
|
FLOAT32 complexitySupportedTotal = (FLOAT32)(pow(2.0f, pstr_drc_uni_sel_proc->compl_level_supported_total));
|
|
ia_drc_instructions_struct* str_drc_instruction_str;
|
|
ia_drc_instructions_struct* drc_inst_uni_drc_dependent;
|
|
ia_drc_sel_proc_output_struct* uni_drc_sel_proc_output = &pstr_drc_uni_sel_proc->uni_drc_sel_proc_output;
|
|
ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct = &pstr_drc_uni_sel_proc->uni_drc_sel_proc_params;
|
|
|
|
impd_select_drc_coeff3(pstr_drc_config, &str_p_loc_drc_coefficients_uni_drc);
|
|
|
|
for (i=0; i<pstr_drc_config->drc_instructions_uni_drc_count; i++)
|
|
{
|
|
str_drc_instruction_str = &pstr_drc_config->str_drc_instruction_str[i];
|
|
if (str_drc_instruction_str->no_independent_use) continue;
|
|
|
|
numBandsTooLarge = 0;
|
|
if (str_drc_instruction_str->drc_apply_to_dwnmix == 1)
|
|
{
|
|
channel_count = uni_drc_sel_proc_output->target_channel_count;
|
|
}
|
|
else
|
|
{
|
|
channel_count = uni_drc_sel_proc_output->base_channel_count;
|
|
}
|
|
if (pstr_drc_uni_sel_proc->subband_domain_mode == SUBBAND_DOMAIN_MODE_OFF)
|
|
{
|
|
for (j=0; j<str_drc_instruction_str->num_drc_ch_groups; j++)
|
|
{
|
|
ia_gain_set_params_struct* gain_set_params = &(str_p_loc_drc_coefficients_uni_drc->gain_set_params[str_drc_instruction_str->gain_set_index_for_channel_group[j]]);
|
|
if (gain_set_params->band_count > pstr_drc_sel_proc_params_struct->num_bands_supported)
|
|
{
|
|
numBandsTooLarge = 1;
|
|
}
|
|
else
|
|
{
|
|
if (gain_set_params->band_count > 4)
|
|
{
|
|
/* Add complexity for analysis and synthesis QMF bank here, if supported */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
complexityDrcPrelim =(FLOAT32)( channel_count * (1 << str_drc_instruction_str->drc_set_complexity_level));
|
|
|
|
if (str_drc_instruction_str->depends_on_drc_set > 0)
|
|
{
|
|
err = impd_find_drc_instructions_uni_drc(pstr_drc_config, str_drc_instruction_str->depends_on_drc_set, &drc_inst_uni_drc_dependent);
|
|
if (err) return (err);
|
|
if (drc_inst_uni_drc_dependent->drc_apply_to_dwnmix == 1)
|
|
{
|
|
channel_count = uni_drc_sel_proc_output->target_channel_count;
|
|
}
|
|
else
|
|
{
|
|
channel_count = uni_drc_sel_proc_output->base_channel_count;
|
|
}
|
|
if (pstr_drc_uni_sel_proc->subband_domain_mode == SUBBAND_DOMAIN_MODE_OFF)
|
|
{
|
|
for (j=0; j<str_drc_instruction_str->num_drc_ch_groups; j++)
|
|
{
|
|
ia_gain_set_params_struct* gain_set_params = &(str_p_loc_drc_coefficients_uni_drc->gain_set_params[drc_inst_uni_drc_dependent->gain_set_index_for_channel_group[j]]);
|
|
if (gain_set_params->band_count > pstr_drc_sel_proc_params_struct->num_bands_supported)
|
|
{
|
|
numBandsTooLarge = 1;
|
|
}
|
|
else
|
|
{
|
|
if (gain_set_params->band_count > 4)
|
|
{
|
|
/* Add complexity for analysis and synthesis QMF bank here, if supported */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
complexityDrcPrelim += channel_count * (1 << drc_inst_uni_drc_dependent->drc_set_complexity_level);
|
|
}
|
|
|
|
complexityDrcPrelim *= pstr_drc_config->sampling_rate / 48000.0f;
|
|
|
|
if ((complexityDrcPrelim <= complexitySupportedTotal) && (numBandsTooLarge == 0))
|
|
{
|
|
pstr_drc_uni_sel_proc->drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id] = 1;
|
|
}
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
WORD32 impd_manage_eq_complexity (ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
|
|
ia_drc_config* pstr_drc_config)
|
|
{
|
|
WORD32 k, n, m, err;
|
|
WORD32 eqComplexityPrimary = 0;
|
|
WORD32 eqComplexityDependent = 0;
|
|
WORD32 eqChannelCountPrimary = 0, eqChannelCountDependent = 0;
|
|
FLOAT32 complexityTotalEq;
|
|
ia_drc_config* drc_config = &pstr_drc_uni_sel_proc->drc_config;
|
|
ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct = &pstr_drc_uni_sel_proc->uni_drc_sel_proc_params;
|
|
FLOAT32 complexitySupportedTotal =(FLOAT32)( pow(2.0f, pstr_drc_uni_sel_proc->compl_level_supported_total));
|
|
|
|
for (n=0; n<drc_config->str_drc_config_ext.eq_instructions_count; n++)
|
|
{
|
|
ia_eq_instructions_struct* str_eq_instructions = &pstr_drc_config->str_drc_config_ext.str_eq_instructions[n];
|
|
|
|
eqChannelCountPrimary = pstr_drc_sel_proc_params_struct->base_channel_count;
|
|
eqChannelCountDependent = pstr_drc_sel_proc_params_struct->base_channel_count;
|
|
|
|
eqComplexityPrimary = 1 << str_eq_instructions->eq_set_complexity_level;
|
|
if (pstr_drc_uni_sel_proc->subband_domain_mode == SUBBAND_DOMAIN_MODE_OFF)
|
|
{
|
|
if (str_eq_instructions->td_filter_cascade_present == 0)
|
|
{
|
|
eqComplexityPrimary = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (str_eq_instructions->td_filter_cascade_present == 1)
|
|
{
|
|
eqComplexityPrimary =(WORD32) 2.5f;
|
|
}
|
|
}
|
|
if (str_eq_instructions->eq_apply_to_downmix == 1)
|
|
{
|
|
if (str_eq_instructions->downmix_id[0] == ID_FOR_ANY_DOWNMIX)
|
|
{
|
|
eqChannelCountPrimary = pstr_drc_sel_proc_params_struct->target_ch_count_prelim;
|
|
}
|
|
else
|
|
{
|
|
for (k=0; k<pstr_drc_config->dwnmix_instructions_count; k++)
|
|
{
|
|
for (m=0; m<str_eq_instructions->dwnmix_id_count; m++)
|
|
{
|
|
if (pstr_drc_config->dwnmix_instructions[k].downmix_id == str_eq_instructions->downmix_id[m])
|
|
{
|
|
if (eqChannelCountPrimary > pstr_drc_config->dwnmix_instructions[k].target_channel_count) {
|
|
eqChannelCountPrimary = pstr_drc_config->dwnmix_instructions[k].target_channel_count;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
complexityTotalEq = (FLOAT32)(eqChannelCountPrimary * eqComplexityPrimary);
|
|
|
|
if (str_eq_instructions->depends_on_eq_set_present > 0)
|
|
{
|
|
ia_eq_instructions_struct* eq_instructionsDependent;
|
|
err = impd_find_eq_instructions(drc_config, str_eq_instructions->depends_on_eq_set, &eq_instructionsDependent);
|
|
if (err) return (err);
|
|
eqComplexityDependent = 1 << eq_instructionsDependent->eq_set_complexity_level;
|
|
if (pstr_drc_uni_sel_proc->subband_domain_mode == SUBBAND_DOMAIN_MODE_OFF)
|
|
{
|
|
if (str_eq_instructions->td_filter_cascade_present == 0)
|
|
{
|
|
eqComplexityDependent = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (str_eq_instructions->td_filter_cascade_present == 1)
|
|
{
|
|
eqComplexityDependent =(WORD32) 2.5f;
|
|
}
|
|
}
|
|
if (eq_instructionsDependent->eq_apply_to_downmix == 1)
|
|
{
|
|
if (eq_instructionsDependent->downmix_id[0] == ID_FOR_ANY_DOWNMIX)
|
|
{
|
|
eqChannelCountDependent = pstr_drc_sel_proc_params_struct->target_ch_count_prelim;
|
|
}
|
|
else
|
|
{
|
|
for (k=0; k<pstr_drc_config->dwnmix_instructions_count; k++)
|
|
{
|
|
for (m=0; m<str_eq_instructions->dwnmix_id_count; m++)
|
|
{
|
|
if (pstr_drc_config->dwnmix_instructions[k].downmix_id == eq_instructionsDependent->downmix_id[m])
|
|
{
|
|
if (eqChannelCountDependent > pstr_drc_config->dwnmix_instructions[k].target_channel_count) {
|
|
eqChannelCountDependent = pstr_drc_config->dwnmix_instructions[k].target_channel_count;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
complexityTotalEq += eqChannelCountDependent * eqComplexityDependent;
|
|
}
|
|
|
|
pstr_drc_uni_sel_proc->eq_set_id_valid_flag[str_eq_instructions->eq_set_id] = 0;
|
|
complexityTotalEq *= pstr_drc_config->sampling_rate / 48000.0f;
|
|
|
|
if (complexityTotalEq <= complexitySupportedTotal)
|
|
{
|
|
pstr_drc_uni_sel_proc->eq_set_id_valid_flag[str_eq_instructions->eq_set_id] = 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
WORD32 impd_manage_complexity (ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
|
|
ia_drc_config* pstr_drc_config,
|
|
WORD32* repeat_selection)
|
|
{
|
|
WORD32 i, j, p, err;
|
|
WORD32 channel_count;
|
|
WORD32 numBandsTooLarge = 0;
|
|
WORD32 drcRequiresEq;
|
|
FLOAT32 complexityEq;
|
|
FLOAT32 complexityDrcTotal = 0.0f;
|
|
FLOAT32 complexityEqTotal = 0.0f;
|
|
FLOAT32 freqNorm = pstr_drc_config->sampling_rate / 48000.0f;
|
|
ia_uni_drc_coeffs_struct* str_p_loc_drc_coefficients_uni_drc;
|
|
ia_drc_instructions_struct* str_drc_instruction_str = &pstr_drc_config->str_drc_instruction_str[0];
|
|
ia_drc_sel_proc_output_struct* uni_drc_sel_proc_output = &pstr_drc_uni_sel_proc->uni_drc_sel_proc_output;
|
|
ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct = &pstr_drc_uni_sel_proc->uni_drc_sel_proc_params;
|
|
FLOAT32 complexitySupportedTotal =(FLOAT32)( pow(2.0f, pstr_drc_uni_sel_proc->compl_level_supported_total));
|
|
|
|
impd_select_drc_coeff3(pstr_drc_config, &str_p_loc_drc_coefficients_uni_drc);
|
|
|
|
for (p=0; p<4; p++)
|
|
{
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[p] <= 0) continue;
|
|
err = impd_find_drc_instructions_uni_drc(pstr_drc_config, pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[p], &str_drc_instruction_str);
|
|
if (err) return (err);
|
|
|
|
if (str_drc_instruction_str->drc_apply_to_dwnmix == 1)
|
|
{
|
|
channel_count = uni_drc_sel_proc_output->target_channel_count;
|
|
}
|
|
else
|
|
{
|
|
channel_count = uni_drc_sel_proc_output->base_channel_count;
|
|
}
|
|
if (pstr_drc_uni_sel_proc->subband_domain_mode == SUBBAND_DOMAIN_MODE_OFF)
|
|
{
|
|
for (j=0; j<str_drc_instruction_str->num_drc_ch_groups; j++)
|
|
{
|
|
ia_gain_set_params_struct* gain_set_params = &(str_p_loc_drc_coefficients_uni_drc->gain_set_params[str_drc_instruction_str->gain_set_index_for_channel_group[j]]);
|
|
if (gain_set_params->band_count > pstr_drc_sel_proc_params_struct->num_bands_supported)
|
|
{
|
|
if (p<2)
|
|
{
|
|
numBandsTooLarge = 1;
|
|
}
|
|
else
|
|
{
|
|
pstr_drc_uni_sel_proc->drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id] = 0;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[p] = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (gain_set_params->band_count > 4)
|
|
{
|
|
/* Add complexity for analysis and synthesis QMF bank here, if supported */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
complexityDrcTotal += channel_count * (1 << str_drc_instruction_str->drc_set_complexity_level);
|
|
}
|
|
|
|
if (uni_drc_sel_proc_output->active_downmix_id > 0)
|
|
{
|
|
FLOAT32 complexityPerCoeff;
|
|
ia_downmix_instructions_struct* dwnmix_instructions;
|
|
|
|
if (pstr_drc_uni_sel_proc->subband_domain_mode == SUBBAND_DOMAIN_MODE_OFF)
|
|
{
|
|
complexityPerCoeff = 1.0f;
|
|
}
|
|
else
|
|
{
|
|
complexityPerCoeff = 2.0f;
|
|
}
|
|
impd_find_downmix(pstr_drc_config, uni_drc_sel_proc_output->active_downmix_id, &dwnmix_instructions);
|
|
if (dwnmix_instructions->downmix_coefficients_present == 1)
|
|
{
|
|
for (i=0; i<uni_drc_sel_proc_output->base_channel_count; i++)
|
|
{
|
|
for (j=0; j<uni_drc_sel_proc_output->target_channel_count; j++)
|
|
{
|
|
if (uni_drc_sel_proc_output->downmix_matrix[i][j] != 0.0f)
|
|
{
|
|
complexityDrcTotal += complexityPerCoeff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* add standard downmix here */
|
|
}
|
|
}
|
|
|
|
for (p=0; p<2; p++)
|
|
{
|
|
if(pstr_drc_uni_sel_proc->eq_inst_index[p] >= 0)
|
|
{
|
|
ia_eq_instructions_struct* str_eq_instructions = &pstr_drc_config->str_drc_config_ext.str_eq_instructions[pstr_drc_uni_sel_proc->eq_inst_index[p]];
|
|
if (p==0)
|
|
{
|
|
channel_count = uni_drc_sel_proc_output->base_channel_count;
|
|
}
|
|
else
|
|
{
|
|
channel_count = uni_drc_sel_proc_output->target_channel_count;
|
|
}
|
|
|
|
complexityEq =(FLOAT32)(1 << str_eq_instructions->eq_set_complexity_level);
|
|
if (pstr_drc_uni_sel_proc->subband_domain_mode == SUBBAND_DOMAIN_MODE_OFF)
|
|
{
|
|
if (str_eq_instructions->td_filter_cascade_present == 0)
|
|
{
|
|
complexityEq = 0.0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (str_eq_instructions->td_filter_cascade_present == 1)
|
|
{
|
|
complexityEq = 2.5;
|
|
}
|
|
}
|
|
|
|
complexityEqTotal += channel_count * complexityEq;
|
|
}
|
|
}
|
|
|
|
complexityDrcTotal *= freqNorm;
|
|
complexityEqTotal *= freqNorm;
|
|
|
|
if (numBandsTooLarge == 1)
|
|
{
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[0] > 0)
|
|
{
|
|
err = impd_find_drc_instructions_uni_drc(pstr_drc_config, pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[0], &str_drc_instruction_str);
|
|
if (err) return (err);
|
|
|
|
pstr_drc_uni_sel_proc->drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id] = 0;
|
|
}
|
|
*repeat_selection = 1;
|
|
}
|
|
else
|
|
{
|
|
if (complexityDrcTotal + complexityEqTotal <= complexitySupportedTotal)
|
|
{
|
|
*repeat_selection = 0;
|
|
}
|
|
else
|
|
{
|
|
drcRequiresEq = 0;
|
|
for (p=0; p<2; p++)
|
|
{
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[p] <= 0) continue;
|
|
err = impd_find_drc_instructions_uni_drc(pstr_drc_config, pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[p], &str_drc_instruction_str);
|
|
if (err) return (err);
|
|
if (str_drc_instruction_str->requires_eq == 1)
|
|
{
|
|
drcRequiresEq = 1;
|
|
}
|
|
}
|
|
if ((drcRequiresEq == 0) && (complexityDrcTotal <= complexitySupportedTotal))
|
|
{
|
|
for (p=0; p<2; p++)
|
|
{
|
|
pstr_drc_uni_sel_proc->eq_inst_index[p] = 0;
|
|
}
|
|
*repeat_selection = 0;
|
|
}
|
|
else
|
|
{
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[0] > 0)
|
|
{
|
|
err = impd_find_drc_instructions_uni_drc(pstr_drc_config, pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[0], &str_drc_instruction_str);
|
|
if (err) return (err);
|
|
|
|
pstr_drc_uni_sel_proc->drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id] = 0;
|
|
}
|
|
else
|
|
{
|
|
for (p=2; p<4; p++)
|
|
{
|
|
pstr_drc_uni_sel_proc->drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id] = 0;
|
|
pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.sel_drc_set_ids[p] = 0;
|
|
}
|
|
}
|
|
*repeat_selection = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (*repeat_selection == 1)
|
|
{
|
|
memset (&pstr_drc_uni_sel_proc->uni_drc_sel_proc_output, 0, sizeof(ia_drc_sel_proc_output_struct));
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
|
|
|
|
WORD32 impd_find_loud_eq_instructions_idx_for_id(ia_drc_config* drc_config,
|
|
WORD32 loud_eq_set_id_requested,
|
|
WORD32* instructions_idx)
|
|
{
|
|
WORD32 i;
|
|
if (loud_eq_set_id_requested > 0)
|
|
{
|
|
for (i=0; i<drc_config->str_drc_config_ext.loud_eq_instructions_count; i++)
|
|
{
|
|
if (drc_config->str_drc_config_ext.loud_eq_instructions[i].loud_eq_set_id == loud_eq_set_id_requested) break;
|
|
}
|
|
if (i == drc_config->str_drc_config_ext.loud_eq_instructions_count)
|
|
{
|
|
return (UNEXPECTED_ERROR);
|
|
}
|
|
*instructions_idx = i;
|
|
}
|
|
else
|
|
{
|
|
*instructions_idx = -1;
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
|
|
WORD32 impd_find_eq_instructions(ia_drc_config* drc_config,
|
|
WORD32 eq_set_id_requested,
|
|
ia_eq_instructions_struct** str_eq_instructions)
|
|
{
|
|
WORD32 i;
|
|
for (i=0; i<drc_config->str_drc_config_ext.eq_instructions_count; i++)
|
|
{
|
|
if (eq_set_id_requested == drc_config->str_drc_config_ext.str_eq_instructions[i].eq_set_id) break;
|
|
}
|
|
if (i == drc_config->str_drc_config_ext.eq_instructions_count)
|
|
{
|
|
return (UNEXPECTED_ERROR);
|
|
}
|
|
*str_eq_instructions = &drc_config->str_drc_config_ext.str_eq_instructions[i];
|
|
return (0);
|
|
}
|
|
|
|
WORD32 impd_find_downmix(ia_drc_config* drc_config,
|
|
WORD32 requested_dwnmix_id,
|
|
ia_downmix_instructions_struct** dwnmix_instructions)
|
|
{
|
|
WORD32 i;
|
|
for (i=0; i<drc_config->dwnmix_instructions_count; i++)
|
|
{
|
|
if (requested_dwnmix_id == drc_config->dwnmix_instructions[i].downmix_id) break;
|
|
}
|
|
if (i == drc_config->dwnmix_instructions_count)
|
|
{
|
|
|
|
return (UNEXPECTED_ERROR);
|
|
}
|
|
*dwnmix_instructions = &drc_config->dwnmix_instructions[i];
|
|
return (0);
|
|
}
|
|
|