2018-05-17 14:36:48 -07:00
|
|
|
/******************************************************************************
|
2018-05-25 11:19:24 -07:00
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
2018-05-17 14:36:48 -07:00
|
|
|
*****************************************************************************
|
2018-05-25 11:19:24 -07:00
|
|
|
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
|
|
|
|
|
*/
|
2018-05-17 14:36:48 -07:00
|
|
|
#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"
|
2025-07-28 17:40:45 +05:30
|
|
|
#ifdef LOUDNESS_LEVELING_SUPPORT
|
|
|
|
|
#include "ixheaac_error_standards.h"
|
|
|
|
|
#endif
|
2018-05-17 14:36:48 -07:00
|
|
|
|
2019-03-20 08:57:35 +05:30
|
|
|
static const WORD32 effect_types_request_table[] = {
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
break;
|
|
|
|
|
case MATCH_DYNAMIC_RANGE:
|
|
|
|
|
break;
|
|
|
|
|
case MATCH_DRC_CHARACTERISTIC:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return (UNEXPECTED_ERROR);
|
|
|
|
|
break;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
return (0);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
WORD32 impd_map_requested_effect_bit_idx(WORD32 requested_effect_type,
|
|
|
|
|
WORD32* effect_bit_idx) {
|
|
|
|
|
switch (requested_effect_type) {
|
2018-05-25 11:19:24 -07:00
|
|
|
case EFFECT_TYPE_REQUESTED_NONE:
|
2018-06-01 13:27:00 +05:30
|
|
|
*effect_bit_idx = EFFECT_BIT_NONE;
|
|
|
|
|
break;
|
2018-05-25 11:19:24 -07:00
|
|
|
case EFFECT_TYPE_REQUESTED_NIGHT:
|
2018-06-01 13:27:00 +05:30
|
|
|
*effect_bit_idx = EFFECT_BIT_NIGHT;
|
|
|
|
|
break;
|
2018-05-25 11:19:24 -07:00
|
|
|
case EFFECT_TYPE_REQUESTED_NOISY:
|
2018-06-01 13:27:00 +05:30
|
|
|
*effect_bit_idx = EFFECT_BIT_NOISY;
|
|
|
|
|
break;
|
2018-05-25 11:19:24 -07:00
|
|
|
case EFFECT_TYPE_REQUESTED_LIMITED:
|
2018-06-01 13:27:00 +05:30
|
|
|
*effect_bit_idx = EFFECT_BIT_LIMITED;
|
|
|
|
|
break;
|
2018-05-25 11:19:24 -07:00
|
|
|
case EFFECT_TYPE_REQUESTED_LOWLEVEL:
|
2018-06-01 13:27:00 +05:30
|
|
|
*effect_bit_idx = EFFECT_BIT_LOWLEVEL;
|
|
|
|
|
break;
|
2018-05-25 11:19:24 -07:00
|
|
|
case EFFECT_TYPE_REQUESTED_DIALOG:
|
2018-06-01 13:27:00 +05:30
|
|
|
*effect_bit_idx = EFFECT_BIT_DIALOG;
|
|
|
|
|
break;
|
2018-05-25 11:19:24 -07:00
|
|
|
case EFFECT_TYPE_REQUESTED_GENERAL_COMPR:
|
2018-06-01 13:27:00 +05:30
|
|
|
*effect_bit_idx = EFFECT_BIT_GENERAL_COMPR;
|
|
|
|
|
break;
|
2018-05-25 11:19:24 -07:00
|
|
|
case EFFECT_TYPE_REQUESTED_EXPAND:
|
2018-06-01 13:27:00 +05:30
|
|
|
*effect_bit_idx = EFFECT_BIT_EXPAND;
|
|
|
|
|
break;
|
2018-05-25 11:19:24 -07:00
|
|
|
case EFFECT_TYPE_REQUESTED_ARTISTIC:
|
2018-06-01 13:27:00 +05:30
|
|
|
*effect_bit_idx = EFFECT_BIT_ARTISTIC;
|
|
|
|
|
break;
|
2018-05-25 11:19:24 -07:00
|
|
|
|
|
|
|
|
default:
|
2018-06-01 13:27:00 +05:30
|
|
|
return (UNEXPECTED_ERROR);
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return (0);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
return (0);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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) {
|
2025-07-28 17:40:45 +05:30
|
|
|
#ifdef LOUDNESS_LEVELING_SUPPORT
|
|
|
|
|
if (drc_instructions_index != -1) break;
|
|
|
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.loudness_leveling_on == 0 &&
|
|
|
|
|
str_drc_instruction_str->leveling_present == 1)
|
|
|
|
|
continue;
|
|
|
|
|
#endif
|
2018-06-01 13:27:00 +05:30
|
|
|
drc_instructions_index = n;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
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) {
|
2025-07-28 17:40:45 +05:30
|
|
|
#ifdef LOUDNESS_LEVELING_SUPPORT
|
|
|
|
|
if (drc_instructions_index != -1) break;
|
|
|
|
|
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.loudness_leveling_on == 0 &&
|
|
|
|
|
str_drc_instruction_str->leveling_present == 1)
|
|
|
|
|
continue;
|
|
|
|
|
#endif
|
2018-06-01 13:27:00 +05:30
|
|
|
drc_instructions_index = n;
|
|
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
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);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WORD32 impd_get_selected_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
|
2018-06-01 13:27:00 +05:30
|
|
|
WORD32 drc_set_id_selected) {
|
|
|
|
|
WORD32 n;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
pstr_drc_uni_sel_proc->drc_instructions_index[0] =
|
|
|
|
|
pstr_drc_uni_sel_proc->drc_inst_index_sel;
|
|
|
|
|
return (0);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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]);
|
2018-05-17 14:36:48 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
if (n == pstr_drc_uni_sel_proc->drc_config.drc_instructions_count_plus) {
|
|
|
|
|
return (UNEXPECTED_ERROR);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
pstr_drc_uni_sel_proc->drc_instructions_index[1] = n;
|
|
|
|
|
} else {
|
|
|
|
|
pstr_drc_uni_sel_proc->drc_instructions_index[1] = -1;
|
|
|
|
|
}
|
|
|
|
|
return (0);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
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);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
|
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
if (match == 1) {
|
2018-09-28 17:58:53 +05:30
|
|
|
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
memcpy(&selection_candidate_info_step_2[k], &selection_candidate_info[i],
|
|
|
|
|
sizeof(ia_selection_candidate_info_struct));
|
|
|
|
|
k++;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
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;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
} else {
|
|
|
|
|
*match_found_flag = 0;
|
|
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
return (0);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
2018-05-17 14:36:48 -07:00
|
|
|
if (err) return (err);
|
2018-06-01 13:27:00 +05:30
|
|
|
} 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);
|
2018-05-17 14:36:48 -07:00
|
|
|
if (err) return (err);
|
2018-06-01 13:27:00 +05:30
|
|
|
|
|
|
|
|
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)) {
|
2018-09-28 17:58:53 +05:30
|
|
|
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
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)) {
|
2018-09-28 17:58:53 +05:30
|
|
|
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
memcpy(&selection_candidate_info_step_2[k],
|
|
|
|
|
&selection_candidate_info[i],
|
|
|
|
|
sizeof(ia_selection_candidate_info_struct));
|
|
|
|
|
k++;
|
|
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
} else {
|
|
|
|
|
if (state_requested == 1) {
|
|
|
|
|
if ((str_drc_instruction_str->drc_set_effect & effect_bit_idx) !=
|
|
|
|
|
0x0) {
|
2018-09-28 17:58:53 +05:30
|
|
|
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
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) {
|
2018-09-28 17:58:53 +05:30
|
|
|
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
memcpy(&selection_candidate_info_step_2[k],
|
|
|
|
|
&selection_candidate_info[i],
|
|
|
|
|
sizeof(ia_selection_candidate_info_struct));
|
|
|
|
|
k++;
|
|
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
selection_candidate_step_2_count = k;
|
2018-05-17 14:36:48 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
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;
|
2022-09-29 17:34:48 +05:30
|
|
|
WORD32 desired_effect_type_found;
|
2018-06-01 13:27:00 +05:30
|
|
|
|
|
|
|
|
desired_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);
|
|
|
|
|
k++;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
return (0);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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)) {
|
2018-09-28 17:58:53 +05:30
|
|
|
if (k >= DRC_INSTRUCTIONS_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
selected[k] = i;
|
|
|
|
|
k++;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
} 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;
|
|
|
|
|
}
|
2018-09-28 17:58:53 +05:30
|
|
|
if (k >= DRC_INSTRUCTIONS_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
selected[k] = i;
|
|
|
|
|
k++;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
return (0);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
if (i == pstr_drc_config->drc_coefficients_drc_count) {
|
|
|
|
|
return (UNEXPECTED_ERROR);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
if ((ref_count > 0) && (((FLOAT32)match_count) > 0.5f * ref_count)) {
|
2018-09-28 17:58:53 +05:30
|
|
|
if (n >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
memcpy(&selection_candidate_info[n], &selection_candidate_info[i],
|
|
|
|
|
sizeof(ia_selection_candidate_info_struct));
|
|
|
|
|
n++;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
if (n > 0) {
|
|
|
|
|
*selection_candidate_count = n;
|
|
|
|
|
*match_found_flag = 1;
|
|
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
return (0);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
|
|
|
|
|
2019-03-20 08:57:35 +05:30
|
|
|
const WORD32* drc_characteristic_order =
|
2018-06-01 13:27:00 +05:30
|
|
|
drc_characteristic_order_default[requested_drc_characteristic - 1];
|
2019-03-20 08:57:35 +05:30
|
|
|
const WORD32 drc_characteristic_order_count =
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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];
|
2023-09-22 17:30:42 +05:30
|
|
|
WORD32 explicit_peak_information_present[16] = { 0 };
|
2018-06-01 13:27:00 +05:30
|
|
|
|
|
|
|
|
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);
|
2018-09-20 19:28:22 +05:30
|
|
|
if (str_p_loc_drc_coefficients_uni_drc == NULL) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
|
|
|
|
|
2018-09-21 19:13:36 +05:30
|
|
|
if (loudness_info_count > MAX_LOUDNESS_INFO_COUNT)
|
|
|
|
|
return UNEXPECTED_ERROR;
|
|
|
|
|
|
2019-05-08 15:21:19 +05:30
|
|
|
impd_signal_peak_level_info(
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
for (l = 0; l < loudness_info_count; l++) {
|
|
|
|
|
WORD32 match_found_flag = 0;
|
|
|
|
|
WORD32 p;
|
2018-09-21 19:13:36 +05:30
|
|
|
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
|
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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)
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-05-17 14:36:48 -07:00
|
|
|
{
|
2018-06-01 13:27:00 +05:30
|
|
|
match_found_flag = 1;
|
|
|
|
|
break;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
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++;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
} 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);
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2019-05-08 15:21:19 +05:30
|
|
|
impd_signal_peak_level_info(
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
|
|
|
|
for (l = 0; l < loudness_info_count; l++) {
|
|
|
|
|
WORD32 match_found_flag = 0;
|
|
|
|
|
WORD32 p;
|
2019-04-10 15:35:29 +05:30
|
|
|
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
|
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
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;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
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++;
|
|
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-10 15:35:29 +05:30
|
|
|
if (k > SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
*selection_candidate_count = k;
|
2019-04-10 15:35:29 +05:30
|
|
|
if (pstr_drc_sel_proc_params_struct->dynamic_range_control_on == 1) {
|
2018-06-01 13:27:00 +05:30
|
|
|
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++) {
|
2018-09-28 17:58:53 +05:30
|
|
|
if (n >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
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++;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
if (str_drc_instruction_str->requires_eq == 0) {
|
2018-09-28 17:58:53 +05:30
|
|
|
if (n >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
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++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-09-28 17:58:53 +05:30
|
|
|
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));
|
2018-06-01 13:27:00 +05:30
|
|
|
*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;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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) {
|
2018-09-28 17:58:53 +05:30
|
|
|
if (j >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
memcpy(&selection_candidate_info[j], &selection_candidate_info[k],
|
|
|
|
|
sizeof(ia_selection_candidate_info_struct));
|
|
|
|
|
j++;
|
|
|
|
|
break;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
*selection_candidate_count = j;
|
|
|
|
|
}
|
|
|
|
|
return (0);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
|
|
|
|
|
2019-05-08 15:21:19 +05:30
|
|
|
err = 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);
|
|
|
|
|
if (err) return (err);
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
if (output_level_min <= 0.0f) {
|
|
|
|
|
selection_candidate_step_2_count = *selection_candidate_count;
|
2018-05-25 11:19:24 -07:00
|
|
|
k = 0;
|
2018-06-01 13:27:00 +05:30
|
|
|
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++;
|
|
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
|
|
|
|
selection_candidate_step_2_count = k;
|
|
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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]) {
|
2020-01-07 18:54:19 +05:30
|
|
|
if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
|
2018-06-01 13:27:00 +05:30
|
|
|
memcpy(&selection_candidate_info_step_2[k],
|
|
|
|
|
&selection_candidate_info_step_2[i],
|
|
|
|
|
sizeof(ia_selection_candidate_info_struct));
|
|
|
|
|
k++;
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (k > 0) {
|
|
|
|
|
selection_candidate_step_2_count = k;
|
|
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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++;
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} 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++;
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
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;
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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++;
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
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;
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
2018-05-25 11:19:24 -07:00
|
|
|
k = 0;
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
memcpy(&selection_candidate_info_step_2[k],
|
|
|
|
|
&selection_candidate_info_step_2[i],
|
|
|
|
|
sizeof(ia_selection_candidate_info_struct));
|
|
|
|
|
k++;
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
selection_candidate_step_2_count = k;
|
|
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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++;
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
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;
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
2018-05-25 11:19:24 -07:00
|
|
|
k = 0;
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
memcpy(&selection_candidate_info_step_2[k],
|
|
|
|
|
&selection_candidate_info_step_2[i],
|
|
|
|
|
sizeof(ia_selection_candidate_info_struct));
|
|
|
|
|
k++;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
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;
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
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++;
|
2018-05-25 11:19:24 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
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;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
return 0;
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WORD32 impd_select_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
|
2018-06-01 13:27:00 +05:30
|
|
|
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) {
|
2018-09-24 15:58:55 +05:30
|
|
|
err = impd_drc_set_preselection(
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
2018-09-24 15:58:55 +05:30
|
|
|
if (err) return err;
|
2018-06-01 13:27:00 +05:30
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
err = impd_validate_requested_drc_feature(pstr_drc_sel_proc_params_struct);
|
|
|
|
|
if (err) return (err);
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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;
|
|
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
} else {
|
|
|
|
|
WORD32 match_found_flag = 0;
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
err = impd_select_drcs_without_compr_effects(
|
|
|
|
|
pstr_drc_config, &match_found_flag, &selection_candidate_count,
|
|
|
|
|
selection_candidate_info);
|
2018-05-17 14:36:48 -07:00
|
|
|
if (err) return (err);
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
2018-05-25 11:19:24 -07:00
|
|
|
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
|
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
|
|
|
|
|
if (selection_candidate_count == 0) {
|
|
|
|
|
if (restrict_to_drc_with_album_loudness == 1) {
|
|
|
|
|
restrict_to_drc_with_album_loudness = 0;
|
|
|
|
|
} else {
|
|
|
|
|
return (UNEXPECTED_ERROR);
|
|
|
|
|
}
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|
2018-06-01 13:27:00 +05:30
|
|
|
}
|
|
|
|
|
*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;
|
|
|
|
|
|
2019-05-08 15:21:19 +05:30
|
|
|
err = impd_select_loud_eq(
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
2019-05-08 15:21:19 +05:30
|
|
|
if (err) return (err);
|
2018-06-01 13:27:00 +05:30
|
|
|
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);
|
2018-05-17 14:36:48 -07:00
|
|
|
}
|