diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 8e4c7c99083c6f3304101a18f80410f196ec2a7e..40a4710579dd35f964601e1becd5fa77e89dd6a6 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -67,8 +67,7 @@ #define MAX16B_FLT 32767.0f #define MIN16B_FLT ( -32768.0f ) #define PCM16_TO_FLT_FAC 32768.0f - - +#define MDFT_NORM_SCALING ( 1.0f / PCM16_TO_FLT_FAC ) #define MAX_FRAME_COUNTER 200 #define MAX_BITS_PER_FRAME 10240 /* Bits per frame for max. bitrate 512kbps */ diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 9c3cd6710c709fd9d87257482b9fd72fb0973af3..bf747a0de37a0148d9eaa9868105f37208e0aaa2 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3717,7 +3717,9 @@ void ivas_spar_config( void ivas_sba_upmixer_renderer( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ float output[][L_FRAME48k], /* i/o: transport/output audio channels */ +#ifndef SPAR_SCALING_HARMONIZATION const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ +#endif const int16_t output_frame /* i : output frame length */ ); diff --git a/lib_com/options.h b/lib_com/options.h index a1981a5e79fa66c55ac728690bb964d92b805b1a..b9132829bb7dc43ee1d9cbed1d9f91beb4190a9a 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -158,6 +158,7 @@ #define NTT_UPDATE_ITD_SW /* contribution 4: Update of ITD switch in stereo downmix for EVS */ #define NTT_REMOVE_EPS_ROM /* contribution 4: Reduction of ROM size in stereo downmix for EVS */ +#define SPAR_SCALING_HARMONIZATION /* issue 80: Changes to harmonize scaling in spar */ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ #endif diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index a103c9f45fabbda0bcaebb580ae9164007c10eeb..b9923a87e7c79c865ccb7925abe14b941a4e6019 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -345,7 +345,11 @@ ivas_error ivas_dec( } else /* SBA_MODE_SPAR */ { - ivas_sba_upmixer_renderer( st_ivas, output, nchan_remapped, output_frame ); /* Note: ivas_sba_linear_renderer() or ivas_dirac_dec() are called internally */ + ivas_sba_upmixer_renderer( st_ivas, output, +#ifndef SPAR_SCALING_HARMONIZATION + nchan_remapped, +#endif + output_frame ); /* Note: ivas_sba_linear_renderer() or ivas_dirac_dec() are called internally */ } } else if ( st_ivas->ivas_format == MC_FORMAT ) diff --git a/lib_dec/ivas_sba_rendering.c b/lib_dec/ivas_sba_rendering.c index 5552c26a50f20ae1596834c35c2b4422f034ed47..3bcf4d3884aafb30aeb49ed5eec8a8dc77de0dab 100755 --- a/lib_dec/ivas_sba_rendering.c +++ b/lib_dec/ivas_sba_rendering.c @@ -205,11 +205,17 @@ static void ivas_sba_mtx_mult( void ivas_sba_upmixer_renderer( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ float output[][L_FRAME48k], /* i/o: transport/output audio channels */ +#ifndef SPAR_SCALING_HARMONIZATION const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ +#endif const int16_t output_frame /* i : output frame length */ ) { +#ifdef SPAR_SCALING_HARMONIZATION + int16_t i; +#else int16_t i, ch, nchan_out; +#endif float temp; int16_t nchan_internal; @@ -220,8 +226,11 @@ void ivas_sba_upmixer_renderer( #else nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); #endif - nchan_out = st_ivas->hDecoderConfig->nchan_out; +#ifndef SPAR_SCALING_HARMONIZATION + nchan_out = st_ivas->hDecoderConfig->nchan_out; +#endif +#ifndef SPAR_SCALING_HARMONIZATION for ( ch = 0; ch < nchan_remapped; ch++ ) { for ( i = 0; i < output_frame; i++ ) @@ -241,6 +250,7 @@ void ivas_sba_upmixer_renderer( output[ch][i] = temp; } } +#endif if ( st_ivas->nchan_transport >= 3 ) { @@ -261,6 +271,7 @@ void ivas_sba_upmixer_renderer( ivas_sba_linear_renderer( output, output_frame, st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hDecoderConfig->output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ); } +#ifndef SPAR_SCALING_HARMONIZATION for ( ch = 0; ch < nchan_out; ch++ ) { for ( i = 0; i < output_frame; i++ ) @@ -268,6 +279,7 @@ void ivas_sba_upmixer_renderer( output[ch][i] = output[ch][i] * PCM16_TO_FLT_FAC; } } +#endif wmops_sub_end(); diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index f2b8f4926a477947e324ef808f2354636f732018..001f14c91c4585b9a35c2c7daa1ff7acb42aab2e 100755 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -973,20 +973,32 @@ void ivas_spar_dec_upmixer( /*---------------------------------------------------------------------* * PCA decoder *---------------------------------------------------------------------*/ - #ifdef DEBUG_SBA_AUDIO_DUMP pState->pca_ingest_channels = num_in_ingest; #endif if ( hSpar->hPCA != NULL ) { +#ifdef SPAR_SCALING_HARMONIZATION + for ( out_ch = 0; out_ch < num_in_ingest; out_ch++ ) + { + v_multc( output[out_ch], MDFT_NORM_SCALING, output[out_ch], output_frame ); + } +#endif ivas_pca_dec( hSpar->hPCA, output_frame, num_in_ingest, hDecoderConfig->ivas_total_brate, hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output ); #ifdef DEBUG_SBA_AUDIO_DUMP /* Dump audio signal after ivas_pca_dec */ ivas_spar_dump_signal_wav( output_frame, NULL, output, num_in_ingest, spar_foa_dec_wav[2], "ivas_pca_dec()" ); +#endif +#ifdef SPAR_SCALING_HARMONIZATION + for ( out_ch = 0; out_ch < num_in_ingest; out_ch++ ) + { + v_multc( output[out_ch], PCM16_TO_FLT_FAC, output[out_ch], output_frame ); + } #endif } + /*---------------------------------------------------------------------* * TD decorrelation *---------------------------------------------------------------------*/ diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc.c index 493d1ac07118e67371f3d44eb9dc654166cfd257..c3c68efc726d155ba7c85d3a2d8a6b9959ff0f36 100644 --- a/lib_enc/ivas_agc_enc.c +++ b/lib_enc/ivas_agc_enc.c @@ -242,7 +242,11 @@ void ivas_agc_enc_process( if ( !isClipped ) { +#ifdef SPAR_SCALING_HARMONIZATION + if ( ( ppPcm_out[i][j] > ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC ) || ( ppPcm_out[i][j] < MIN16B_FLT ) ) +#else if ( ( ppPcm_out[i][j] > ( 1.f - pState->minDelta ) ) || ( ppPcm_out[i][j] < -1.f ) ) +#endif { if ( j < offset ) { @@ -278,7 +282,11 @@ void ivas_agc_enc_process( maxGain = max( smoothedMaxAbsVal, MaxAbsVal ) * pState->gain_state[i].lastGain * 2.f; +#ifdef SPAR_SCALING_HARMONIZATION + if ( maxGain < ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC ) +#else if ( maxGain < 1.f - pState->minDelta ) +#endif { pState->gain_state[i].gainExpVal = -1; } @@ -313,7 +321,11 @@ void ivas_agc_enc_process( { int16_t isCompensated = FALSE; pState->gain_data[i].gainException = FALSE; +#ifdef SPAR_SCALING_HARMONIZATION + pState->gain_state[i].gainExpVal = (int16_t) ceilf( -logf( actualMaxAbsVal * MDFT_NORM_SCALING ) / logf( pState->agc_com.winFunc[MaxAbsValIdx] ) ); +#else pState->gain_state[i].gainExpVal = (int16_t) ceilf( -logf( actualMaxAbsVal ) / logf( pState->agc_com.winFunc[MaxAbsValIdx] ) ); +#endif while ( !isCompensated ) { @@ -324,7 +336,11 @@ void ivas_agc_enc_process( { tmpSignal = ppPcm_out[i][idx] * powf( pState->agc_com.winFunc[idx], (float) pState->gain_state[i].gainExpVal ); +#ifdef SPAR_SCALING_HARMONIZATION + if ( ( tmpSignal > ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC ) || ( tmpSignal < MIN16B_FLT ) ) +#else if ( ( tmpSignal > ( 1.f - pState->minDelta ) ) || ( tmpSignal < -1.f ) ) +#endif { isCompensated = FALSE; break; @@ -374,7 +390,11 @@ void ivas_agc_enc_process( } else { +#ifdef SPAR_SCALING_HARMONIZATION + pState->gain_state[i].gainExpVal = (int16_t) ( -floorf( -logf( ( actualMaxAbsVal + pState->minDelta ) * MDFT_NORM_SCALING ) * INV_LOG_2 ) ); +#else pState->gain_state[i].gainExpVal = (int16_t) ( -floorf( -logf( actualMaxAbsVal + pState->minDelta ) * INV_LOG_2 ) ); +#endif pState->gain_state[i].gainExpVal = min( gainExpValMaxRange, pState->gain_state[i].gainExpVal ); gain = powf( 2.0f, -1.0f * pState->gain_state[i].gainExpVal ); diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 0e4fd817c74556bbedb6375829a61a4b737ec827..abe392c390b0186d0c62cc1a0167aa8ed900d5b4 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -291,7 +291,9 @@ ivas_error ivas_spar_enc( ) { ENCODER_CONFIG_HANDLE hEncoderConfig; - int16_t i, ch; +#ifndef SPAR_SCALING_HARMONIZATION + int16_t ch; +#endif ivas_error error; error = IVAS_ERR_OK; @@ -303,14 +305,13 @@ ivas_error ivas_spar_enc( return error; } +#ifndef SPAR_SCALING_HARMONIZATION /* normalize input channels */ for ( ch = 0; ch < hEncoderConfig->nchan_inp; ch++ ) { - for ( i = 0; i < input_frame; i++ ) - { - data_f[ch][i] *= ( 1.0 / PCM16_TO_FLT_FAC ); - } + v_multc( data_f[ch], MDFT_NORM_SCALING, data_f[ch], input_frame ); } +#endif if ( hEncoderConfig->sba_planar ) { @@ -817,7 +818,19 @@ static ivas_error ivas_spar_enc_process( if ( hSpar->hPCA != NULL ) { +#ifdef SPAR_SCALING_HARMONIZATION + for ( int out_ch = 0; out_ch < FOA_CHANNELS; out_ch++ ) + { + v_multc( p_pcm_tmp[out_ch], MDFT_NORM_SCALING, p_pcm_tmp[out_ch], input_frame ); + } +#endif ivas_pca_enc( hEncoderConfig, hSpar->hPCA, hMetaData, p_pcm_tmp, input_frame, FOA_CHANNELS ); +#ifdef SPAR_SCALING_HARMONIZATION + for ( int out_ch = 0; out_ch < FOA_CHANNELS; out_ch++ ) + { + v_multc( p_pcm_tmp[out_ch], PCM16_TO_FLT_FAC, p_pcm_tmp[out_ch], input_frame ); + } +#endif } else { @@ -912,7 +925,11 @@ static ivas_error ivas_spar_enc_process( { for ( j = 0; j < nchan_transport; j++ ) { +#ifndef SPAR_SCALING_HARMONIZATION data_f[order[j]][i] = p_pcm_tmp[j][i] * PCM16_TO_FLT_FAC; +#else + data_f[order[j]][i] = p_pcm_tmp[j][i]; +#endif } for ( ; j < IVAS_SPAR_MAX_DMX_CHS; j++ ) {