From 5010b92449afeeb7f23b19b93ea06ca12a957e10 Mon Sep 17 00:00:00 2001 From: Shanush Prema Thasarathan Date: Thu, 20 Oct 2022 17:55:36 +1100 Subject: [PATCH 1/5] AGC tuning change and enable AGC for SBA SPAR 1TC This commit has two changes: A tuning change has been done to fix a clicking artifact (of which is described in the issue #168.) The changes include: - Limiting the attack/release done per frame to 6dB - In the code, this attack/release amount is configurable at compile time using the `DBSTEP` macro - Always distributing the total amount of attack/release to be done across a maximum of 3 frames - Removing hard transition cases and instead always doing a smooth transition These changes are bit exact for signals that do not become OOR inside the encoder. However the changes are, of course, not bit exact for non-OOR signals. AGC will be enabled by default when 1 transport channel is used and in SBA mode. This translates to bitrates of 24.4 and 32kbps in SBA. It is enabled only in these modes, because these are the modes where we know out of range signals can occur, and because degradations are known to occur for the 1 transport channel case. Further explanation is done in issue #168. Otherwise AGC is disabled. In the command line, a user can force agc to be enabled or disabled using the `-agc` flag. If a user does not specify the `-agc` flag, then the default behaviour will be done. Additional tests have been added, where for any test in `tests/test_sba_bs_dec_plc.py` and `tests/test_sba_bs_enc.py` which had agc has a paramaeter, agc undefined case was added. For any other existing tests which had set AGC to off, it has been changed to be AGC undefined to maintain the previous intent. For the python files touched, small editorial changes were made to comply with the pep8 standard. Co-authored-by: Benjamin McDonald Co-authored-by: Panji Setiawan --- apps/encoder.c | 19 ++++++ lib_com/ivas_agc_com.c | 29 +++++++++ lib_com/ivas_prot.h | 11 +++- lib_com/options.h | 8 ++- lib_dec/ivas_agc_dec.c | 14 ++++ lib_enc/ivas_agc_enc.c | 68 ++++++++++++++++++- lib_enc/ivas_spar_encoder.c | 7 ++ lib_enc/ivas_stat_enc.h | 11 +++- lib_enc/lib_enc.c | 41 ++++++++++-- lib_enc/lib_enc.h | 12 ++++ tests/test_sba_bs_dec_plc.py | 80 +++++++++++------------ tests/test_sba_bs_enc.py | 123 ++++++++++++++++++----------------- 12 files changed, 312 insertions(+), 111 deletions(-) diff --git a/apps/encoder.c b/apps/encoder.c index b1abc36d2f..bcd2dcea78 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -120,7 +120,11 @@ typedef struct const char *ca_config_file; bool mimeOutput; +#ifdef AGC_ENABLE_FOR_LBR + IVAS_ENC_AGC agc; +#else bool agc; +#endif bool pca; #ifdef DEBUG_FOA_AGC FILE *agcBitstream; /* temporary */ @@ -870,7 +874,11 @@ static void initArgStruct( EncArguments *arg ) arg->ca_config_file = NULL; arg->mimeOutput = false; +#ifdef AGC_ENABLE_FOR_LBR + arg->agc = IVAS_ENC_AGC_UNDEFINED; +#else arg->agc = IVAS_DEFAULT_AGC; +#endif arg->pca = false; #ifdef DEBUG_FOA_AGC arg->agcBitstream = NULL; @@ -1381,7 +1389,11 @@ static bool parseCmdlIVAS_enc( i++; if ( i < argc - 4 ) { +#ifdef AGC_ENABLE_FOR_LBR + arg->agc = ( atoi( argv[i] ) ) ? IVAS_ENC_AGC_ENABLED : IVAS_ENC_AGC_DISABLED; +#else arg->agc = (int16_t) atoi( argv[i] ); +#endif if ( argv[i] == NULL || atoi( argv[i] ) < 0 || atoi( argv[i] ) > 1 ) { fprintf( stderr, "Error: wrong adaptive gain control option specified (%d), expected 0 or 1\n\n", (int32_t) atoi( argv[i] ) ); @@ -1636,7 +1648,14 @@ static void usage_enc( void ) #ifdef DEBUG_SBA fprintf( stdout, "-tag : Tag name for intermediate debug files\n" ); #endif +#ifdef AGC_ENABLE_FOR_LBR + fprintf( stdout, "-agc op : SBA Adaptive gain control, op = (0, 1). \n" ); + fprintf( stdout, " By default op is 1 (activated) for bitrates between 24400 and 32000,\n" ); + fprintf( stdout, " otherwise it is 0 (deactivated) for all other bitrates\n" ); +#else fprintf( stdout, "-agc op : SBA Adaptive gain control, op = (0, 1), by default op is 0 or deactivated\n" ); +#endif + fprintf( stdout, "-bypass mode : SBA PCA by-pass, mode = (1, 2), 1 = PCA off, 2 = signal adaptive, default is 1\n" ); #ifdef DEBUGGING fprintf( stdout, "-force T : Force specific mode, T = (speech, music, ACELP, GSC, TCX, HQ),\n" ); diff --git a/lib_com/ivas_agc_com.c b/lib_com/ivas_agc_com.c index d7a174fe65..63dda27afd 100644 --- a/lib_com/ivas_agc_com.c +++ b/lib_com/ivas_agc_com.c @@ -40,6 +40,9 @@ #endif #include #include "wmops.h" +#ifdef AGC_TUNING_IMPROVEMENT +#include "prot.h" +#endif /*------------------------------------------------------------------------------------------* * Local constants @@ -47,6 +50,11 @@ #define SQRKMAX ( 1.5f ) #define NBITS_DIFFG ( 2 ) +#ifdef AGC_TUNING_IMPROVEMENT +#define DBSTEP ( -6.f ) /* desired dB step value in dB*/ +#define ABS_EMIN_MAX ( 3 ) +#define MAXATTEXP ( 1 ) /* the desired maximum attenuation exponent range per frame*/ +#endif /*-----------------------------------------------------------------------------------------* * Function ivas_agc_initWindowFunc() @@ -60,12 +68,22 @@ void ivas_agc_initWindowFunc( { int16_t i; float N; +#ifdef AGC_TUNING_IMPROVEMENT + float a; +#endif N = (float) ( length - 1 ); +#ifdef AGC_TUNING_IMPROVEMENT + a = 0.5f * ( 1.f - powf( 10.f, DBSTEP / 20.f ) ); +#endif for ( i = 0; i < length; i++ ) { +#ifdef AGC_TUNING_IMPROVEMENT + pWinFunc[i] = 1.f + a * ( cosf( EVS_PI * i / N ) - 1.f ); +#else pWinFunc[i] = 0.75f + 0.25f * cosf( EVS_PI * i / N ); +#endif } return; @@ -89,7 +107,11 @@ void ivas_agc_calcGainParams( nbits = NBITS_DIFFG; +#ifdef AGC_TUNING_IMPROVEMENT + *absEmin = max( ABS_EMIN_MAX, (uint16_t) ceilf( logf( ceilf( SQRKMAX * numCoeffs ) ) * INV_LOG_2 ) ); +#else *absEmin = (uint16_t) ceilf( logf( ceilf( SQRKMAX * numCoeffs ) ) * INV_LOG_2 ); +#endif totExp = *absEmin + AGC_EMAX + 1; *betaE = (uint16_t) ceilf( logf( totExp ) * INV_LOG_2 ); @@ -98,10 +120,17 @@ void ivas_agc_calcGainParams( if ( nbits > 0 ) { +#ifdef AGC_TUNING_IMPROVEMENT + Bm = min( AGC_BITS_PER_CH - 1, NBITS_DIFFG ); +#else Bm = NBITS_DIFFG; +#endif } *maxAttExp = ( (uint16_t) powf( 2, Bm ) ) - 2; +#ifdef AGC_TUNING_IMPROVEMENT + *maxAttExp = min( MAXATTEXP, *maxAttExp ); +#endif return; } diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 84450e89a0..ca1d236fae 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -44,7 +44,9 @@ #include "ivas_stat_dec.h" #include "ivas_stat_com.h" #include "ivas_error_utils.h" - +#ifdef AGC_ENABLE_FOR_LBR +#include "lib_enc.h" +#endif /* clang-format off */ @@ -3770,6 +3772,13 @@ void ivas_sba_prototype_renderer( ); /* AGC */ +#ifdef AGC_ENABLE_FOR_LBR +int16_t ivas_agc_enc_get_enablement_flag( + IVAS_ENC_AGC agc_configuration, /* i : configuration used when encoder was initialised from cmd line */ + int16_t nchan_transport /* i : number of transport channels */ +); +#endif + ivas_error ivas_spar_agc_enc_open( ivas_agc_enc_state_t **hAgcEnc, /* i/o: AGC decoder handle */ const int32_t input_Fs, /* i : input sampling rate */ diff --git a/lib_com/options.h b/lib_com/options.h index 5906991cdf..66fc0c611b 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -142,7 +142,7 @@ #define DISABLE_ADAP_RES_COD_TMP /* temporary fix for IVAS-403, disables adaptive residual coding */ /*#define ITD_WINNER_GAIN_MODIFY */ /* ITD optimization - WORK IN PROGRESS */ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ -#define MDCT_STEREO_PLC_FADE_2_BG_NOISE /* IVAS-185 fix bug in TCX-PLC fadeout for MDCT-Stereo and improve fadeout by fading to background noise instead of white noise */ +#define MDCT_STEREO_PLC_FADE_2_BG_NOISE /* IVAS-185 fix bug in TCX-PLC fadeout for MDCT-Stereo and improve fadeout by fading to background noise instead of white noise */ #define FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS /*#define FIX_I1_113*/ /* under review : MCT bit distribution optimization for SBA high bitrates*/ @@ -152,8 +152,10 @@ #define ISM_BITRATE_SWITCHING /* Issue 115: Support for Bitrate Switching in ISM */ #define SBA_SPAR_HARM /* Issue 92: maintenance of the SBA SPAR functions */ #define FIX_155_HP20_ISSUE /* Issue 155: apply hp20 on all input channels instead of just 2 channels */ - - +#define AGC_TUNING_IMPROVEMENT /* Issue 168: Tuning improvement to deal with click artifacts */ +#ifdef AGC_TUNING_IMPROVEMENT +#define AGC_ENABLE_FOR_LBR /* Issue 168: Enable AGC for low bit rate (1 TC) */ +#endif /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_agc_dec.c b/lib_dec/ivas_agc_dec.c index 97ce3d49d1..81039651d8 100644 --- a/lib_dec/ivas_agc_dec.c +++ b/lib_dec/ivas_agc_dec.c @@ -190,10 +190,20 @@ void ivas_agc_dec_process( if ( ( pState->gain_state[i].gainExpVal > (int32_t) ( pState->agc_com.maxAttExp + 1 ) ) || ( pState->gain_state[i].gainExpVal < -1 ) ) { +#ifdef AGC_TUNING_IMPROVEMENT + /* Such conditions indicate packet loss, better reset and do nothing*/ + pState->gain_data[i].absGainExp = pState->agc_com.absEmin; + pState->gain_state[i].gainExpVal = 0; +#else assert( 0 ); +#endif } +#ifdef AGC_TUNING_IMPROVEMENT + pState->gain_state[i].lastGain = powf( pState->agc_com.winFunc[offset - 1], ( -1.f * (float) ( pState->gain_data[i].absGainExp - pState->agc_com.absEmin ) ) ); +#else pState->gain_state[i].lastGain = powf( 2, (float) ( pState->gain_data[i].absGainExp - pState->agc_com.absEmin ) ); +#endif gainLast = 1.f / pState->gain_state[i].lastGain; if ( !pState->gain_data[i].gainException ) @@ -227,7 +237,11 @@ void ivas_agc_dec_process( } else { +#ifdef AGC_TUNING_IMPROVEMENT + float gainCurr = powf( pState->agc_com.winFunc[offset - 1], ( -1.f * (float) pState->gain_state[i].gainExpVal ) ); +#else float gainCurr = powf( 2, (float) pState->gain_state[i].gainExpVal ); +#endif float gainTot = gainCurr * gainLast; for ( idx = 0; idx < output_frame; idx++ ) diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc.c index 3ed7bb6d2f..702324d2a8 100644 --- a/lib_enc/ivas_agc_enc.c +++ b/lib_enc/ivas_agc_enc.c @@ -59,6 +59,25 @@ extern FILE *agcOut; static int16_t ivas_agc_writeBits( FILE *stream, const int16_t n_channels, ivas_agc_enc_state_t *pState ); #endif +#ifdef AGC_ENABLE_FOR_LBR +/*-----------------------------------------------------------------------------------------* + * Function ivas_agc_enc_get_enablement_flag() + * + * This function determines if AGC should be enabled or disabled. + * If agc_configuration is not undefined, then this value decides on the state of + * enablement, otherwise AGC is enabled only if there is one transport channel. + * + *-----------------------------------------------------------------------------------------*/ + +int16_t ivas_agc_enc_get_enablement_flag( + IVAS_ENC_AGC agc_configuration, + int16_t nchan_transport ) +{ + return (bool) ( ( agc_configuration == IVAS_ENC_AGC_UNDEFINED ) + ? ( nchan_transport == 1 ) + : !!agc_configuration ); +} +#endif /*-----------------------------------------------------------------------------------------* * Function ivas_agc_enc_init() @@ -215,7 +234,11 @@ void ivas_agc_enc_process( { float sampleAbsVal; int16_t isClipped = FALSE; +#ifdef AGC_TUNING_IMPROVEMENT + int16_t clippedIdx = 0; +#else int16_t clippedIdx = offset - 1; +#endif int16_t MaxAbsValIdx = 0; float MaxAbsVal = pState->gain_state[i].MaxAbsVal_del; float predMaxAbsVal = fabsf( ppPcm_in[i][offset] ); @@ -244,19 +267,25 @@ void ivas_agc_enc_process( { if ( ( ppPcm_out[i][j] > ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC ) || ( ppPcm_out[i][j] < MIN16B_FLT ) ) { +#ifdef AGC_TUNING_IMPROVEMENT + clippedIdx = j; +#else if ( j < offset ) { clippedIdx = j; } +#endif isClipped = TRUE; } } } +#ifndef AGC_TUNING_IMPROVEMENT if ( MaxAbsValIdx >= offset ) { MaxAbsValIdx = offset - 1; } +#endif pState->gain_state[i].MaxAbsVal_del = predMaxAbsVal; isGainAdjusted = FALSE; @@ -305,15 +334,21 @@ void ivas_agc_enc_process( if ( isClipped ) { actualMaxAbsVal = pState->gain_state[i].lastMaxAbs * pState->gain_state[i].lastGain; +#ifndef AGC_TUNING_IMPROVEMENT if ( MaxAbsValIdx == 0 ) { pState->gain_data[i].gainException = TRUE; } else { +#endif int16_t isCompensated = FALSE; pState->gain_data[i].gainException = FALSE; - pState->gain_state[i].gainExpVal = (int16_t) ceilf( -logf( actualMaxAbsVal * MDFT_NORM_SCALING ) / logf( pState->agc_com.winFunc[MaxAbsValIdx] ) ); +#ifdef AGC_TUNING_IMPROVEMENT + pState->gain_state[i].gainExpVal = (int16_t) ceilf( -logf( actualMaxAbsVal * MDFT_NORM_SCALING ) / logf( pState->agc_com.winFunc[min( offset - 1, MaxAbsValIdx )] ) ); +#else + pState->gain_state[i].gainExpVal = (int16_t) ceilf( -logf( actualMaxAbsVal * MDFT_NORM_SCALING ) / logf( pState->agc_com.winFunc[MaxAbsValIdx] ) ); +#endif while ( !isCompensated ) { @@ -322,7 +357,19 @@ void ivas_agc_enc_process( for ( idx = clippedIdx; idx <= MaxAbsValIdx; idx++ ) { - tmpSignal = ppPcm_out[i][idx] * powf( pState->agc_com.winFunc[idx], (float) pState->gain_state[i].gainExpVal ); +#ifdef AGC_TUNING_IMPROVEMENT + if ( idx >= offset ) + { + idx = MaxAbsValIdx; + tmpSignal = ppPcm_out[i][idx] * powf( pState->agc_com.winFunc[offset - 1], (float) pState->gain_state[i].gainExpVal ); + } + else + { +#endif + tmpSignal = ppPcm_out[i][idx] * powf( pState->agc_com.winFunc[idx], (float) pState->gain_state[i].gainExpVal ); +#ifdef AGC_TUNING_IMPROVEMENT + } +#endif if ( ( tmpSignal > ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC ) || ( tmpSignal < MIN16B_FLT ) ) { @@ -336,6 +383,14 @@ void ivas_agc_enc_process( pState->gain_state[i].gainExpVal++; } +#ifdef AGC_TUNING_IMPROVEMENT + if ( pState->gain_state[i].gainExpVal > currMaxAttExp ) + { + pState->gain_state[i].gainExpVal = min( pState->gain_state[i].gainExpVal, currMaxAttExp ); + break; + } +#endif + if ( pState->gain_state[i].gainExpVal > currMaxAttExp ) { pState->gain_data[i].gainException = TRUE; @@ -351,7 +406,9 @@ void ivas_agc_enc_process( break; } } +#ifndef AGC_TUNING_IMPROVEMENT } +#endif } if ( !pState->gain_data[i].gainException ) @@ -377,7 +434,11 @@ void ivas_agc_enc_process( pState->gain_state[i].gainExpVal = (int16_t) ( -floorf( -logf( ( actualMaxAbsVal + pState->minDelta ) * MDFT_NORM_SCALING ) * INV_LOG_2 ) ); pState->gain_state[i].gainExpVal = min( gainExpValMaxRange, pState->gain_state[i].gainExpVal ); +#ifdef AGC_TUNING_IMPROVEMENT + gain = powf( pState->agc_com.winFunc[offset - 1], pState->gain_state[i].gainExpVal ); +#else gain = powf( 2.0f, -1.0f * pState->gain_state[i].gainExpVal ); +#endif for ( idx = 0; idx < input_frame; idx++ ) { ppPcm_out[i][idx] *= gain; @@ -466,6 +527,9 @@ void ivas_agc_enc_process( { push_next_indice( hMetaData, (uint16_t) pState->gain_data[i].absGainExpCurr, (int16_t) pState->agc_com.betaE ); push_next_indice( hMetaData, (uint16_t) pState->gain_data[i].gainException, 1 ); +#ifdef AGC_TUNING_IMPROVEMENT + assert( pState->gain_data[i].gainException == FALSE ); +#endif } } } diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 988a8fa013..d49521a3ce 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -120,6 +120,9 @@ ivas_error ivas_spar_enc_open( } /* AGC handle */ +#ifdef AGC_ENABLE_FOR_LBR + hSpar->AGC_Enable = ivas_agc_enc_get_enablement_flag( hEncoderConfig->Opt_AGC_ON, nchan_transport ); +#endif if ( ( error = ivas_spar_agc_enc_open( &hSpar->hAgcEnc, input_Fs, nchan_inp ) ) != IVAS_ERR_OK ) { return error; @@ -877,7 +880,11 @@ static ivas_error ivas_spar_enc_process( if ( dtx_vad == 1 ) { +#ifdef AGC_ENABLE_FOR_LBR + if ( hSpar->AGC_Enable > 0 ) +#else if ( hEncoderConfig->Opt_AGC_ON > 0 ) +#endif { ivas_agc_enc_process( hSpar->hAgcEnc, hMetaData, p_pcm_tmp, p_pcm_tmp, hSpar->hFbMixer->fb_cfg->num_out_chans, hEncoderConfig ); } diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index a4e8e1142a..181a05f114 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -40,7 +40,9 @@ #include "stat_enc.h" #include "ivas_cnst.h" #include "ivas_stat_com.h" - +#ifdef AGC_ENABLE_FOR_LBR +#include "lib_enc.h" +#endif /*----------------------------------------------------------------------------------* * DFT Stereo encoder structures @@ -692,6 +694,9 @@ typedef struct ivas_spar_enc_lib_t ivas_agc_enc_state_t *hAgcEnc; int16_t dirac_to_spar_md_bands[DIRAC_MAX_NBANDS]; int16_t enc_param_start_band; +#ifdef AGC_ENABLE_FOR_LBR + int16_t AGC_Enable; +#endif PCA_ENC_STATE *hPCA; int32_t core_nominal_brate; /* Nominal bitrate for core coding */ FRONT_VAD_ENC_HANDLE hFrontVad; /* front-VAD handle */ @@ -1020,8 +1025,12 @@ typedef struct encoder_config_structure int16_t Opt_SC_VBR; /* flag indicating SC-VBR mode */ int16_t last_Opt_SC_VBR; /* flag indicating prev frame's SC-VBR mode */ +#ifdef AGC_ENABLE_FOR_LBR + IVAS_ENC_AGC Opt_AGC_ON; /* flag indicating AGC operation in SBA */ +#else /* temp. development parameters */ int16_t Opt_AGC_ON; /* flag indicating AGC operation in SBA */ +#endif int16_t Opt_PCA_ON; /* flag indicating PCA operation in SBA */ #ifdef DEBUGGING diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 4f990a25df..e21ac143b0 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -451,8 +451,12 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ const IVAS_ENC_SBA_ORDER order, /* i : order of the Ambisonics input */ const bool isPlanar, /* i : if true, input is treated as planar Ambisonics */ - const bool Opt_AGC_ON, /* i : AGC on/off flag */ - const bool Opt_PCA_ON /* i : PCA option flag */ +#ifdef AGC_ENABLE_FOR_LBR + const IVAS_ENC_AGC Opt_AGC_ON, /* i : AGC on/off/undefined flag */ +#else + const bool Opt_AGC_ON, /* i : AGC on/off flag */ +#endif + const bool Opt_PCA_ON /* i : PCA option flag */ #ifdef DEBUG_SBA_AUDIO_DUMP , int16_t *numTransportChannels @@ -475,7 +479,11 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( hEncoderConfig->sba_order = order; /* Input in ACN/SN3D in all cases (3D and planar): get number of channels */ hEncoderConfig->nchan_inp = ivas_sba_get_nchan( hEncoderConfig->sba_order, 0 ); /*planar input arg. deliberately set to zero since input always in ACN/SN3D*/ +#ifdef AGC_ENABLE_FOR_LBR + hEncoderConfig->Opt_AGC_ON = Opt_AGC_ON; +#else hEncoderConfig->Opt_AGC_ON = (int16_t) Opt_AGC_ON; +#endif hEncoderConfig->Opt_PCA_ON = (int16_t) Opt_PCA_ON; hIvasEnc->maxBandwidthUser = max_bwidth_user; @@ -889,7 +897,11 @@ static ivas_error configureEncoder( return IVAS_ERROR( IVAS_ERR_DTX_NOT_SUPPORTED, "DTX is not supported in this IVAS format and element mode." ); } +#ifdef AGC_ENABLE_FOR_LBR + if ( hEncoderConfig->Opt_AGC_ON == IVAS_ENC_AGC_ENABLED && !( hEncoderConfig->ivas_format == SBA_FORMAT && ivas_sba_mode_select( hEncoderConfig->ivas_total_brate ) == SBA_MODE_SPAR ) ) +#else if ( hEncoderConfig->Opt_AGC_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && ivas_sba_mode_select( hEncoderConfig->ivas_total_brate ) == SBA_MODE_SPAR ) ) +#endif { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "AGC supported in SBA format at bitrates >= 24.4 kbps only." ); } @@ -1506,10 +1518,27 @@ static ivas_error printConfigInfo_enc( { fprintf( stdout, "- PCA configured with signal adaptive decision " ); } - if ( hEncoderConfig->Opt_AGC_ON ) +#ifdef AGC_ENABLE_FOR_LBR + switch ( hEncoderConfig->Opt_AGC_ON ) { - fprintf( stdout, "- AGC ON " ); + case IVAS_ENC_AGC_ENABLED: + fprintf( stdout, "- AGC FORCED ON " ); + break; + case IVAS_ENC_AGC_DISABLED: + fprintf( stdout, "- AGC FORCED OFF " ); + break; + case IVAS_ENC_AGC_UNDEFINED: + fprintf( stdout, "- AGC default mode " ); + break; + default: + fprintf( stdout, "- AGC unknown " ); + break; } +#else + if ( hEncoderConfig->Opt_AGC_ON ) + fprintf( stdout, "- AGC ON " ); + } +#endif fprintf( stdout, "\n" ); } else if ( hEncoderConfig->ivas_format == MASA_FORMAT ) @@ -2182,7 +2211,11 @@ static void init_encoder_config( hEncoderConfig->stereo_dmx_evs = 0; hEncoderConfig->sba_order = 0; hEncoderConfig->sba_planar = 0; +#ifdef AGC_ENABLE_FOR_LBR + hEncoderConfig->Opt_AGC_ON = IVAS_ENC_AGC_UNDEFINED; +#else hEncoderConfig->Opt_AGC_ON = 0; +#endif hEncoderConfig->Opt_PCA_ON = 0; return; diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index 325c854f73..20eef7b1fe 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -123,6 +123,14 @@ typedef enum _IVAS_ENC_FORCED_MODE } IVAS_ENC_FORCED_MODE; #endif +#ifdef AGC_ENABLE_FOR_LBR +typedef enum _IVAS_ENC_AGC +{ + IVAS_ENC_AGC_DISABLED = 0, + IVAS_ENC_AGC_ENABLED, + IVAS_ENC_AGC_UNDEFINED = 0xffff +} IVAS_ENC_AGC; +#endif /*---------------------------------------------------------------------* * Encoder structures @@ -189,7 +197,11 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ const IVAS_ENC_SBA_ORDER order, /* i : order of the Ambisonics input */ const bool isPlanar, /* i : if true, input is treated as planar Ambisonics */ +#ifdef AGC_ENABLE_FOR_LBR + const IVAS_ENC_AGC Opt_AGC_ON, /* i : AGC on/off/undefined flag */ +#else const bool Opt_AGC_ON, /* i : AGC on/off flag */ +#endif const bool Opt_PCA_ON /* i : PCA option flag */ #ifdef DEBUG_SBA_AUDIO_DUMP , diff --git a/tests/test_sba_bs_dec_plc.py b/tests/test_sba_bs_dec_plc.py index 58be07ec33..27bf561cdc 100644 --- a/tests/test_sba_bs_dec_plc.py +++ b/tests/test_sba_bs_dec_plc.py @@ -1,38 +1,38 @@ __copyright__ = \ -""" -(C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, -Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., -Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, -Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other -contributors to this repository. All Rights Reserved. - -This software is protected by copyright law and by international treaties. -The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, -Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., -Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, -Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other -contributors to this repository retain full ownership rights in their respective contributions in -the software. This notice grants no license of any kind, including but not limited to patent -license, nor is any license granted by implication, estoppel or otherwise. - -Contributors are required to enter into the IVAS codec Public Collaboration agreement before making -contributions. - -This software is provided "AS IS", without any express or implied warranties. The software is in the -development stage. It is intended exclusively for experts who have experience with such software and -solely for the purpose of inspection. All implied warranties of non-infringement, merchantability -and fitness for a particular purpose are hereby disclaimed and excluded. - -Any dispute, controversy or claim arising under or in relation to providing this software shall be -submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in -accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and -the United Nations Convention on Contracts on the International Sales of Goods. -""" + """ + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + """ __doc__ = \ -""" -Execute SBA decoder tests using different PLC patterns. -""" + """ + Execute SBA decoder tests using different PLC patterns. + """ import os import errno @@ -41,13 +41,13 @@ import pytest from cmp_custom import cmp_custom from conftest import DecoderFrontend -#params +# params tag_list = ['stvFOA'] plc_patterns = ['PLperc12mblen5', 'PLperc40mblen50', 'PLperc42mblen2'] dtx_set = ['0', '1'] ivas_br_list = ['32000', '64000', '96000', '256000'] sampling_rate_list = ['48', '32', '16'] -agc_list = [0, 1] +agc_list = [-1, 0, 1] AbsTol = '3' @@ -91,7 +91,7 @@ def test_sba_plc_system( ): tag = tag + fs + 'c' - #dec + # dec sba_dec_plc( dut_decoder_frontend, test_vector_path, @@ -110,7 +110,7 @@ def test_sba_plc_system( ######################################################### -############ test function ############################## +# -------------------- test function -------------------- def sba_dec_plc( decoder_frontend, test_vector_path, @@ -127,11 +127,11 @@ def sba_dec_plc( keep_files, ): - ######### run cmd ##################################### + # ------------ run cmd ------------ tag_out = f"{tag}_ivasbr{ivas_br[:-3]}k_DTX{dtx}" - if agc == 1: - tag_out += '_AGC1' + if agc != -1: + tag_out += f'_AGC{agc}' plc_tag_out = f"{tag_out}_{plc_pattern}" dut_out_dir = f"{dut_base_path}/sba_bs/raw" @@ -169,7 +169,7 @@ def sba_dec_plc( plc_file=plc_file, ) - ######### compare cmd ##################################### + # -------------- compare cmd -------------- end_skip_samples = '0' diff --git a/tests/test_sba_bs_enc.py b/tests/test_sba_bs_enc.py index 95cfea1d19..e8edf01285 100644 --- a/tests/test_sba_bs_enc.py +++ b/tests/test_sba_bs_enc.py @@ -1,39 +1,39 @@ __copyright__ = \ -""" -(C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, -Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., -Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, -Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other -contributors to this repository. All Rights Reserved. - -This software is protected by copyright law and by international treaties. -The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, -Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., -Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, -Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other -contributors to this repository retain full ownership rights in their respective contributions in -the software. This notice grants no license of any kind, including but not limited to patent -license, nor is any license granted by implication, estoppel or otherwise. - -Contributors are required to enter into the IVAS codec Public Collaboration agreement before making -contributions. - -This software is provided "AS IS", without any express or implied warranties. The software is in the -development stage. It is intended exclusively for experts who have experience with such software and -solely for the purpose of inspection. All implied warranties of non-infringement, merchantability -and fitness for a particular purpose are hereby disclaimed and excluded. - -Any dispute, controversy or claim arising under or in relation to providing this software shall be -submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in -accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and -the United Nations Convention on Contracts on the International Sales of Goods. -""" + """ + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + """ __doc__ = \ -""" -Test file to run C encoder and decoder code. -The outputs are compared with C generated references. -""" + """ + Test file to run C encoder and decoder code. + The outputs are compared with C generated references. + """ import os import errno @@ -43,23 +43,23 @@ from cmp_custom import cmp_custom from cut_pcm import cut_samples from conftest import EncoderFrontend, DecoderFrontend -#params +# params tag_list = ['stvFOA'] tag_list_HOA2 = ['test_HOA2'] tag_list_HOA3 = ['test_HOA3'] tag_list_bw_force = ['stvFOA'] dtx_set = ['0', '1'] -dict_fsample_bw = {'48':'3', '32':'2', '16':'1'} -dict_bw_idx = {'FB':'3', 'SWB':'2', 'WB':'1'} -dict_bw_tag = {'SWB':'_ForceSWB', 'WB':'_ForceWB'} +dict_fsample_bw = {'48': '3', '32': '2', '16': '1'} +dict_bw_idx = {'FB': '3', 'SWB': '2', 'WB': '1'} +dict_bw_tag = {'SWB': '_ForceSWB', 'WB': '_ForceWB'} ivas_br_FOA = ['32000', '64000', '96000', '160000', '256000', '384000', '512000'] ivas_br_HOA2 = ['256000', '384000', '512000'] ivas_br_HOA3 = ['256000', '384000', '512000'] sample_rate_list = ['48', '32', '16'] bypass_list = [1, 2] -agc_list = [0, 1] +agc_list = [-1, 0, 1] sample_rate_bw_idx_list = [('48', 'SWB'), ('48', 'WB'), ('32', 'WB')] @@ -100,7 +100,7 @@ def test_bypass_enc( ivas_br = '256000' dtx = '0' max_bw = "FB" - agc = 0 + agc = -1 sba_order = "+1" output_config = "FOA" @@ -173,7 +173,7 @@ def test_sba_enc_system( elif dtx == '1': cut_gain = ".004" else: - cut_gain = "1.0" + cut_gain = "1.0" # enc sba_enc( dut_encoder_frontend, @@ -212,6 +212,7 @@ def test_sba_enc_system( keep_files, ) + @pytest.mark.create_ref @pytest.mark.parametrize("ivas_br", ivas_br_HOA2) @pytest.mark.parametrize("tag", tag_list_HOA2) @@ -275,6 +276,7 @@ def test_spar_hoa2_enc_system( keep_files, ) + @pytest.mark.create_ref @pytest.mark.parametrize("ivas_br", ivas_br_HOA3) @pytest.mark.parametrize("tag", tag_list_HOA3) @@ -338,6 +340,7 @@ def test_spar_hoa3_enc_system( keep_files, ) + @pytest.mark.create_ref @pytest.mark.parametrize("ivas_br", ivas_br_FOA) @pytest.mark.parametrize("dtx", dtx_set) @@ -362,7 +365,7 @@ def test_sba_enc_BWforce_system( bw = sample_rate_bw_idx[1] tag = tag + fs + 'c' bypass = -1 - agc = 0 + agc = -1 sba_order = "+1" output_config = "FOA" @@ -404,7 +407,7 @@ def test_sba_enc_BWforce_system( ######################################################### -############ test function ############################## +# -------------------- test function -------------------- def sba_enc( encoder_frontend, test_vector_path, @@ -420,12 +423,12 @@ def sba_enc( agc, sba_order, update_ref, - in_extension = '.pcm', - cut_gain = '1.0', - create_dutenc = False + in_extension='.pcm', + cut_gain='1.0', + create_dutenc=False ): - ######### run cmd ##################################### + # ------------ run cmd ------------ dut_out_dir = f"{dut_base_path}/sba_bs/pkt" ref_out_dir = f"{reference_path}/sba_bs/pkt" @@ -433,34 +436,34 @@ def sba_enc( check_and_makedir(ref_out_dir) tag_in = tag - #sampling rate to BW mapping + # sampling rate to BW mapping bw_idx = dict_fsample_bw[sampling_rate] if int(dict_bw_idx[ivas_max_bw]) < int(bw_idx): tag = tag + dict_bw_tag[ivas_max_bw] - tag_out = f"{tag}_ivasbr{ivas_br[:-3]}k_DTX{dtx}" short_tag_ext = "" - if agc == 1: - short_tag_ext += '_AGC1' + if agc != -1: + short_tag_ext += f'_AGC{agc}' # we update only bypass = 0/2 (bypass 1 is the same as the baseline) if bypass in [0, 2]: short_tag_ext += f"_pca{bypass}" # to avoid conflicting names in case of parallel test execution, differentiate all cases - long_tag_ext = f"_AGC{agc}_pca{bypass}" + long_tag_ext = f"_AGC{agc}" if agc != -1 else "_AGC-unspecified" + long_tag_ext += f"_pca{bypass}" dut_pkt_file = f"{dut_out_dir}/{tag_out}{long_tag_ext}.pkt" ref_pkt_file = f"{ref_out_dir}/{tag_out}{short_tag_ext}.pkt" ref_pkt_file_dutenc = f"{ref_out_dir}/{tag_out}{short_tag_ext}_dutenc.pkt" input_path = f"{test_vector_path}/{tag_in}{in_extension}" - agc_op = agc if agc >= 0 else None + agc_op = agc if agc != -1 else None bypass_mode = bypass if bypass >= 0 else None dtx_mode = dtx == '1' if in_extension == '.pcm': # use shortened and potentially gain adjusted input PCM file - create if not present # cut input PCM file: currently with mostly fixed (i.e. not test dependant) values - num_channels = "4" # currently only FOA inputs end up, here + num_channels = "4" # currently only FOA inputs end up, here cut_from = "0.0" cut_len = "5.0" if cut_gain == "1.0": @@ -531,24 +534,24 @@ def sba_dec( keep_files, ): - ######### run cmd ##################################### - #sampling rate to BW mapping + # -------- run cmd ------------ + # sampling rate to BW mapping bw_idx = dict_fsample_bw[sampling_rate] if int(dict_bw_idx[ivas_max_bw]) < int(bw_idx): tag = tag + dict_bw_tag[ivas_max_bw] - tag_out = f"{tag}_ivasbr{ivas_br[:-3]}k_DTX{dtx}" short_tag_ext = "" - if agc == 1: - short_tag_ext += '_AGC1' + if agc != -1: + short_tag_ext += f'_AGC{agc}' # we update only bypass = 0/2 (bypass 1 is the same as the baseline) if bypass in [0, 2]: short_tag_ext += f"_pca{bypass}" # to avoid conflicting names in case of parallel test execution, differentiate all cases - long_tag_ext = f"_AGC{agc}_pca{bypass}" + long_tag_ext = f"_AGC{agc}" if agc != -1 else "_AGC-unspecified" + long_tag_ext += f"_pca{bypass}" dut_out_dir = f"{dut_base_path}/sba_bs/raw" ref_out_dir = f"{reference_path}/sba_bs/raw" @@ -582,7 +585,7 @@ def sba_dec( dut_out_raw, ) - ######### compare cmd ##################################### + # -------------- compare cmd -------------- end_skip_samples = '0' -- GitLab From 1941f9b6de419df952d7047af49e422804457c0a Mon Sep 17 00:00:00 2001 From: Shanush Prema Thasarathan Date: Thu, 20 Oct 2022 18:33:34 +1100 Subject: [PATCH 2/5] Fix unbalanced brackets when AGC_ENABLE_FOR_LBR was disabled --- lib_enc/lib_enc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index e21ac143b0..337f9de509 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1536,8 +1536,9 @@ static ivas_error printConfigInfo_enc( } #else if ( hEncoderConfig->Opt_AGC_ON ) + { fprintf( stdout, "- AGC ON " ); - } + } #endif fprintf( stdout, "\n" ); } -- GitLab From 35d9a6ccd58153c7cbc5098d5802a1d373161bd5 Mon Sep 17 00:00:00 2001 From: Shanush Prema Thasarathan Date: Thu, 20 Oct 2022 19:33:06 +1100 Subject: [PATCH 3/5] Move variable creation to higher up in scope to fix issue with instrumentation --- lib_enc/ivas_agc_enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc.c index 702324d2a8..5bfcc74e53 100644 --- a/lib_enc/ivas_agc_enc.c +++ b/lib_enc/ivas_agc_enc.c @@ -333,6 +333,7 @@ void ivas_agc_enc_process( if ( isClipped ) { + int16_t isCompensated = FALSE; actualMaxAbsVal = pState->gain_state[i].lastMaxAbs * pState->gain_state[i].lastGain; #ifndef AGC_TUNING_IMPROVEMENT if ( MaxAbsValIdx == 0 ) @@ -342,7 +343,6 @@ void ivas_agc_enc_process( else { #endif - int16_t isCompensated = FALSE; pState->gain_data[i].gainException = FALSE; #ifdef AGC_TUNING_IMPROVEMENT pState->gain_state[i].gainExpVal = (int16_t) ceilf( -logf( actualMaxAbsVal * MDFT_NORM_SCALING ) / logf( pState->agc_com.winFunc[min( offset - 1, MaxAbsValIdx )] ) ); -- GitLab From eecac1f227c893baa2b0508b7802d9b0a64537e7 Mon Sep 17 00:00:00 2001 From: Shanush Prema Thasarathan Date: Wed, 26 Oct 2022 19:50:43 +1100 Subject: [PATCH 4/5] Fix a previous incorrect merge and address some review comments --- lib_com/options.h | 1 + lib_enc/ivas_agc_enc.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 83dc3a752f..2f31efb32f 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -152,6 +152,7 @@ #define FIX_155_HP20_ISSUE /* Issue 155: apply hp20 on all input channels instead of just 2 channels */ #define EFAP_FIX_POLY /* Issue 167: fix bug in EFAP polygon selection */ #define SBA_HOA_HBR_IMPROV /* issue 91: Improvements to SBA high bitrate HOA3 coding */ +#define AGC_TUNING_IMPROVEMENT /* Issue 168: Enable AGC for low bit rate (1 TC) */ #ifdef AGC_TUNING_IMPROVEMENT #define AGC_ENABLE_FOR_LBR /* Issue 168: Enable AGC for low bit rate (1 TC) */ #endif diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc.c index 5bfcc74e53..0f3274f43c 100644 --- a/lib_enc/ivas_agc_enc.c +++ b/lib_enc/ivas_agc_enc.c @@ -73,9 +73,9 @@ int16_t ivas_agc_enc_get_enablement_flag( IVAS_ENC_AGC agc_configuration, int16_t nchan_transport ) { - return (bool) ( ( agc_configuration == IVAS_ENC_AGC_UNDEFINED ) + return (int16_t) ( ( agc_configuration == IVAS_ENC_AGC_UNDEFINED ) ? ( nchan_transport == 1 ) - : !!agc_configuration ); + : agc_configuration ); } #endif -- GitLab From e869e90a19a8a38fa0315e6541d1088d56e216f8 Mon Sep 17 00:00:00 2001 From: Shanush Prema Thasarathan Date: Wed, 26 Oct 2022 19:58:38 +1100 Subject: [PATCH 5/5] Do a != false check rather than greater than 0 --- lib_enc/ivas_spar_encoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index eab9224303..b5f00848a8 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -926,7 +926,7 @@ static ivas_error ivas_spar_enc_process( if ( dtx_vad == 1 ) { #ifdef AGC_ENABLE_FOR_LBR - if ( hSpar->AGC_Enable > 0 ) + if ( hSpar->AGC_Enable != 0 ) #else if ( hEncoderConfig->Opt_AGC_ON > 0 ) #endif -- GitLab