Loudness leveling support for encoder and decoder (#99)

* Loudness leveling support for encoder and decoder

- Addition of loudness leveling support to encoder and
  decoder as per ISO/IEC 23003-4:2020/Amd.2:2023(E)

Testing:

Encoder: Smoke-test

Decoder: CTS and Conformance for x86, x86_64, armv7 and armv8 are
         passing

* Addressed review comments

* Addressed minor nits in documentation

---------

Co-authored-by: Akshay Ragir <100833@ittiam.com>
This commit is contained in:
akshayragir833 2025-07-28 17:40:45 +05:30 committed by GitHub
parent 11fa437dda
commit 3dfa708b6e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
42 changed files with 634 additions and 127 deletions

View file

@ -28,6 +28,7 @@ cc_library_static {
host_supported: true,
cflags: [
"-O3",
"-DLOUDNESS_LEVELING_SUPPORT",
],
export_include_dirs: [
@ -354,6 +355,7 @@ cc_library_static {
host_supported: true,
cflags: [
"-O3",
"-DLOUDNESS_LEVELING_SUPPORT",
],
export_include_dirs: [

View file

@ -39,8 +39,8 @@ A single API is used to get and set configurations and execute the decode thread
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_PEAK_LIMITER | Sets the flag to disable/enable peak limiter |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_FRAMELENGTH_FLAG | Sets to flag to indicate whether decoder should decode for frame length 960 or 1024 |
|IA_API_CMD_SET_CONFIG_PARAM | IA_XHEAAC_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL | Sets the value of DRC target level |
|IA_API_CMD_SET_CONFIG_PARAM | IA_XHEAAC_DEC_CONFIG_ERROR_CONCEALMENT | Sets to flag to disable/enable error concealment |
|IA_API_CMD_SET_CONFIG_PARAM | IA_XHEAAC_DEC_CONFIG_PARAM_ESBR | Sets to flag to disable/enable eSBR |
|IA_API_CMD_SET_CONFIG_PARAM | IA_XHEAAC_DEC_CONFIG_ERROR_CONCEALMENT | Sets the flag to disable/enable error concealment |
|IA_API_CMD_SET_CONFIG_PARAM | IA_XHEAAC_DEC_CONFIG_PARAM_ESBR | Sets the flag to disable/enable eSBR |
|IA_API_CMD_GET_N_MEMTABS | 0 | Gets the number of memory types |
|IA_API_CMD_GET_N_TABLES | 0 | Gets the number of tables |
|IA_API_CMD_GET_MEM_INFO_SIZE | 0 | Gets the size of the memory type being referred to by the index |
@ -66,6 +66,7 @@ A single API is used to get and set configurations and execute the decode thread
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS | Gets the value of DRC target loudness |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM | Gets the value of DRC loudness normalization level |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_AOT | Gets the value of audio object type |
|IA_API_CMD_GET_CONFIG_PARAM | IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUDNESS_LEVELING | Gets the value of loudness leveling flag |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR | Gets the extension element pointer |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES | Gets the extension element buffer sizes |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE | Gets the number of configuration elements |
@ -132,7 +133,7 @@ A single API is used to get and set configurations and execute the decode thread
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS | Sets the number of channels in the input stream/data |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ | Sets the PCM word size of the input data |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT | Sets the bit stream format |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT | Sets the DRC decoders interface present flag to 1 or 0 |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT | Sets the DRC decoders interface present flag to 1 or 0 |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE | Sets the frame size |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE | Sets the value of DRC effect type |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS | Sets the value of DRC target loudness |
@ -191,6 +192,7 @@ Command line usage :
[-peak_limiter_off:<peak_limiter_off_flag>]
[-err_conceal:<error_concealment_flag>]
[-esbr:<esbr_flag>]
[-loudness_leveling:<loudness_leveling_flag>]
where,
<input_file> is the input AAC-LC/HE-AACv1/HE-AACv2/AAC-LD/AAC-ELD/AAC-ELDv2/USAC file name.
@ -222,8 +224,10 @@ where,
<peak_limiter_off_flag> is to enable/disable peak limiter. Default value is 0.
<error_concealment_flag> is to enable/disable error concealment. Default value is 0.
<esbr_flag> is to enable/disable eSBR. Default value is 1.
<loudness_leveling_flag> is to enable / disable loudness leveling. Default value is 1.
```
Note: `loudness_leveling_flag` is applicable only if `LOUDNESS_LEVELING_SUPPORT` macro is enabled.
Sample CLI:
```
<xaac_dec_exe> -ifile:in_file.aac -ofile:out_file.wav -pcmsz:16

View file

@ -50,6 +50,7 @@ function(libxaac_add_definitions)
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
add_definitions(-DX86_64 -D_X86_64_)
endif()
add_definitions(-DLOUDNESS_LEVELING_SUPPORT)
endfunction()
# Adds libraries needed for executables

View file

@ -246,7 +246,7 @@ IA_ERRORCODE ia_drc_dec_api(pVOID p_ia_drc_dec_obj, WORD32 i_cmd, WORD32 i_idx,
case IA_API_CMD_SET_CONFIG_PARAM: {
switch (i_idx) {
case IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ: {
if (*pus_value < 8000 || *pus_value > 96000) {
if (*pus_value == 0 || *pus_value > 96000) {
return IA_DRC_DEC_CONFIG_NON_FATAL_INVALID_SAMP_FREQ;
}
p_obj_drc->str_config.sampling_rate = *pus_value;
@ -328,6 +328,12 @@ IA_ERRORCODE ia_drc_dec_api(pVOID p_ia_drc_dec_obj, WORD32 i_cmd, WORD32 i_idx,
p_obj_drc->str_config.compress_set = 1;
break;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
case IA_DRC_DEC_CONFIG_DRC_LOUDNESS_LEVELING: {
p_obj_drc->str_config.loudness_leveling_flag = *pus_value;
break;
}
#endif
default: { return -1; }
}
break;

View file

@ -63,6 +63,9 @@ typedef struct ia_drc_config_struct {
WORD32 apply_crossfade;
WORD32 is_config_changed;
WORD32 ln_dbgain_prev;
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 loudness_leveling_flag;
#endif
} ia_drc_config_struct;
/* DRC bitsteam handler */

View file

@ -193,6 +193,9 @@ extern "C" {
#define UNIDRCCONFEXT_V1 0x2
#define UNIDRCLOUDEXT_EQ 0x1
#define UNIDRCINTERFACEEXT_EQ 0x1
#ifdef LOUDNESS_LEVELING_SUPPORT
#define UNIDRCCONFEXT_LEVELING (0x4)
#endif
#define LOUD_EQ_REQUEST_OFF 0x0
#define LOUD_EQ_REQUEST_LIGHT 0x1

View file

@ -46,4 +46,7 @@
#define IA_DRC_DEC_CONFIG_DRC_COMPRESS 0x0016
#define IA_DRC_DEC_CONFIG_PARAM_APPLY_CROSSFADE 0x0017
#define IA_DRC_DEC_CONFIG_PARAM_CONFIG_CHANGED 0x0018
#ifdef LOUDNESS_LEVELING_SUPPORT
#define IA_DRC_DEC_CONFIG_DRC_LOUDNESS_LEVELING 0x0019
#endif
#endif

View file

@ -28,6 +28,10 @@
#include "impd_drc_parser.h"
#include "impd_drc_filter_bank.h"
#include "impd_drc_rom.h"
#ifdef LOUDNESS_LEVELING_SUPPORT
#include "impd_drc_error_codes.h"
#include "ixheaacd_error_codes.h"
#endif
WORD32 impd_parse_loud_eq_instructions(
ia_bit_buf_struct* it_bit_buff,
ia_loud_eq_instructions_struct* loud_eq_instructions);
@ -646,6 +650,42 @@ WORD32 impd_parse_drc_ext_v1(ia_bit_buf_struct* it_bit_buff,
return 0;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
IA_ERROR_CODE impd_leveling_instructions(ia_bit_buf_struct* it_bit_buff,
ia_drc_config* pstr_drc_config) {
WORD32 i;
IA_ERROR_CODE err = IA_NO_ERROR;
WORD32 drc_instruction_uni_drc_count = pstr_drc_config->drc_instructions_uni_drc_count;
for (i = 0; i < drc_instruction_uni_drc_count; ++i) {
if ((pstr_drc_config->str_drc_instruction_str[i].drc_set_effect & (1 << 11)) != 0) {
pstr_drc_config->str_drc_instruction_str[i].leveling_present =
impd_read_bits_buf(it_bit_buff, 1);
if (pstr_drc_config->str_drc_instruction_str[i].leveling_present) {
WORD32 ducking_only_drc_set_present = impd_read_bits_buf(it_bit_buff, 1);
if (ducking_only_drc_set_present) {
pstr_drc_config->drc_instructions_uni_drc_count++;
if (pstr_drc_config->drc_instructions_uni_drc_count > DRC_INSTRUCTIONS_COUNT_MAX) {
return IA_XHEAAC_DEC_INIT_NONFATAL_MAX_INSTRUCTIONS_ERROR;
}
err = impd_parse_drc_instructions_uni_drc(
it_bit_buff, 1, pstr_drc_config,
&pstr_drc_config
->str_drc_instruction_str[pstr_drc_config->drc_instructions_uni_drc_count -
1]);
if (err) return err;
}
}
}
}
return err;
}
#endif
WORD32 impd_parse_filt_block(ia_bit_buf_struct* it_bit_buff,
ia_filt_block_struct* str_filter_block,
WORD32 block_count) {

View file

@ -58,10 +58,15 @@ impd_drc_dec_interface_process(ia_bit_buf_struct *it_bit_buff,
WORD32 *num_bits_read);
WORD32
impd_drc_dec_interface_add_effect_type(
ia_drc_interface_struct *pstr_drc_interface, WORD32 drc_effect_type,
WORD32 target_loudness, WORD32 loud_norm, WORD32 album_mode, FLOAT32 boost,
FLOAT32 compress);
impd_drc_dec_interface_add_effect_type(ia_drc_interface_struct *pstr_drc_interface,
WORD32 drc_effect_type, WORD32 target_loudness,
WORD32 loud_norm, WORD32 album_mode, FLOAT32 boost,
FLOAT32 compress
#ifdef LOUDNESS_LEVELING_SUPPORT
,
WORD32 loudness_leveling_flag
#endif
);
#define BITSTREAM_FILE_FORMAT_SPLIT 1
#define LIM_DEFAULT_THRESHOLD (0.89125094f)
@ -411,10 +416,15 @@ IA_ERRORCODE impd_drc_init(ia_drc_api_struct *p_obj_drc) {
p_obj_drc->str_config.compress = 1.0f;
err_code = impd_drc_dec_interface_add_effect_type(
p_obj_drc->str_payload.pstr_drc_interface,
p_obj_drc->str_config.effect_type, p_obj_drc->str_config.target_loudness,
p_obj_drc->str_config.loud_norm_flag, p_obj_drc->str_config.album_mode,
p_obj_drc->str_config.boost, p_obj_drc->str_config.compress);
p_obj_drc->str_payload.pstr_drc_interface, p_obj_drc->str_config.effect_type,
p_obj_drc->str_config.target_loudness, p_obj_drc->str_config.loud_norm_flag,
p_obj_drc->str_config.album_mode, p_obj_drc->str_config.boost,
p_obj_drc->str_config.compress
#ifdef LOUDNESS_LEVELING_SUPPORT
,
p_obj_drc->str_config.loudness_leveling_flag
#endif
);
if (err_code != IA_NO_ERROR) return err_code;

View file

@ -42,6 +42,11 @@ typedef struct {
typedef struct {
WORD32 interface_ext_count;
ia_specific_interface_extension_struct specific_interface_ext[EXT_COUNT_MAX];
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 loudness_leveling_on;
#endif
WORD32 loudness_eq_parameter_interface_flag;
WORD32 eq_ctrl_interface_flag;
ia_loudness_eq_parameter_interface_struct loudness_eq_parameter_interface;

View file

@ -29,10 +29,15 @@
#include "impd_drc_parser_interface.h"
WORD32
impd_drc_dec_interface_add_effect_type(
ia_drc_interface_struct* pstr_drc_interface, WORD32 drc_effect_type,
WORD32 target_loudness, WORD32 loud_norm, WORD32 album_mode, FLOAT32 boost,
FLOAT32 compress) {
impd_drc_dec_interface_add_effect_type(ia_drc_interface_struct* pstr_drc_interface,
WORD32 drc_effect_type, WORD32 target_loudness,
WORD32 loud_norm, WORD32 album_mode, FLOAT32 boost,
FLOAT32 compress
#ifdef LOUDNESS_LEVELING_SUPPORT
,
WORD32 loudness_leveling_flag
#endif
) {
WORD32 err = 0;
WORD32 i = 0;
@ -65,7 +70,9 @@ impd_drc_dec_interface_add_effect_type(
}
pstr_drc_interface->loudness_norm_ctrl_interface.target_loudness =
(FLOAT32)target_loudness;
#ifdef LOUDNESS_LEVELING_SUPPORT
pstr_drc_interface->drc_uni_interface_ext.loudness_leveling_on = loudness_leveling_flag;
#endif
pstr_drc_interface->loudness_norm_parameter_interface_flag = 1;
pstr_drc_interface->loudness_norm_param_interface.album_mode = album_mode;
pstr_drc_interface->loudness_norm_param_interface.peak_limiter = 0;

View file

@ -73,6 +73,10 @@ impd_parse_drc_ext_v1(ia_bit_buf_struct* it_bit_buff,
ia_drc_config* drc_config,
ia_drc_config_ext* str_drc_config_ext);
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 impd_leveling_instructions(ia_bit_buf_struct* it_bit_buff, ia_drc_config* pstr_drc_config);
#endif
WORD32
impd_parse_drc_config(ia_bit_buf_struct* it_bit_buff,
ia_drc_params_bs_dec_struct* ia_drc_params_struct,

View file

@ -82,6 +82,10 @@ typedef struct ia_drc_sel_proc_params_struct {
FLOAT32 playback_gain;
WORD32 eq_set_purpose_request;
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 loudness_leveling_on;
#endif
FLOAT32 boost;
FLOAT32 compress;
WORD32 drc_characteristic_target;

View file

@ -30,6 +30,9 @@
#include "impd_drc_loudness_control.h"
#include "impd_drc_filter_bank.h"
#include "impd_drc_rom.h"
#ifdef LOUDNESS_LEVELING_SUPPORT
#include "ixheaac_error_standards.h"
#endif
static const WORD32 effect_types_request_table[] = {
EFFECT_BIT_NIGHT, EFFECT_BIT_NOISY, EFFECT_BIT_LIMITED,
@ -170,6 +173,12 @@ WORD32 impd_get_ducking_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
(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) {
#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
drc_instructions_index = n;
}
}
@ -186,6 +195,12 @@ WORD32 impd_get_ducking_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
(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) {
#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
drc_instructions_index = n;
}
}

View file

@ -104,6 +104,10 @@ WORD32 impd_drc_sel_proc_init_dflt(
pstr_drc_uni_sel_proc->eq_inst_index[0] = -1;
pstr_drc_uni_sel_proc->eq_inst_index[1] = -1;
pstr_drc_uni_sel_proc->sel_proc_request_flag = 1;
#ifdef LOUDNESS_LEVELING_SUPPORT
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.loudness_leveling_on = 1;
#endif
} else {
return 1;
}
@ -133,6 +137,10 @@ VOID impd_drc_sel_proc_init_interface_params(
WORD32 i, j;
if (pstr_drc_uni_sel_proc != NULL && pstr_drc_interface != NULL) {
#ifdef LOUDNESS_LEVELING_SUPPORT
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.loudness_leveling_on =
pstr_drc_interface->drc_uni_interface_ext.loudness_leveling_on;
#endif
if (pstr_drc_interface->system_interface_flag) {
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
.target_config_request_type !=

View file

@ -954,6 +954,13 @@ impd_parse_drc_config_ext(ia_bit_buf_struct* it_bit_buff,
drc_config, str_drc_config_ext);
if (err) return (err);
break;
#ifdef LOUDNESS_LEVELING_SUPPORT
case UNIDRCCONFEXT_LEVELING:
err = impd_leveling_instructions(it_bit_buff, drc_config);
if (err) return err;
break;
#endif
default:
for (i = 0; i < str_drc_config_ext->ext_bit_size[k]; i++) {
impd_read_bits_buf(it_bit_buff, 1);

View file

@ -424,6 +424,9 @@ typedef struct {
WORD32 gain_set_idx_of_ch_group_parametric_drc[CHANNEL_GROUP_COUNT_MAX];
WORD32 parametric_drc_look_ahead_samples[CHANNEL_GROUP_COUNT_MAX];
WORD32 parametric_drc_look_ahead_samples_max;
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 leveling_present;
#endif
} ia_drc_instructions_struct;
typedef struct {

View file

@ -65,6 +65,10 @@
#define IA_XHEAAC_DEC_CONFIG_PARAM_ESBR 0x0028
#ifdef LOUDNESS_LEVELING_SUPPORT
#define IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUDNESS_LEVELING 0x0029
#endif
#define IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ IA_XHEAAC_DEC_CONFIG_PARAM_PCM_WDSZ
#define IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ IA_XHEAAC_DEC_CONFIG_PARAM_SAMP_FREQ
#define IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS IA_XHEAAC_DEC_CONFIG_PARAM_NUM_CHANNELS

View file

@ -480,7 +480,9 @@ IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_xheaac_dec_obj, WORD32 i_cmd,
p_obj_exhaacplus_dec->aac_config.ui_drc_set = 0;
p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 0;
p_obj_exhaacplus_dec->aac_config.output_level = -1;
#ifdef LOUDNESS_LEVELING_SUPPORT
p_obj_exhaacplus_dec->aac_config.ui_loudness_leveling_flag = 1;
#endif
p_obj_exhaacplus_dec->aac_config.ui_max_channels = 6;
p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 0;
@ -789,6 +791,16 @@ IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_xheaac_dec_obj, WORD32 i_cmd,
p_obj_exhaacplus_dec->aac_config.ui_enh_sbr = *pui_value_signed;
break;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUDNESS_LEVELING: {
if (((*pui_value_signed) != 0) && ((*pui_value_signed) != 1)) {
p_obj_exhaacplus_dec->aac_config.ui_loudness_leveling_flag = 1;
return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_LOUDNESS_LEVELING_FLAG);
}
p_obj_exhaacplus_dec->aac_config.ui_loudness_leveling_flag = *pui_value_signed;
break;
}
#endif
default: { return IA_XHEAAC_DEC_API_FATAL_INVALID_CONFIG_PARAM; }
}
break;
@ -931,7 +943,15 @@ IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_xheaac_dec_obj, WORD32 i_cmd,
} else {
*pui_value = AOT_AAC_LC;
}
} else {
}
#ifdef LOUDNESS_LEVELING_SUPPORT
else if (IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUDNESS_LEVELING == i_idx) {
WORD32 *ui_value =
(WORD32 *)(&p_obj_exhaacplus_dec->aac_config.ui_loudness_leveling_flag);
*pui_value = *ui_value;
}
#endif
else {
return IA_XHEAAC_DEC_API_FATAL_INVALID_CONFIG_PARAM;
}
break;

View file

@ -63,6 +63,9 @@
#define IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_ESBR_HQ_FLAG 0x00000815
#define IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_FRAMELENGTHFLAG 0x00000816
#define IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_ESBR_FLAG 0x00000817
#ifdef LOUDNESS_LEVELING_SUPPORT
#define IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_LOUDNESS_LEVELING_FLAG 0x00000818
#endif
/* Fatal Errors */
#define IA_XHEAAC_DEC_CONFIG_FATAL_INVALID_SAMPLE_RATE 0xFFFF8800
@ -75,7 +78,7 @@
#define IA_XHEAAC_DEC_INIT_NONFATAL_EC_INIT_FAIL 0x00001002
#define IA_XHEAAC_DEC_INIT_NONFATAL_INSUFFICIENT_INPUT_BYTES 0x00001003
#define IA_XHEAAC_DEC_INIT_NONFATAL_DECODE_FRAME_ERROR 0x00001004
#define IA_XHEAAC_DEC_INIT_NONFATAL_MAX_INSTRUCTIONS_ERROR 0x00001005
/* Fatal Errors */
#define IA_XHEAAC_DEC_INIT_FATAL_DEC_INIT_FAIL 0xFFFF9000
#define IA_XHEAAC_DEC_INIT_FATAL_EO_INPUT_REACHED 0xFFFF9001

View file

@ -137,6 +137,9 @@ typedef struct {
WORD32 ui_err_conceal;
FLAG first_frame;
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 ui_loudness_leveling_flag;
#endif
} ia_aac_dec_config_struct;
typedef struct ia_aac_dec_state_struct {

View file

@ -88,6 +88,15 @@ IA_ERRORCODE impd_drc_validate_config_params(ia_drc_input_config *pstr_inp_confi
}
IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i].limiter_peak_target,
MIN_LIMITER_PEAK_TARGET, 0.0f);
#ifdef LOUDNESS_LEVELING_SUPPORT
if (pstr_uni_drc_config->str_drc_instructions_uni_drc[i].drc_set_effect &
EFFECT_BIT_DUCK_SELF) {
IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i].leveling_present,
0, 1);
IMPD_DRC_BOUND_CHECK(
pstr_uni_drc_config->str_drc_instructions_uni_drc[i].ducking_only_set_present, 0, 1);
}
#endif
}
IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->drc_coefficients_uni_drc_count, 0,
@ -395,6 +404,16 @@ IA_ERRORCODE impd_drc_validate_config_params(ia_drc_input_config *pstr_inp_confi
IMPD_DRC_BOUND_CHECK(
pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].limiter_peak_target,
MIN_LIMITER_PEAK_TARGET, 0.0f);
#ifdef LOUDNESS_LEVELING_SUPPORT
if (pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].drc_set_effect &
EFFECT_BIT_DUCK_SELF) {
IMPD_DRC_BOUND_CHECK(
pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].leveling_present, 0, 1);
IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
.ducking_only_set_present,
0, 1);
}
#endif
}
}
}
@ -423,8 +442,67 @@ static IA_ERRORCODE impd_drc_validate_drc_instructions(
if (profile_found == FALSE) {
return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
if (pstr_uni_drc_config->str_drc_instructions_uni_drc[i].drc_set_effect &
EFFECT_BIT_DUCK_SELF) {
if (pstr_uni_drc_config->str_drc_instructions_uni_drc[i].leveling_present &&
pstr_uni_drc_config->str_drc_instructions_uni_drc[i].ducking_only_set_present) {
if (i < pstr_uni_drc_config->drc_instructions_uni_drc_count - 1) {
if (pstr_uni_drc_config->str_drc_instructions_uni_drc[i + 1].drc_set_effect !=
EFFECT_BIT_DUCK_SELF &&
pstr_uni_drc_config->str_drc_instructions_uni_drc[i + 1].drc_set_effect !=
EFFECT_BIT_DUCK_OTHER) {
pstr_uni_drc_config->str_drc_instructions_uni_drc[i + 1].drc_set_effect =
EFFECT_BIT_DUCK_SELF;
}
pstr_uni_drc_config->str_drc_instructions_uni_drc[i + 1].leveling_present = 0;
pstr_uni_drc_config->str_drc_instructions_uni_drc[i + 1].ducking_only_set_present = 0;
} else {
pstr_uni_drc_config->str_drc_instructions_uni_drc[i].ducking_only_set_present = 0;
}
} else if (!pstr_uni_drc_config->str_drc_instructions_uni_drc[i].leveling_present &&
pstr_uni_drc_config->str_drc_instructions_uni_drc[i].ducking_only_set_present) {
pstr_uni_drc_config->str_drc_instructions_uni_drc[i].ducking_only_set_present = 0;
}
}
#endif
}
#ifdef LOUDNESS_LEVELING_SUPPORT
if (pstr_uni_drc_config->uni_drc_config_ext_present) {
ia_drc_uni_drc_config_ext_struct *pstr_uni_drc_config_ext =
&pstr_uni_drc_config->str_uni_drc_config_ext;
for (i = 0; i < pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count; i++) {
if (pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].drc_set_effect &
EFFECT_BIT_DUCK_SELF) {
if (pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].leveling_present &&
pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
.ducking_only_set_present) {
if (i < pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count - 1) {
if (pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i + 1].drc_set_effect !=
EFFECT_BIT_DUCK_SELF &&
pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i + 1].drc_set_effect !=
EFFECT_BIT_DUCK_OTHER) {
pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i + 1].drc_set_effect =
EFFECT_BIT_DUCK_SELF;
}
pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i + 1].leveling_present = 0;
pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i + 1]
.ducking_only_set_present = 0;
} else {
pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].ducking_only_set_present =
0;
}
} else if (!pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
.leveling_present &&
pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
.ducking_only_set_present) {
pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].ducking_only_set_present =
0;
}
}
}
}
#endif
return IA_NO_ERROR;
}
@ -461,6 +539,18 @@ IA_ERRORCODE impd_drc_enc_init(VOID *pstr_drc_state, VOID *ptr_drc_scratch,
if (err_code) {
return err_code;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
err_code = impd_drc_validate_drc_instructions(&pstr_inp_config->str_uni_drc_config);
if (err_code & IA_FATAL_ERROR) {
return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
}
pstr_drc_state_local->str_enc_params = pstr_inp_config->str_enc_params;
pstr_drc_state_local->str_uni_drc_config = pstr_inp_config->str_uni_drc_config;
pstr_drc_state_local->str_enc_gain_extension = pstr_inp_config->str_enc_gain_extension;
pstr_drc_state_local->str_gain_enc.str_uni_drc_config = pstr_inp_config->str_uni_drc_config;
#else
pstr_drc_state_local->str_enc_params = pstr_inp_config->str_enc_params;
pstr_drc_state_local->str_uni_drc_config = pstr_inp_config->str_uni_drc_config;
pstr_drc_state_local->str_enc_gain_extension = pstr_inp_config->str_enc_gain_extension;
@ -469,6 +559,7 @@ IA_ERRORCODE impd_drc_enc_init(VOID *pstr_drc_state, VOID *ptr_drc_scratch,
if (err_code & IA_FATAL_ERROR) {
return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
}
#endif
err_code = impd_drc_write_uni_drc_config(pstr_drc_state_local, &bit_count, 1);
if (err_code & IA_FATAL_ERROR) {

View file

@ -36,7 +36,11 @@
#define MAX_CHANNEL_GROUP_COUNT (MAX_SEQUENCE_COUNT)
#define MAX_ADDITIONAL_DOWNMIX_ID (7)
#define DELAY_MODE_REGULAR_DELAY (0)
#ifdef LOUDNESS_LEVELING_SUPPORT
#define MAX_EXT_COUNT (3)
#else
#define MAX_EXT_COUNT (2)
#endif
#define MAX_GAIN_POINTS (256)
#define MAX_DRC_INSTRUCTIONS_BASIC_COUNT (15)
@ -46,6 +50,9 @@
#define UNIDRC_CONF_EXT_PARAM_DRC (0x1)
#define UNIDRC_CONF_EXT_V1 (0x2)
#define UNIDRC_LOUD_EXT_EQ (0x1)
#ifdef LOUDNESS_LEVELING_SUPPORT
#define UNIDRCCONFEXT_LEVELING (0x4)
#endif
#define MAX_PARAM_DRC_INSTRUCTIONS_COUNT (8)

View file

@ -1099,6 +1099,97 @@ static IA_ERRORCODE impd_drc_write_drc_instruct_uni_drc(
return err_code;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
static UWORD32 get_num_ducking_only_drc_sets(
ia_drc_instructions_uni_drc const *pstr_drc_instructions_uni_drc,
UWORD32 drc_intructions_uni_drc_count) {
UWORD32 num_ducking_only_drc_sets = 0;
for (UWORD16 i = 0; i < drc_intructions_uni_drc_count; i++) {
if (pstr_drc_instructions_uni_drc[i].ducking_only_set_present) {
num_ducking_only_drc_sets++;
}
}
return num_ducking_only_drc_sets;
}
static WORD32 write_loudness_leveling_extension(ia_bit_buf_struct *it_bit_buf,
ia_drc_uni_drc_config_struct *pstr_uni_drc_config,
ia_drc_gain_enc_struct *pstr_gain_enc,
VOID *ptr_scratch, WORD32 *bit_cnt) {
IA_ERRORCODE err_code = IA_NO_ERROR;
WORD32 bit_cnt_local = 0;
WORD32 drc_instructions_uni_drc_count_v1 =
pstr_uni_drc_config->str_uni_drc_config_ext.drc_instructions_uni_drc_v1_count;
WORD32 drc_instructions_uni_drc_count = pstr_uni_drc_config->drc_instructions_uni_drc_count;
WORD32 version = 0;
WORD16 ducking_set_expected = 0;
// V0 instructions
for (WORD16 i = 0; i < drc_instructions_uni_drc_count; i++) {
ia_drc_instructions_uni_drc *pstr_drc_instruction =
&pstr_uni_drc_config->str_drc_instructions_uni_drc[i];
if (pstr_drc_instruction->drc_set_effect & EFFECT_BIT_DUCK_SELF) {
if (ducking_set_expected) {
ia_drc_instructions_uni_drc *pstr_drc_instruction_prev =
&pstr_uni_drc_config->str_drc_instructions_uni_drc[i - 1];
if (pstr_drc_instruction_prev->ducking_only_set_present) {
err_code = impd_drc_write_drc_instruct_uni_drc(it_bit_buf, version, pstr_uni_drc_config,
pstr_gain_enc, pstr_drc_instruction,
ptr_scratch, &bit_cnt_local);
if (err_code & IA_FATAL_ERROR) {
return (err_code);
}
}
ducking_set_expected = 0;
} else {
bit_cnt_local +=
iusace_write_bits_buf(it_bit_buf, pstr_drc_instruction->leveling_present, 1);
if (pstr_drc_instruction->leveling_present) {
ducking_set_expected = 1;
bit_cnt_local += iusace_write_bits_buf(
it_bit_buf, pstr_drc_instruction->ducking_only_set_present, 1);
continue;
}
}
}
}
// V1 instructions
version = 1;
ducking_set_expected = 0;
for (WORD16 i = 0; i < drc_instructions_uni_drc_count_v1; i++) {
ia_drc_instructions_uni_drc *pstr_drc_instruction =
&pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_instructions_uni_drc_v1[i];
if (pstr_drc_instruction->drc_set_effect & EFFECT_BIT_DUCK_SELF) {
if (ducking_set_expected) {
ia_drc_instructions_uni_drc *pstr_drc_instruction_prev =
&pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_instructions_uni_drc_v1[i - 1];
if (pstr_drc_instruction_prev->ducking_only_set_present) {
err_code = impd_drc_write_drc_instruct_uni_drc(it_bit_buf, version, pstr_uni_drc_config,
pstr_gain_enc, pstr_drc_instruction,
ptr_scratch, &bit_cnt_local);
if (err_code & IA_FATAL_ERROR) {
return (err_code);
}
}
ducking_set_expected = 0;
} else {
bit_cnt_local +=
iusace_write_bits_buf(it_bit_buf, pstr_drc_instruction->leveling_present, 1);
if (pstr_drc_instruction->leveling_present) {
ducking_set_expected = 1;
bit_cnt_local += iusace_write_bits_buf(
it_bit_buf, pstr_drc_instruction->ducking_only_set_present, 1);
continue;
}
}
}
}
*bit_cnt += bit_cnt_local;
return IA_NO_ERROR;
}
#endif
static VOID impd_drc_write_gain_params(ia_bit_buf_struct *it_bit_buf, const WORD32 version,
const WORD32 band_count, const WORD32 drc_band_type,
ia_drc_gain_params_struct *pstr_gain_params,
@ -2536,6 +2627,9 @@ static IA_ERRORCODE impd_drc_write_uni_drc_config_extn(
pstr_uni_drc_config_ext->uni_drc_config_ext_type[counter] != UNIDRC_CONF_EXT_TERM) {
switch (pstr_uni_drc_config_ext->uni_drc_config_ext_type[counter]) {
case UNIDRC_CONF_EXT_PARAM_DRC: {
#ifdef LOUDNESS_LEVELING_SUPPORT
bit_cnt_local_ext = 0;
#endif // LOUDNESS_LEVELING_SUPPORT
err_code = impd_drc_write_drc_coeff_parametric_drc(
ptr_bit_buf_ext, pstr_uni_drc_config,
&(pstr_uni_drc_config_ext->str_drc_coeff_parametric_drc), &bit_cnt_local_ext);
@ -2559,6 +2653,9 @@ static IA_ERRORCODE impd_drc_write_uni_drc_config_extn(
} break;
case UNIDRC_CONF_EXT_V1: {
version = 1;
#ifdef LOUDNESS_LEVELING_SUPPORT
bit_cnt_local_ext = 0;
#endif // LOUDNESS_LEVELING_SUPPORT
bit_cnt_local_ext += iusace_write_bits_buf(
ptr_bit_buf_ext, pstr_uni_drc_config_ext->downmix_instructions_v1_present, 1);
if (pstr_uni_drc_config_ext->downmix_instructions_v1_present == 1) {
@ -2583,10 +2680,27 @@ static IA_ERRORCODE impd_drc_write_uni_drc_config_extn(
&(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[idx]),
&bit_cnt_local_ext);
}
#ifdef LOUDNESS_LEVELING_SUPPORT
UWORD32 num_ducking_only_drc_sets = get_num_ducking_only_drc_sets(
pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1,
pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count);
bit_cnt_local_ext +=
iusace_write_bits_buf(ptr_bit_buf_ext,
pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count -
num_ducking_only_drc_sets,
6);
#else
bit_cnt_local_ext += iusace_write_bits_buf(
ptr_bit_buf_ext, pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count, 6);
#endif
for (idx = 0; idx < pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count; idx++) {
#ifdef LOUDNESS_LEVELING_SUPPORT
if (idx > 0 && pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[idx - 1]
.ducking_only_set_present) {
continue;
}
#endif
err_code = impd_drc_write_drc_instruct_uni_drc(
ptr_bit_buf_ext, version, pstr_uni_drc_config, pstr_gain_enc,
&(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[idx]), ptr_scratch,
@ -2632,6 +2746,17 @@ static IA_ERRORCODE impd_drc_write_uni_drc_config_extn(
}
}
} break;
#ifdef LOUDNESS_LEVELING_SUPPORT
case UNIDRCCONFEXT_LEVELING: {
bit_cnt_local_ext = 0;
err_code = write_loudness_leveling_extension(
ptr_bit_buf_ext, pstr_uni_drc_config, pstr_gain_enc, ptr_scratch, &bit_cnt_local_ext);
if (err_code & IA_FATAL_ERROR) {
return (err_code);
}
} break;
#endif
default:
break;
}
@ -2639,6 +2764,9 @@ static IA_ERRORCODE impd_drc_write_uni_drc_config_extn(
pstr_uni_drc_config_ext->ext_bit_size[counter] = bit_cnt_local_ext;
bit_size = pstr_uni_drc_config_ext->ext_bit_size[counter] - 1;
ext_size_bits = (WORD32)(log((FLOAT32)bit_size) / log(2.f)) + 1;
#ifdef LOUDNESS_LEVELING_SUPPORT
ext_size_bits = (ext_size_bits < 4) ? 4 : ext_size_bits;
#endif // LOUDNESS_LEVELING_SUPPORT
bit_size_len = ext_size_bits - 4;
bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size_len, 4);
@ -2693,10 +2821,26 @@ static IA_ERRORCODE impd_drc_write_uni_drc_config_extn(
it_bit_buf, version,
&(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[idx]), &bit_cnt_local);
}
#ifdef LOUDNESS_LEVELING_SUPPORT
UWORD32 num_ducking_only_drc_sets = get_num_ducking_only_drc_sets(
pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1,
pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count);
bit_cnt_local +=
iusace_write_bits_buf(it_bit_buf,
pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count -
num_ducking_only_drc_sets,
6);
#else
bit_cnt_local += iusace_write_bits_buf(
it_bit_buf, pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count, 6);
#endif
for (idx = 0; idx < pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count; idx++) {
#ifdef LOUDNESS_LEVELING_SUPPORT
if (idx > 0 && pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[idx - 1]
.ducking_only_set_present) {
continue;
}
#endif
err_code = impd_drc_write_drc_instruct_uni_drc(
it_bit_buf, version, pstr_uni_drc_config, pstr_gain_enc,
&(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[idx]), ptr_scratch,
@ -2741,6 +2885,15 @@ static IA_ERRORCODE impd_drc_write_uni_drc_config_extn(
}
}
} break;
#ifdef LOUDNESS_LEVELING_SUPPORT
case UNIDRCCONFEXT_LEVELING: {
err_code = write_loudness_leveling_extension(it_bit_buf, pstr_uni_drc_config,
pstr_gain_enc, ptr_scratch, &bit_cnt_local);
if (err_code & IA_FATAL_ERROR) {
return (err_code);
}
} break;
#endif
default:
for (idx = 0; idx < pstr_uni_drc_config_ext->ext_bit_size[counter]; idx++) {
bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 0, 1);
@ -3019,7 +3172,7 @@ IA_ERRORCODE impd_drc_write_measured_loudness_info(ia_drc_enc_state *pstr_drc_st
return (err_code);
}
pstr_drc_state->drc_config_ext_data_size_bit = bit_cnt_lis;
return err_code;
}

View file

@ -388,6 +388,10 @@ typedef struct {
WORD32 multiband_audio_signal_count;
WORD32 channel_group_is_parametric_drc[MAX_CHANNEL_GROUP_COUNT];
WORD32 gain_set_idx_for_ch_group_parametric_drc[MAX_CHANNEL_GROUP_COUNT];
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 leveling_present;
WORD32 ducking_only_set_present;
#endif
} ia_drc_instructions_uni_drc;
typedef struct {

View file

@ -2155,7 +2155,7 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co
} else if (pstr_sbr_extract_env->time_step == 4) {
ixheaace_detect_transient_4_1(pstr_sbr_extract_env->ptr_y_buffer,
&pstr_env_ch[ch]->str_sbr_trans_detector, transient_info[ch],
pstr_sbr_extract_env->time_step, pstr_sbr_cfg->sbr_codec);
pstr_sbr_extract_env->time_step);
} else {
ixheaace_detect_transient(pstr_sbr_extract_env->ptr_y_buffer,
&pstr_env_ch[ch]->str_sbr_trans_detector, transient_info[ch],

View file

@ -47,8 +47,7 @@ ixheaace_create_extract_sbr_envelope(WORD32 ch,
ixheaace_pstr_sbr_extract_envelope pstr_sbr_ext_env,
WORD32 start_index, WORD32 *ptr_common_buffer2,
FLOAT32 *ptr_sbr_env_r_buf, FLOAT32 *ptr_sbr_env_i_buf,
WORD32 is_ld_sbr, WORD32 frame_flag_480,
ixheaace_sbr_codec_type sbr_codec);
WORD32 frame_flag_480, ixheaace_sbr_codec_type sbr_codec);
struct ixheaace_str_sbr_config_data;
struct ixheaace_str_sbr_bitstream_data;

View file

@ -62,8 +62,7 @@ ixheaace_create_extract_sbr_envelope(WORD32 ch,
ixheaace_pstr_sbr_extract_envelope pstr_sbr_ext_env,
WORD32 start_index, WORD32 *ptr_common_buffer2,
FLOAT32 *ptr_sbr_env_r_buf, FLOAT32 *ptr_sbr_env_i_buf,
WORD32 is_ld_sbr, WORD32 frame_flag_480,
ixheaace_sbr_codec_type sbr_codec) {
WORD32 frame_flag_480, ixheaace_sbr_codec_type sbr_codec) {
WORD32 i;
WORD32 y_buffer_length, r_buffer_length;
WORD32 offset = 0;

View file

@ -262,7 +262,7 @@ static IA_ERRORCODE ixheaace_create_env_channel(
}
err_code = ixheaace_create_extract_sbr_envelope(
ch, &pstr_env->str_sbr_extract_env, start_index, ptr_common_buffer2, ptr_sbr_env_r_buf,
ptr_sbr_env_i_buf, params->is_ld_sbr, params->frame_flag_480, params->sbr_codec);
ptr_sbr_env_i_buf, params->frame_flag_480, params->sbr_codec);
if (err_code) {
return err_code;
}

View file

@ -61,8 +61,7 @@ VOID ixheaace_detect_transient(FLOAT32 **ptr_energies,
VOID ixheaace_detect_transient_4_1(FLOAT32 **ptr_energies,
ixheaace_pstr_sbr_trans_detector pstr_sbr_trans_det,
WORD32 *ptr_tran_vector, WORD32 time_step,
ixheaace_sbr_codec_type sbr_codec);
WORD32 *ptr_tran_vector, WORD32 time_step);
VOID ixheaace_detect_transient_eld(FLOAT32 **ptr_energies,
ixheaace_pstr_sbr_trans_detector pstr_sbr_trans_det,

View file

@ -162,8 +162,7 @@ VOID ixheaace_detect_transient(FLOAT32 **ptr_energies,
}
static VOID ixheaace_calc_thresholds_4_1(FLOAT32 **ptr_energies, WORD32 num_cols, WORD32 num_rows,
FLOAT32 *ptr_thresholds,
ixheaace_sbr_codec_type sbr_codec, WORD32 time_step) {
FLOAT32 *ptr_thresholds, WORD32 time_step) {
FLOAT32 mean_val, std_val, thr;
FLOAT32 *ptr_energy;
FLOAT32 inv_num_cols = 1.0f / (FLOAT32)((num_cols + num_cols / 2) / time_step);
@ -207,7 +206,7 @@ static VOID ixheaace_extract_transient_candidates_4_1(FLOAT32 **ptr_energies,
FLOAT32 *ptr_thresholds,
FLOAT32 *ptr_transients, WORD32 num_cols,
WORD32 start_band, WORD32 stop_band,
WORD32 buf_len, WORD32 time_step)
WORD32 time_step)
{
WORD32 idx;
@ -233,8 +232,7 @@ static VOID ixheaace_extract_transient_candidates_4_1(FLOAT32 **ptr_energies,
VOID ixheaace_detect_transient_4_1(FLOAT32 **ptr_energies,
ixheaace_pstr_sbr_trans_detector pstr_sbr_trans_det,
WORD32 *ptr_tran_vector, WORD32 time_step,
ixheaace_sbr_codec_type sbr_codec) {
WORD32 *ptr_tran_vector, WORD32 time_step) {
WORD32 i;
WORD32 no_cols = pstr_sbr_trans_det->no_cols;
WORD32 qmf_start_sample = time_step * 4;
@ -246,12 +244,11 @@ VOID ixheaace_detect_transient_4_1(FLOAT32 **ptr_energies,
ixheaace_calc_thresholds_4_1(ptr_energies, pstr_sbr_trans_det->no_cols,
pstr_sbr_trans_det->no_rows, pstr_sbr_trans_det->ptr_thresholds,
sbr_codec, time_step);
time_step);
ixheaace_extract_transient_candidates_4_1(
ptr_energies, pstr_sbr_trans_det->ptr_thresholds, pstr_sbr_trans_det->ptr_transients,
pstr_sbr_trans_det->no_cols, 0, pstr_sbr_trans_det->no_rows,
pstr_sbr_trans_det->buffer_length, time_step);
pstr_sbr_trans_det->no_cols, 0, pstr_sbr_trans_det->no_rows, time_step);
for (i = 0; i < no_cols; i++) {
if ((ptr_trans[i] < 0.9f * ptr_trans[i - 1]) && (ptr_trans[i - 1] > int_thr)) {

View file

@ -240,6 +240,10 @@ enum {
DRC_BOOST_OFFSET,
DRC_COMPRESS_OFFSET,
DRC_EFFECT_OFFSET
#ifdef LOUDNESS_LEVELING_SUPPORT
,
DRC_LOUDNESS_LEVELING_OFFSET
#endif
};
IA_ERRORCODE Codec::initXAACDrc(const uint8_t* data, size_t size) {
@ -295,6 +299,15 @@ IA_ERRORCODE Codec::initXAACDrc(const uint8_t* data, size_t size) {
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &ui_drc_val);
#ifdef LOUDNESS_LEVELING_SUPPORT
// DRC_LOUDNESS_LEVELING_FLAG
size_t flagOffset = std::min((size_t)DRC_LOUDNESS_LEVELING_OFFSET, size - 1);
uint8_t loudnessFlag = data[flagOffset];
ui_drc_val = (unsigned int)loudnessFlag;
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUDNESS_LEVELING, &ui_drc_val);
#endif
return IA_NO_ERROR;
}

View file

@ -56,7 +56,10 @@ static VOID ixheaace_read_drc_config_params(
WORD32 in_ch) {
WORD32 n, g, s, m, ch, p;
WORD32 gain_set_channels;
#ifdef LOUDNESS_LEVELING_SUPPORT
UWORD32 loudness_leveling_extension_present = 0;
UWORD32 config_extension_count = 0;
#endif
pstr_enc_params->gain_sequence_present = fuzzed_data->ConsumeBool();
pstr_enc_params->delay_mode = fuzzed_data->ConsumeBool();
pstr_uni_drc_config->sample_rate_present = fuzzed_data->ConsumeBool();
@ -121,6 +124,13 @@ static VOID ixheaace_read_drc_config_params(
pstr_drc_instructions_uni_drc->drc_instructions_type = fuzzed_data->ConsumeIntegral<WORD8>();
pstr_drc_instructions_uni_drc->mae_group_id = fuzzed_data->ConsumeIntegral<WORD8>();
pstr_drc_instructions_uni_drc->mae_group_preset_id = fuzzed_data->ConsumeIntegral<WORD8>();
#ifdef LOUDNESS_LEVELING_SUPPORT
if (pstr_drc_instructions_uni_drc->drc_set_effect & EFFECT_BIT_DUCK_SELF) {
pstr_drc_instructions_uni_drc->leveling_present = fuzzed_data->ConsumeBool();
pstr_drc_instructions_uni_drc->ducking_only_set_present = fuzzed_data->ConsumeBool();
loudness_leveling_extension_present = 1;
}
#endif
}
pstr_uni_drc_config->drc_coefficients_uni_drc_count =
@ -305,7 +315,13 @@ static VOID ixheaace_read_drc_config_params(
pstr_enc_gain_extension->uni_drc_gain_ext_present = fuzzed_data->ConsumeBool();
if (pstr_uni_drc_config->uni_drc_config_ext_present) {
#ifdef LOUDNESS_LEVELING_SUPPORT
pstr_uni_drc_config->str_uni_drc_config_ext.uni_drc_config_ext_type[config_extension_count] =
UNIDRC_CONF_EXT_V1;
config_extension_count++;
#else
pstr_uni_drc_config->str_uni_drc_config_ext.uni_drc_config_ext_type[0] = UNIDRC_CONF_EXT_V1;
#endif
pstr_uni_drc_config->str_uni_drc_config_ext.downmix_instructions_v1_present =
fuzzed_data->ConsumeBool();
if (pstr_uni_drc_config->str_uni_drc_config_ext.downmix_instructions_v1_present) {
@ -496,8 +512,23 @@ static VOID ixheaace_read_drc_config_params(
pstr_drc_instructions_uni_drc->mae_group_id = fuzzed_data->ConsumeIntegral<WORD8>();
pstr_drc_instructions_uni_drc->mae_group_preset_id =
fuzzed_data->ConsumeIntegral<WORD8>();
#ifdef LOUDNESS_LEVELING_SUPPORT
if (pstr_drc_instructions_uni_drc->drc_set_effect & EFFECT_BIT_DUCK_SELF) {
pstr_drc_instructions_uni_drc->leveling_present = fuzzed_data->ConsumeBool();
pstr_drc_instructions_uni_drc->ducking_only_set_present = fuzzed_data->ConsumeBool();
loudness_leveling_extension_present = 1;
}
#endif
}
}
#ifdef LOUDNESS_LEVELING_SUPPORT
if (loudness_leveling_extension_present) {
pstr_uni_drc_config->str_uni_drc_config_ext
.uni_drc_config_ext_type[config_extension_count] = UNIDRCCONFEXT_LEVELING;
config_extension_count++;
}
#endif
}
}

View file

@ -21,7 +21,8 @@ cc_test {
"-DECLIPSE",
"-DDRC_ENABLE",
"-DMULTICHANNEL_ENABLE",
"-DENABLE_DRC"
"-DENABLE_DRC",
"-DLOUDNESS_LEVELING_SUPPORT",
],
include_dirs: [
@ -50,6 +51,7 @@ cc_test {
cflags: [
"-O3",
"-D_X86_",
"-DLOUDNESS_LEVELING_SUPPORT",
],
include_dirs: [

View file

@ -44,7 +44,9 @@
#define IA_DRC_DEC_CONFIG_PARAM_APPLY_CROSSFADE 0x0017
#define IA_DRC_DEC_CONFIG_PARAM_CONFIG_CHANGED 0x0018
#ifdef LOUDNESS_LEVELING_SUPPORT
#define IA_DRC_DEC_CONFIG_DRC_LOUDNESS_LEVELING 0x0019
#endif
#define IA_API_CMD_SET_INPUT_BYTES_BS 0x0026
#define IA_API_CMD_SET_INPUT_BYTES_IC_BS 0x0027
#define IA_API_CMD_SET_INPUT_BYTES_IL_BS 0x0029

View file

@ -75,7 +75,12 @@ pWORD8 ixheaacd_ppb_config_non_fatal[IA_MAX_ERROR_SUB_CODE] = {
(pWORD8) "Invalid target loudness value",
(pWORD8) "Invalid HQ eSBR flag option. Setting to default 0",
(pWORD8) "Invalid frame length flag option. Setting to default 0",
(pWORD8) "Invalid eSBR flag option. Setting to default 1"};
(pWORD8) "Invalid eSBR flag option. Setting to default 1"
#ifdef LOUDNESS_LEVELING_SUPPORT
,
(pWORD8) "Invalid Loudness leveling flag option. Setting to default 1"
#endif
};
/* Fatal Errors */
pWORD8 ixheaacd_ppb_config_fatal[IA_MAX_ERROR_SUB_CODE] = {
(pWORD8) "Invalid Sample rate specified for RAW decoding"};
@ -87,7 +92,12 @@ pWORD8 ixheaacd_ppb_config_fatal[IA_MAX_ERROR_SUB_CODE] = {
pWORD8 ixheaacd_ppb_init_non_fatal[IA_MAX_ERROR_SUB_CODE] = {
(pWORD8) "Header not found at the beginning of input data continuing syncing",
(pWORD8) "Invalid number of QMF bands", (pWORD8) "Decoder initialization failed",
(pWORD8) "Input bytes insufficient for decoding", (pWORD8) "Error in AAC decoding"};
(pWORD8) "Input bytes insufficient for decoding", (pWORD8) "Error in AAC decoding"
#ifdef LOUDNESS_LEVELING_SUPPORT
,
(pWORD8) "DRC instruction count exceeded"
#endif
};
/* Fatal Errors */
pWORD8 ixheaacd_ppb_init_fatal[IA_MAX_ERROR_SUB_CODE] = {
(pWORD8) "AAC Decoder initialization failed",

View file

@ -667,6 +667,17 @@ IA_ERRORCODE ixheaacd_set_config_param(WORD32 argc, pWORD8 argv[],
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
ec_enable = ui_err_conceal;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
/* For loudness leveling*/
if (!strncmp((pCHAR8)argv[i], "-loudness_leveling:", 19)) {
pCHAR8 pb_arg_val = (pCHAR8)(argv[i] + 19);
UWORD32 loudness_leveling_flag = atoi(pb_arg_val);
err_code = (*p_ia_process_api)(p_ia_process_api_obj, IA_API_CMD_SET_CONFIG_PARAM,
IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUDNESS_LEVELING,
&loudness_leveling_flag);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
}
#endif
}
return IA_NO_ERROR;
@ -899,7 +910,9 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
WORD32 drc_flag = 0;
WORD32 mpegd_drc_present = 0;
WORD32 uo_num_chan;
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 i_loudness_leveling_flag = 1;
#endif
/* The process API function */
IA_ERRORCODE(*p_ia_process_api)
(pVOID p_ia_process_api_obj, WORD32 i_cmd, WORD32 i_idx, pVOID pv_value);
@ -1410,6 +1423,22 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
}
#ifdef LOUDNESS_LEVELING_SUPPORT
/*Set loudness leveling */
{
err_code = (*p_ia_process_api)(pv_ia_process_api_obj, IA_API_CMD_GET_CONFIG_PARAM,
IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUDNESS_LEVELING,
&i_loudness_leveling_flag);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
err_code =
ia_drc_dec_api(pv_ia_drc_process_api_obj, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_DRC_LOUDNESS_LEVELING, &i_loudness_leveling_flag);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
}
#endif
/*Set loud_norm_flag*/
{
err_code = (*p_ia_process_api)(
@ -2238,6 +2267,9 @@ void print_usage() {
printf("\n[-peak_limiter_off:<peak_limiter_off_flag>]");
printf("\n[-err_conceal:<error_concealment_flag>]");
printf("\n[-esbr:<esbr_flag>]");
#ifdef LOUDNESS_LEVELING_SUPPORT
printf("\n[-loudness_leveling:<loudness_leveling_flag>]");
#endif
printf("\n\nwhere, \n <input_file> is the input AAC-LC/HE-AACv1/HE-AACv2//AAC-LD/AAC-ELD/AAC-ELDv2/USAC file name");
printf("\n <meta_data_file> is a text file which contains metadata.");
printf("\n To be given when -mp4:1 is enabled");
@ -2294,6 +2326,10 @@ void print_usage() {
printf("\n <error_concealment_flag> is to enable / disable error concealment.");
printf("\n Default value is 0");
printf("\n <esbr_flag> is to enable / disable eSBR. Default value is 1\n\n");
#ifdef LOUDNESS_LEVELING_SUPPORT
printf("\n <loudness_leveling_flag> is to enable / disable loudness leveling.");
printf("\n Default value is 1");
#endif
}
/*******************************************************************************/

View file

@ -15,13 +15,13 @@ if(MSVC)
xaacdec
PROPERTIES
COMPILE_FLAGS
"-UARM_PROFILE_HW -UARM_PROFILE_BOARD -DDRC_ENABLE -DMULTICHANNEL_ENABLE -DECLIPSE -DWIN32 -D_CRT_SECURE_NO_WARNINGS"
"-UARM_PROFILE_HW -UARM_PROFILE_BOARD -DDRC_ENABLE -DMULTICHANNEL_ENABLE -DECLIPSE -DWIN32 -D_CRT_SECURE_NO_WARNINGS -DLOUDNESS_LEVELING_SUPPORT"
)
else()
set_target_properties(
xaacdec
PROPERTIES
COMPILE_FLAGS
"-UARM_PROFILE_HW -UARM_PROFILE_BOARD -DDRC_ENABLE -DMULTICHANNEL_ENABLE -DECLIPSE -DWIN32"
"-UARM_PROFILE_HW -UARM_PROFILE_BOARD -DDRC_ENABLE -DMULTICHANNEL_ENABLE -DECLIPSE -DWIN32 -DLOUDNESS_LEVELING_SUPPORT"
)
endif()

View file

@ -1,3 +1,8 @@
#In order to support DRC AMD-2(ISO/IEC 23003-4:2020/Amd. 2:2023(E)), `leveling_present` and `ducking_only_set` fields are introduced in DRC config file.
#For a given DRC effect, when both `leveling_present` and `ducking_only_set` are set to 1, automatically the next drc instruction is treated as ducking only set.
#For example, if the second DRC effect is marked as 2048/4096 with `leveling_present` is set to 1 and `ducking_only_set` is set to 1, then the third DRC effect will be treated as ducking-only.
#For the last drc instruction, `leveling_present` and `ducking_only_set` fields are ignored and reset to 0. Maximum supported instructions are 8.
#####str_drc_instructions_uni_drc#####
drc_instructions_uni_drc_count:0
#####str_drc_coefficients_uni_drc#####
@ -28,10 +33,9 @@ attack:2.0
decay:5.0
#end gain parameters
#####str_drc_instructions_uni_drc_v1#####
drc_instructions_uni_drc_count:8
drc_instructions_uni_drc_count_v1:3
#n=0
downmix_id:0
#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_
drc_set_effect:0x0001
gain_set_channels:8
gain_set_index:0
@ -45,8 +49,7 @@ gain_set_index:0
num_drc_channel_groups:1
#n=1
downmix_id:0
#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_
drc_set_effect:0x0002
drc_set_effect:0x800
gain_set_channels:8
gain_set_index:0
gain_set_index:0
@ -57,80 +60,13 @@ gain_set_index:0
gain_set_index:0
gain_set_index:0
num_drc_channel_groups:1
#leveling present flag
leveling_present:1
#if ducking_only_set is one next drc instruction's set effect is set to 0x800 (ducking/leveling self)
ducking_only_set:1
#n=2
downmix_id:0
#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_
drc_set_effect:0x0004
gain_set_channels:8
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
num_drc_channel_groups:1
#n=3
downmix_id:0
#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_
drc_set_effect:0x0008
gain_set_channels:8
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
num_drc_channel_groups:1
#n=4
downmix_id:0
#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_
drc_set_effect:0x0010
gain_set_channels:8
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
num_drc_channel_groups:1
#n=5
downmix_id:0
#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_
drc_set_effect:0x0020
gain_set_channels:8
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
num_drc_channel_groups:1
#n=6
downmix_id:0
#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_
drc_set_effect:0x0040
gain_set_channels:8
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
num_drc_channel_groups:1
#n=7
downmix_id:0
#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_
drc_set_effect:0x0080
drc_set_effect:0x0800
gain_set_channels:8
gain_set_index:0
gain_set_index:0

View file

@ -92,7 +92,10 @@ VOID ixheaace_read_drc_config_params(FILE *fp, ia_drc_enc_params_struct *pstr_en
pstr_uni_drc_config->sample_rate_present = 1;
pstr_uni_drc_config->str_drc_coefficients_uni_drc->drc_frame_size_present = 0;
pstr_uni_drc_config->loudness_info_set_present = 1;
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD16 loudness_leveling_extension_present = 0;
UWORD32 config_extension_count = 0;
#endif
/*********** str_drc_instructions_uni_drc *************/
pstr_uni_drc_config->drc_instructions_uni_drc_count = impd_drc_get_integer_value(fp);
@ -145,8 +148,15 @@ VOID ixheaace_read_drc_config_params(FILE *fp, ia_drc_enc_params_struct *pstr_en
pstr_drc_instructions_uni_drc->drc_instructions_type = 0;
pstr_drc_instructions_uni_drc->mae_group_id = 0;
pstr_drc_instructions_uni_drc->mae_group_preset_id = 0;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
if (pstr_drc_instructions_uni_drc->drc_set_effect & EFFECT_BIT_DUCK_SELF) {
pstr_drc_instructions_uni_drc->leveling_present = impd_drc_get_integer_value(fp);
pstr_drc_instructions_uni_drc->ducking_only_set_present = impd_drc_get_integer_value(fp);
loudness_leveling_extension_present = 1;
}
#endif // LOUDNESS_LEVELING_SUPPORT
}
/*********** str_drc_coefficients_uni_drc *************/
pstr_uni_drc_config->drc_coefficients_uni_drc_count = impd_drc_get_integer_value(fp);
@ -247,7 +257,13 @@ VOID ixheaace_read_drc_config_params(FILE *fp, ia_drc_enc_params_struct *pstr_en
pstr_uni_drc_config->uni_drc_config_ext_present = 1;
if (pstr_uni_drc_config->uni_drc_config_ext_present) {
#ifdef LOUDNESS_LEVELING_SUPPORT
pstr_uni_drc_config->str_uni_drc_config_ext.uni_drc_config_ext_type[config_extension_count] =
UNIDRC_CONF_EXT_V1;
config_extension_count++;
#else
pstr_uni_drc_config->str_uni_drc_config_ext.uni_drc_config_ext_type[0] = UNIDRC_CONF_EXT_V1;
#endif
pstr_uni_drc_config->str_uni_drc_config_ext.downmix_instructions_v1_present = 1;
if (pstr_uni_drc_config->str_uni_drc_config_ext.downmix_instructions_v1_present) {
@ -420,9 +436,25 @@ VOID ixheaace_read_drc_config_params(FILE *fp, ia_drc_enc_params_struct *pstr_en
pstr_drc_instructions_uni_drc->drc_instructions_type = 0;
pstr_drc_instructions_uni_drc->mae_group_id = 0;
pstr_drc_instructions_uni_drc->mae_group_preset_id = 0;
#ifdef LOUDNESS_LEVELING_SUPPORT
if (pstr_drc_instructions_uni_drc->drc_set_effect & EFFECT_BIT_DUCK_SELF) {
pstr_drc_instructions_uni_drc->leveling_present = impd_drc_get_integer_value(fp);
pstr_drc_instructions_uni_drc->ducking_only_set_present =
impd_drc_get_integer_value(fp);
loudness_leveling_extension_present = 1;
}
#endif // LOUDNESS_LEVELING_SUPPORT
}
}
}
#ifdef LOUDNESS_LEVELING_SUPPORT
if (loudness_leveling_extension_present) {
pstr_uni_drc_config->str_uni_drc_config_ext.uni_drc_config_ext_type[config_extension_count] =
UNIDRCCONFEXT_LEVELING;
config_extension_count++;
}
#endif
pstr_enc_loudness_info_set->loudness_info_set_ext_present = 0;
pstr_enc_gain_extension->uni_drc_gain_ext_present = 0;
}

View file

@ -577,6 +577,20 @@ static VOID ixheaace_print_drc_config_params(ixheaace_input_config *pstr_input_c
pstr_uni_drc_config_user->str_drc_instructions_uni_drc[i].limiter_peak_target) {
flag = 1;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
if (pstr_uni_drc_config->str_drc_instructions_uni_drc[i].drc_set_effect !=
pstr_uni_drc_config_user->str_drc_instructions_uni_drc[i].drc_set_effect) {
flag = 1;
}
if (pstr_uni_drc_config->str_drc_instructions_uni_drc[i].leveling_present !=
pstr_uni_drc_config_user->str_drc_instructions_uni_drc[i].leveling_present) {
flag = 1;
}
if (pstr_uni_drc_config->str_drc_instructions_uni_drc[i].ducking_only_set_present !=
pstr_uni_drc_config_user->str_drc_instructions_uni_drc[i].ducking_only_set_present) {
flag = 1;
}
#endif
}
if (flag == 1) {
printf("\nDRC : Invalid config str_drc_instructions_uni_drc");
@ -653,6 +667,33 @@ static VOID ixheaace_print_drc_config_params(ixheaace_input_config *pstr_input_c
printf("\nDRC : Invalid config: str_drc_coefficients_uni_drc");
flag = 0;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
ia_drc_uni_drc_config_ext_struct *pstr_uni_drc_config_ext =
&pstr_uni_drc_config->str_uni_drc_config_ext;
ia_drc_uni_drc_config_ext_struct *pstr_uni_drc_config_ext_user =
&pstr_uni_drc_config_user->str_uni_drc_config_ext;
for (i = 0; i < pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count; i++) {
if (pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].drc_set_effect !=
pstr_uni_drc_config_ext_user->str_drc_instructions_uni_drc_v1[i].drc_set_effect) {
flag = 1;
}
if (pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].leveling_present !=
pstr_uni_drc_config_ext_user->str_drc_instructions_uni_drc_v1[i].leveling_present) {
flag = 1;
}
if (pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].ducking_only_set_present !=
pstr_uni_drc_config_ext_user->str_drc_instructions_uni_drc_v1[i]
.ducking_only_set_present) {
flag = 1;
}
}
if (flag == 1) {
printf("\nDRC : Invalid config str_drc_instructions_uni_drc_v1");
flag = 0;
}
#endif
for (i = 0; i < pstr_enc_loudness_info_set->loudness_info_count; i++) {
if (pstr_enc_loudness_info_set->str_loudness_info[i].sample_peak_level !=
pstr_enc_loudness_info_set_user->str_loudness_info[i].sample_peak_level) {

View file

@ -18,12 +18,12 @@ if (MSVC)
xaacenc
PROPERTIES
COMPILE_FLAGS
"-D_CRT_SECURE_NO_WARNINGS -D_X86_")
"-D_CRT_SECURE_NO_WARNINGS -D_X86_ -DLOUDNESS_LEVELING_SUPPORT")
else()
set_target_properties(
xaacenc
PROPERTIES
COMPILE_FLAGS
"-D_X86_ -c -O3 -Wall -Wsequence-point -Wunused-function"
"-D_X86_ -c -O3 -Wall -Wsequence-point -Wunused-function -DLOUDNESS_LEVELING_SUPPORT"
)
endif()